I'm creating an XSL-FO document in Java. It contains a long table with multiple cells that can, at times, run multiple pages. When it does, it causes the table to clip into an image in our header at the top.
What type of padding do I need to add to prevent our table from clipping into a header image when the clipping occurs mid-table?
We cannot move the header up or down because it is a legal document.
Edit: I'll do my best to include the code from the app, though I'll have to edit it down a bit.
This is our header:
w.write("<fo:static-content flow-name=\"xsl-region-before\">");
w.write("<fo:block-container height=\"1.01in\" width=\"7in\" padding-bottom=\".1in\">");
w.write("<fo:table table-layout=\"fixed\" width=\"7in\">");
w.write("<fo:table-column column-width=\"2.4cm\"/><fo:table-column column-width=\"14cm\"/>");
w.write("<fo:table-body>");
w.write("<fo:table-row>");
w.write("<fo:table-cell number-rows-spanned=\"2\">");
w.write("<fo:block padding-left=\"4mm\">");
w.write("<fo:external-graphic top=\"0cm\" src=\"url('"+this.getResourceUrl("Url.tif")+"')\" width=\"2.4cm\"/>");
w.write("</fo:block>");
w.write("</fo:table-cell>");
w.write("<fo:table-cell>");
w.write("<fo:block font-size=\"10pt\" padding-top=\"4mm\" text-align=\"left\"><fo:inline font-weight=\"bold\">");
w.filteredWrite("SomeCompany");
w.write("</fo:inline></fo:block>");
w.write("<fo:block font-size=\"10pt\" padding-top=\"1mm\" text-align=\"left\"><fo:inline font-weight=\"bold\">");
w.filteredWrite(this.getStuff());
w.write(",</fo:inline> Stuff");
w.write("</fo:block>");
w.write("<fo:block font-size=\"10pt\" padding-top=\"1mm\" padding-bottom=\"1mm\" text-align=\"left\"><fo:inline font-weight=\"bold\">");
w.filteredWrite(this.getAThing());
w.write(",</fo:inline> ");
if (this.getAVariable() != null && this.getAVariableLength().length() > 0)
{
w.write(this.getAVariable());
}
else
{
w.write("TEXT");
}
w.write("</fo:block>");
w.write("</fo:table-cell>");
w.write("</fo:table-row>");
w.write("<fo:table-row>");
w.write("<fo:table-cell border-top-style=\"solid\" border-top-color=\"#000000\" border-top-width=\"0.2mm\" >");
w.write("</fo:table-cell>");
w.write("</fo:table-row>");
w.write("</fo:table-body>");
w.write("</fo:table>");
w.write("</fo:block-container>");
w.write("</fo:static-content>");
}
This is what the initial declaration of our table looks like:
w.write("<fo:table table-layout=\"fixed\" width=\"176mm\">");
w.write("<fo:table-column column-width=\"38mm\"/><fo:table-column column-width=\"38mm\"/>");
w.write("<fo:table-column column-width=\"28mm\"/><fo:table-column column-width=\"27mm\"/>");
w.write("<fo:table-column column-width=\"25mm\"/>");
w.write("<fo:table-column column-width=\"20mm\"/>");
This is what the table header looks like:
w.write("<fo:table-header>");
w.write("<fo:table-row background-color=\"black\" color=\"white\" padding=\"2px\" border-width=\"0.2mm\">");
w.write("<fo:table-cell padding=\"inherit\" border-right-style=\"solid\" border-right-color=\"#000000\" border-right-width=\"0.2mm\">");
w.write("<fo:block text-align=\"left\" font-size=\"10pt\" color=\"white\" font-weight=\"bold\" font-family=\""+font+"\">NameOfColumn</fo:block>");
w.write("</fo:table-cell>");
-Four Additional identical sets of cells-
}
w.write("</fo:table-row>");
w.write("</fo:table-header>");
w.write("<fo:table-body>");
And this is what each additional row looks like when it is initially declared:
w.write("<fo:table-row keep-together=\"always\" padding=\"2px\">");
w.write("<fo:table-cell padding=\"inherit\" number-rows-spanned=" + rowsToSpan+" border-right-style=\"solid\" border-right-color=\"#000000\" border-right-width=\"0.2mm\" border-left-style=\"solid\" border-left-color=\"#000000\" border-left-width=\"0.2mm\" border-bottom-style=\"solid\" border-bottom-color=\"#000000\" border-bottom-width=\"0.2mm\">");
w.write("<fo:block text-align=\"left\" font-size=\"10pt\" font-family=\""+font+"\">");
I've figured out a way to make this work - I simply need to extend the top margin for the Body of my main page master so that the header doesn't overlap my text.
w.write("<fo:simple-page-master master-name=\"main-master\" ");
w.write("page-height=\"11in\" page-width=\"8.5in\" margin-top=\".5in\" ");
w.write("margin-bottom=\".5in\" margin-left=\".5in\" margin-right=\".5in\">");
//w.write("<fo:region-body margin-top=\"20mm\" margin-bottom=\"4in\"/>");
w.write("<fo:region-body margin-top=\"25mm\" margin-bottom=\"4in\"/>");
This means that the top of the page will have a small space between the start of the body and the header, but this is an acceptable compromise for me.
Related
I wanted to loop through a folder containig .mp3 files and changing their album names (if they don't have one) to their title (e.g. Remix.mp3 with Title "Remix" gets the Album "Remix") using mp3agic.
This is my code so far:
if (mp3file.hasId3v1Tag()) {
ID3v1 id3v1Tag = mp3file.getId3v1Tag();
try {
if (id3v1Tag.getAlbum().equals("")) {
id3v1Tag.setAlbum(id3v1Tag.getTitle());
mp3file.save(SAVE_DIR + "\\" + child.getName());
System.out.println(SAVE_DIR + "/" + child.getName());
} else {
mp3file.save(SAVE_DIR + "/" + child.getName());
}
} catch (Exception e) {
mp3file.save(SAVE_DIR + "/" + child.getName());
}
}
I get the following error:
Exception in thread "main" com.mpatric.mp3agic.NotSupportedException: Packing Obselete frames is not supported
at com.mpatric.mp3agic.ID3v2ObseleteFrame.packFrame(ID3v2ObseleteFrame.java:32)
at com.mpatric.mp3agic.ID3v2Frame.toBytes(ID3v2Frame.java:83)
at com.mpatric.mp3agic.AbstractID3v2Tag.packSpecifiedFrames(AbstractID3v2Tag.java:275)
at com.mpatric.mp3agic.AbstractID3v2Tag.packFrames(AbstractID3v2Tag.java:261)
at com.mpatric.mp3agic.AbstractID3v2Tag.packTag(AbstractID3v2Tag.java:227)
at com.mpatric.mp3agic.AbstractID3v2Tag.toBytes(AbstractID3v2Tag.java:218)
at com.mpatric.mp3agic.Mp3File.save(Mp3File.java:450)
at de.thejetstream.main.Iterator.(Iterator.java:57)
at de.thejetstream.main.Main.main(Main.java:12)
at this file:
name: Feel Good in Black and Yellow.mp3
title: Feel Good in Black and Yellow (feat. Gorillaz & De La Soul)
album: Black and Yellow - Single
It crashes at line 57, which equals to the last save (in the catch).
What is the problem with this code? Is it just because the file uses an old kind of codec or something like this?
I found the solution:
The problem was that these files used ip3v2 tags instead of ip3v1. Simply checking which on it is and adjusting the code accordingly solved everything.
I am trying to shirt the values with leading zero to the right when opening the csv file with Excel MS. I am using bufferedWriter.write("\\"\t"+row[4] + "\\"\t"); . The tabe and quote to display the leading zero since without it I am just getting 46 and not 046.
if(row[4].startsWith("0")){
bufferedWriter.write(";" + "\\"\t"+row[4] + "\\"\t");
}else{
bufferedWriter.write(";" + row[4]);
}
screen shot
Couple of things:
Fix the write line to properly escape the quote
bufferedWriter.write(";" + "\"\t"+row[4] + "\"\t");
This is the output (I am using the pipe/"|" instead of a new line)
2016;" 046" |2016;" 046" |2016;400|2016;400|
Remove the second tab to get rid of the extra space in your display
bufferedWriter.write(";" + "\"\t"+row[4]);
This is now the output
2016;" 046"|2016;" 046"|2016;400|2016;400|
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 10 months ago.
Improve this question
Currently, I am working on a "Selenium Wrapper Library", where a set of methods are created in order to perform automation on a particular Web Portal. These methods includes debug logging and other logic, and are called within test classes.
I've just created a new method to check whether a table cell (tag name td), is present inside a table row (tag name tr). Below is the created method:
public void checkEntryIsNotInTable(String elementTableName, By byElementTable, String checkVisibleText1) {
// Get All Rows from table, using tagname <tr>
List<WebElement> tableRows = getElements(elementTableName, byElementTable);
Debug.log.info("\tTotal of [" + tableRows.size() + "] Rows found in table [" + elementTableName + "]" );
int rowCount = 0;
boolean isNotFound = false;
FINDCELL:
for(WebElement row : tableRows) {
// Get All Cells from table, using tagname <td>
List<WebElement> rowCells = row.findElements(By.tagName("td"));
if(rowCells == null) {
Debug.log.error("\tNo Elements found with TagName [td] in Element [" + byElementTable + "]");
} else {
Debug.log.info("\tRow [" + rowCount++ + "] contains [" + rowCells.size() + "] Cells");
}
// Check Visible Text in Cell, and if found, break from for loop.
for(WebElement cell : rowCells) {
waitFor(2.0);
if(!cell.getText().contains(checkVisibleText1)){
Debug.log.info("\t[" + checkVisibleText1 + "] not found in any Cell.");
isNotFound = true;
break FINDCELL;
}
}
}
// What kind of exception should I throw here!!
if(isNotFound) {
Debug.log.error("\t[" + checkVisibleText1 + "] found in one Cell.");
throw new NoSuchElementException(checkVisibleText1);
}
}
At this stage, when checkVisibleText1 is found, I need to throw a new exception. However, for this method, the exception NoSuchElementException does not reflect a proper exception, since the element is found - and it should not be found.
What exception would be appropriate to throw here?
You should check the available exceptions and:
If you have the appropriate exception that matches your error then use it, else create/use a custom exception or create/use a general exception with a custom message depending on the method.
Always try to output an exception with an message that will be helpful to you.
In this case, assuming checkVisibleText1 is the text you are looking for, using NoSuchElementException with the text as the parameter is not OK.
You should have an exception like ElementDoesNotContainsTextException with a message saying "\t Element [" + elementTableName+ "] does not contain text [" + checkVisibleText1 + "]."
Try to use an appropriate exception when possible or use a general exception with the appropriate message.
My opinion is that you have too much noise/logs in this method, too much logs and too complex for the functionality that it has.
The methods should have their exceptions you you shouldn't need so many logs.
Some solutions:
1. Get the text from the table and check if the text is there
2. Create a selector based on that text with xpath and check for that selector
3. Check for the text in a specific selector
Create reusable methods like: theElementContainsText, theElementDoesNotContainsText
Reuse as much as possible for example for above method(s) you could use other methods that: find element, get element from text
I am working in project which most of the code written by JADE technology.I am new bie to jade.I dont get any clue from the Error stack flow, I posted my jade code and error below ,please share your suggestion's what I am wrote wrong and where do I make a change?
.row
.col-md-12
.panel.panel-primary
.panel-heading
h3 {{cc.header.subject}}
ep-editable-date-time(model='cc.header')
.panel-body
.panel.panel-default(ng-repeat='step in cc.checklist.steps',
data-step='{{step.stepPath[step.stepPath.length - 1].name}}')
.panel-heading
span.pull-right.checklist-controls(ng-if='cc.checkupType !== cc.types.DRIVEBY')
button.btn(ng-class="{'active': !step.skip, 'btn-default': step.skip, 'btn-success':!step.skip}",
ng-click='step.skip=!step.skip; step.skip ? step.noSelfCheckNeeded=true : noop')
span Include
=" "
span.fa(ng-class="{'fa-square-o': step.skip, 'fa-check-square-o': !step.skip}")
=" "
span(ng-if='cc.checkupType === cc.types.SUPERVISOR')
button.btn(ng-class="{'active': !step.noSelfCheckNeeded, 'btn-success': !step.noSelfCheckNeeded, 'btn-default':step.noSelfCheckNeeded}",
ng-click='step.noSelfCheckNeeded=!step.noSelfCheckNeeded',
ng-disabled='step.skip')
span Self Check
=" "
span.fa(ng-class="{'fa-check-square-o':!step.noSelfCheckNeeded, 'fa-square-o': step.noSelfCheckNeeded}")
h5.checklist-header(ng-bind='step.process.name')
h6
span(ng-repeat='s in step.stepPath')
span(ng-bind='s.name')
span(ng-show='!$last')
=" > "
table.table
col
col(style='width: 60px')
thead
tr
th(colspan='2', style='text-align: right') In compliance?
th(style='width: 100px') Not-Applicable
tbody
tr(ng-repeat='b in step.behaviors')
td(ng-bind='b.name')
td
span.bigcheck.compliance-checkbox
label.bigcheck
input.bigcheck(type='checkbox', ng-model='b.compliance', ng-disabled='step.skip')
span.bigcheck-target
//I added these lines which started and ended with ** , It makes me a trouble please guided any one what I have missed .,
**td
span.bigcheck.compliance-checkbox
label.bigcheck
input.bigcheck(type='checkbox', ng-model='b.compliance', ng-disabled='step.skip')
span.bigcheck-target**
.panel-footer
div(ng-if='cc.checkupType === cc.types.SUPERVISOR', style='text-align: center')
span(ng-if='!cc.selfCheckupNeeded()')
h6(ng-if='cc.anyStepsSelected()') Save and Return to Subject Dashboard
h6(ng-if='!cc.anyStepsSelected()') Include at least one Step before saving Checkups
button.btn.btn-success(ng-if='!cc.selfCheckupNeeded()',
ng-disabled='!cc.isCheckupDTValid() || !cc.anyStepsSelected()',
ng-click='cc.saveAndDontSelfCheckup()') Save Supervisor Checkup
span(ng-if='cc.selfCheckupNeeded()')
h6 Save and Start Self Checkup
button.btn.btn-primary.self-checkup-now-btn(ng-disabled='!cc.isCheckupDTValid()',
ng-click='cc.saveAndStartSelfCheckup()')
span.fa.fa-check-square-o
| Self Checkup Now
=" "
button.btn.btn-danger.self-checkup-later-btn(ng-disabled='!cc.isCheckupDTValid()', ng-click='cc.saveAndSelfCheckupLater()')
span.fa.fa-check-square-o
| Self Checkup Later
div(ng-if='cc.checkupType === cc.types.SELF', style='text-align: center')
h6 Save and View Results
button.btn.btn-success.save-self-checkup(ng-disabled='!cc.isCheckupDTValid()',
ng-click='cc.saveAndDontSelfCheckup()')
span.fa.fa-check-square-o
| Save Self Checkup
div(ng-if='cc.checkupType === cc.types.DRIVEBY', style='text-align: center')
h6 Save Checkup
button.btn.btn-success(ng-disabled='!cc.isCheckupDTValid()', ng-click='cc.saveAndDontSelfCheckup()')
span.fa.fa-check-square-o
| Save Checkup
Error stack flow
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is class de.neuland.jade4j.exceptions.JadeLexerException checkup/checklist.jade:42
invalid indentation; expecting 0 spaces
Caused by: de.neuland.jade4j.exceptions.JadeLexerException: invalid indentation; expecting 0 spaces
The edited code above works fine with jade node module.
You should doublecheck such issues just by pasting your template at jade-lang.com
(Your template works fine there also)
As robertklep mentioned, it is likely an issue with your lexer
I'm building an application where I have mainDoc which can have one or more related notes Documents. In the mainDoc there is a repeat control that is bound to Payments.getAllItems(WFSMainDoc.getValue("LinkKey")); The java class Payments has methods that manipulate and ArrayList of PaymentItems. The getAllItems method grabs all of the related NotesDocuments and loads them into an ArrayList. If the ArrayList already exists it just returns the previously built ArrayList. The button in the Repeat sets viewScope.vsRIndex = rIndex; and viewScope.vsShowPayment = true; which now displays the panelPaymentDetail and the custom control that has a custom property of type java.lang.Object and load pItem using pItem = Payments.getItem(rIndex); return pItem;
all of the above works and I have a couple sample controls below. I have two issues:
1. The compositeData.pItem is computed over and over again and as far as I can tell keeps returning the original values from the Payments.getAllItems() even though I'm editing them in the payment input 'form' -- the question then is how can I block this repeated calculation?
The save button in the Payment Input custom control does not appear to fire (none of the print statements occur when clicked) I think the reloading of the Object pItem gets in the way.
Test Main Document Control:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xc="http://www.ibm.com/xsp/custom">
<xp:this.data>
<xp:dominoDocument var="WFSMainDoc" formName="frmMainDoc"
computeWithForm="onsave" ignoreRequestParams="false">
<xp:this.documentId><![CDATA[${javascript:var UNID:String = sessionScope.get("ssUNID");
(UNID == null || UNID == "") ? "" : UNID}]]></xp:this.documentId>
<xp:this.action><![CDATA[${javascript:if (sessionScope.containsKey("ssUNID")){
if(sessionScope.get('ssUNID').length){
sessionScope.get('ssAction') == 'edit' ? 'editDocument':'openDocument'
} else {
return 'createDocument'
break;
}
}else{
return "createDocument";
break;
}}]]></xp:this.action>
<xp:this.databaseName><![CDATA[${appProps[sessionScope.ssApplication].appFilePath}]]></xp:this.databaseName>
</xp:dominoDocument>
</xp:this.data>
Main document
<xp:br></xp:br>
<xp:inputText id="inputText1" value="#{WFSMainDoc.LinkKey}"
defaultValue="#{javascript:#Unique}">
</xp:inputText>
<xp:br></xp:br>
Other Fields and controls
<xp:br></xp:br>
<xp:panel id="panelPaymentContainer">
<xp:repeat id="repeatData" rows="10" var="pItem"
indexVar="rIndex">
<xp:this.value><![CDATA[#{javascript:Payments.getAllItems(WFSMainDoc.getValue("LinkKey"));}]]></xp:this.value>
<xp:button id="buttonEditPayment"
rendered="#{javascript:(WFSMainDoc.isEditable())}">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="panelPaymentsContainer">
<xp:this.action><![CDATA[#{javascript:try{
viewScope.vsRIndex = rIndex;
viewScope.vsShowPayment = true;
break;
}catch(e){
WFSUtils.sysOut("Error in calling dialogPayment " + e.tostring)
}}]]>
</xp:this.action>
</xp:eventHandler>
</xp:button>
<br />
</xp:repeat>
<xp:panel id="panelPaymentInput">
<xp:this.styleClass><![CDATA[#{javascript:(viewScope.vsShowPayment) ? "" : "display=none";}]]></xp:this.styleClass>
<xc:ccTestPaymentInput rendered="#{javascript:(viewScope.vsShowPayment)}">
<xc:this.pItem><![CDATA[#{javascript:try{
var debug:Boolean = true;
if (debug) WFSUtils.sysOut("Open existing row = " + viewScope.vsRIndex)
rIndex = parseInt(viewScope.vsRIndex.toString());
if (debug) WFSUtils.sysOut("rIndex = " + rIndex);
pItem = Payments.getItem(rIndex);
return pItem;
}catch(e){
WFSUtils.sysOut("Failure in Custom Prop of add item " + e.toString());
return null;
}}]]></xc:this.pItem>
</xc:ccTestPaymentInput>
</xp:panel>
</xp:panel><!-- panelPaymentContainer -->
<xp:br></xp:br>
<xp:br></xp:br>
</xp:view>
payment Input Control
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:br></xp:br>
Actual Pay Date:
<xp:inputText id="actualPayDate"
value="#{compositeData.pItem.actualPayDate}">
<xp:dateTimeHelper id="dateTimeHelper1"></xp:dateTimeHelper>
<xp:this.converter>
<xp:convertDateTime type="date"></xp:convertDateTime>
</xp:this.converter>
</xp:inputText>
<br /> <br />
<xp:button value="Save" id="button1">
<xp:eventHandler event="onclick"
submit="true" refreshMode="partial" refreshId="panelPayments">
<xp:this.action><![CDATA[#{javascript:try{
var debug:Boolean = true;
if (debug) print("Start Payment save");
var pos:Integer = parseInt(viewScope.vsRIndex.toString());
if (debug) print("Working with pos = " + pos + " Call saveThisItem");
if (Payments.saveThisItem(compositeData.pItem , pos)){
if (debug) print("save Payments Worked ");
}else{
if (debug) print("save Payments FAILED ");
}
}catch(e){
print("payment save Error " + e.tostring);
}finally{
viewScope.vsExpPayDate = "";
viewScope.remove("vsShowPayment");
viewScope.remove("vsRIndex");
viewScope.remove("vsGotItem")
}}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:view>
This is all very complicated, and I'm far from understanding what you're trying to achieve here. But at least I found a few oddities in your code:
ad 1: there is a panel with id="panelPaymentContainer" containing a repeat. Inside that repeat is a button doing a partialRefresh on an id="panelPaymentsContainer" >> is this a typo (plural vs. singular forms in "Payment(s))? Should the button be refreshing the panel?
Assuming that this assumption is true: every time you click the button the panel is refreshed together with all its contents, thus also refreshing the repeat's datasource. And so pItem will always be pushed from "outside in" into the content of your repeat. - If the refreshId thing is NOT a typo, then what should it be? I tried hard to read the entire code, but there's a lot of it, so I might have missed something
ad 2: similar thing here: the save button tries to refresh something with an id="panelPayments", but I cannot see anything with this id. So no wonder it doesn't appear to do anything useful.
My recommendation for complicated tasks like these: try to strip everything down to the bare essentials; the more complicated your code is the harder it is to find its mistakes. Start with a panel, a repeat and a few simple controls like a button and a bunch of computed fields to display some test values. Then as soon as this very simple model is working you can start to add to it. - Simplifying also helps others to find mistakes in you concept, btw.