Adding PdfPCell in iText PdfPtable doesnt work anymore - itext

I have created several PdfPTable without problem, but now I dont know what is wrong. Fourth line doesnt displayed.
table = new PdfPTable(4);
table.setSpacingBefore(10);
columnWidths = new float[] {60,10,10,10};
table.setWidths(columnWidths);
PdfPCell cellFooter = new PdfPCell(new Phrase("Rows One", ARIAL_12_BOLD));
table.addCell(cellFooter);
for(int k=0; k<3; k++){
table.addCell("");
}
cellFooter = new PdfPCell(new Phrase("Row Two", ARIAL_12_BOLD));
table.addCell(cellFooter);
for(int k=0; k<3; k++){
table.addCell("");
}
cellFooter = new PdfPCell(new Phrase("Row Three", ARIAL_12_BOLD));
cellFooter.setColspan(4);
table.addCell(cellFooter);
// Row Four not displayed
for(int k=0; k<4; k++){
table.addCell("");
}

To answer, let me ask you this: How many pixels in height is an empty string?
The simplest way to get around this is to just add something. You should be able to just use:
table.addCell(" ");
However, if you're changing font sizes elsewhere the height might be different so you might want to explicitly set the font (and thus the height) of the empty cell:
table.addCell(new Phrase(" ", ARIAL_12_BOLD));
You could also explicitly define heights on cells but this is usually the easiest way.

Related

Header with 2 cells aligned in the same row, itextpdf 5.5.10

I have a row in my header, which looks good, but I need to add another String in the same row, so it is on the right side of it
When I try to add that String in the same cell, everything loses the alignment
private void addHeader(PdfWriter writer) {
PdfPTable tableHeader = new PdfPTable(2);
try {
// set defaults
header.setWidths(new int[] { 20, 12, 12 });
header.setTotalWidth(527);
header.setLockedWidth(true);
header.getDefaultCell().setFixedHeight(5);
header.getDefaultCell().setBorder(Rectangle.BOTTOM);
header.getDefaultCell().setBorderColor(BaseColor.LIGHT_GRAY);
// add text
PdfPCell text = new PdfPCell();
text.setPaddingBottom(12);
text.setPaddingLeft(8);
text.setBorder(Rectangle.BOTTOM);
text.setBorderColor(BaseColor.LIGHT_GRAY);
text.addElement(new Phrase("Hi", new Font(Font.FontFamily.HELVETICA, 12, Font.BOLD)));
text.addElement(new Phrase("", new Font(Font.FontFamily.HELVETICA, 8)));
text.addElement(new Phrase("Hi" + "CVE-2017-2018", new Font(Font.FontFamily.HELVETICA, 9)));
header.addCell(text);
// add image
Image logo = Image.getInstance(App.class.getResource(LOGO_2));
header.addCell(logo);
PdfPCell cveTitle = new PdfPCell();
cveTitle.setPaddingBottom(15);
cveTitle.setPaddingLeft(8);
cveTitle.setBorder(Rectangle.BOTTOM);
cveTitle.setBorderColor(BaseColor.LIGHT_GRAY);
cveTitle.addElement(new Phrase("3 Cell", new Font(Font.FontFamily.HELVETICA, 16, Font.BOLD)));
header.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
header.addCell(cveTitle);
}
CVE-2010-2016
Is just what I want to do, leave it on the right side
Update
The solution was to add a new value to the array, corresponding to a new cell, and also instantiating PdfPCell again, thks
Just from the classname PdfPTable, I can tell the iText version you are using is pretty outdated.
Please consider switching to a newer version. Latest version is iText7.
I think what you're looking for is colspan and rowspan.
Have a look at the tutorial:
http://developers.itextpdf.com/examples/tables/clone-colspan-and-rowspan

Strange display of a table of radio buttons

I am creating a form, in which there is a table of buttons. The following shows the idea:
Good OK Bad
Item1 [button] [button] [button]
Item2 [button] [button] [button]
Each row is a button group.
My program is able to work for a small table like the above. However, when rows or columns are more than one page to hold, the display is weird. This is my program:
PdfPTable table = new PdfPTable(colHeaders.size() + 1 );
table.setWidthPercentage(100);
PdfPCell cell;
table.setSpacingBefore(10);
table.setSpacingAfter(0);
table.setKeepTogether(false); //tested "true" different display error
//upper-left corner empty cell
cell = new CustomPdfPCell();
cell.setBackgroundColor(BaseColor.LIGHT_GRAY);
table.addCell(cell);
//header row
for (TableOfChoicesHeader c: colHeaders) {
String text = c.getText();
cell = new PdfPCell(new Phrase(text));
cell.setBackgroundColor(BaseColor.LIGHT_GRAY);
table.addCell(cell);
}
List<PdfFormField> radioGroups= new ArrayList<PdfFormField>();
//for each row
for (TableOfChoicesHeader r: rowHeaders) {
//row header
String rowText = r.getText();
cell = new PdfPCell(new Phrase(rowText));
cell.setBackgroundColor(BaseColor.LIGHT_GRAY);
table.addCell(cell);
//for the current row row
String fieldName = "question" + q.getId() +"_" + r.getId().toString();
PdfFormField radiogroup = PdfFormField.createRadioButton(writer, true);
radiogroup.setFieldName(fieldName);
radioGroups.add(radiogroup);
for (TableOfChoicesHeader c: colHeaders) {
cell = new PdfPCell();
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setPadding(5);
cell.setCellEvent(new CheckboxCellEvent(fieldName, r.getId() + "_" + c.getId()));
table.addCell(cell);
}
}
document.add(table);
for (PdfFormField g: radioGroups) {
writer.addAnnotation(g);
}
Here are the screenshots when table.setKeepTogether(false). The display is a little different but still strange if the value is true.
Page 1
Page 2
Update
By following Samuel's approach, I am able to see radio buttons displayed on the first page. However, the buttons on the first page got displayed on the second page. See the screenshots.
Update 2
I got it working by adding the following in MyCellField :
writer.addAnnotation(radiogroup);
instead of
PdfFormField field = radio.getRadioField();
writer.addAnnotation(field);
I cannot explain why. Thank Samuel and Bruno for their help!
Looking at your code again, is there any reason why you add the annotations for the radiobuttons all in one go at the end?.
Have you tried adding the annotation whenever you've added your row of cells? Something like this:
for (TableOfChoicesHeader r: rowHeaders) {
//row header
String rowText = r.getText();
cell = new PdfPCell(new Phrase(rowText));
cell.setBackgroundColor(BaseColor.LIGHT_GRAY);
table.addCell(cell);
//for the current row row
String fieldName = "question" + q.getId() +"_" + r.getId().toString();
PdfFormField radiogroup = PdfFormField.createRadioButton(writer, true);
radiogroup.setFieldName(fieldName);
radioGroups.add(radiogroup);
for (TableOfChoicesHeader c: colHeaders) {
cell = new PdfPCell();
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setPadding(5);
cell.setCellEvent(new CheckboxCellEvent(fieldName, r.getId() + "_" + c.getId()));
table.addCell(cell);
}
writer.addAnnotation(radiogroup)
}
EDIT:
As Bruno said, the examples for distributing a radio-group over multiple pages are RadioGroupMultiPage1 and RadioGroupMultiPage2. The examples for distributing a radio group across a table is found here: Distributing radio buttons of a radio field across multiple PdfCells.
EDIT 2, Electric Bogaloo:
Wipped up a quick example based on your code and the examples Bruno pointed out:
I basicly took your code frm the question above(with some stub-implementations for your custom data-classes), and used the MyCellField PdfCellEvent extension found in RadioGroupMultiPage2:
public MyCellField(PdfWriter writer, PdfFormField radiogroup, String value) {
this.writer = writer;
this.radiogroup = radiogroup;
this.value = value;
}
public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
try {
RadioCheckField radio = new RadioCheckField(writer, position, null, value);
PdfFormField field = radio.getRadioField();
writer.addAnnotation(field);
radiogroup.addKid(field);
} catch (IOException ex) {
// do nothing
} catch (DocumentException ex) {
// do nothing
}
}

horizontalSpan in SWT GridLayout doesn't span

I'm trying to configure a dialog window like so:
#Override
protected Control createDialogArea(Composite parent) {
GridLayout dialogAreaLayout = new GridLayout();
dialogAreaLayout.numColumns = 2;
parent.setLayout(dialogAreaLayout);
GridData gridData = new GridData();
gridData.grabExcessHorizontalSpace = true;
gridData.horizontalAlignment = GridData.FILL;
gridData.minimumWidth = 300;
// the label in the first row should span across both columns
gridData.horizontalSpan = 2;
Label headlineLabel = new Label(parent, SWT.NONE);
headlineLabel.setText("example test");
headlineLabel.setLayoutData(gridData);
// the rest should be ordered in two columns
gridData.horizontalSpan = 1;
companyLabel = new Label(parent, SWT.NONE);
companyLabel("company");
companyTextfield = new Text(parent, SWT.BORDER);
companyTextfield(gridData);
...
What I'm trying to accomplish is a label in the first line, that spans across both columns and have the following fields be ordered in pairs per line. What I get with this is, that the lable (that should be left in second line) is right in first line, just as the label wouldn't span across two columns. Can anybody see, what I'm doing wrong?
Thanx again!
After setting the layoutData to headlineLabel, you are setting the horizontalSpan to 1. You need to create a new LayoutData object for every SWT widget. It is not possible to reuse them after setting them.

Table shows extra blank columns at the end

I am using jface tableViewer.When table has no data in it ,it shows all columns correctly But when Data gets added to the table it shows extra blank space or column at the end of the table.
I am using TreeViewer + TreeViewerColumn and had this problem too, this workaround might work for your TableViewer too: Programmatically set the size of the last column on parent resize:
treeViewer.getTree().addControlListener(new ControlAdapter() {
public void controlResized(ControlEvent e) {
packAndFillLastColumn();
}
});
where the action is in
// Resize last column in tree viewer so that it fills the client area completely if extra space.
protected void packAndFillLastColumn() {
Tree tree = treeViewer.getTree();
int columnsWidth = 0;
for (int i = 0; i < tree.getColumnCount() - 1; i++) {
columnsWidth += tree.getColumn(i).getWidth();
}
TreeColumn lastColumn = tree.getColumn(tree.getColumnCount() - 1);
lastColumn.pack();
Rectangle area = tree.getClientArea();
Point preferredSize = tree.computeSize(SWT.DEFAULT, SWT.DEFAULT);
int width = area.width - 2*tree.getBorderWidth();
if (preferredSize.y > area.height + tree.getHeaderHeight()) {
// Subtract the scrollbar width from the total column width
// if a vertical scrollbar will be required
Point vBarSize = tree.getVerticalBar().getSize();
width -= vBarSize.x;
}
// last column is packed, so that is the minimum. If more space is available, add it.
if(lastColumn.getWidth() < width - columnsWidth) {
lastColumn.setWidth(width - columnsWidth);
}
}
Works well for me - you might want to set column resizable to false ;-). This can also be called when data in the last column changes (introducting / removing vertical scroll bar).
Thanks Thomas. Your idea worked for me as well, though I was using TableViewer and TableColumn.
Quoting my code so that others can take some hints.
`public void controlResized(ControlEvent e) {
if ( listOfTableColumns.size() != colProportions.length )
{
logger.warn( "Number of columns passed and size of column proportions array are different. " +
"Columns resizing shall not be effective on GUI window resizing" );
return;
}
Rectangle area = tableBaseComposite.getClientArea();
Point size = theTable.computeSize(SWT.DEFAULT, SWT.DEFAULT);
ScrollBar vBar = theTable.getVerticalBar();
int width = area.width - theTable.computeTrim(0,0,0,0).width - vBar.getSize().x;
if (size.y > area.height + theTable.getHeaderHeight()) {
// Subtract the scrollbar width from the total column width
// if a vertical scrollbar will be required
Point vBarSize = vBar.getSize();
width -= vBarSize.x;
}
Point oldSize = theTable.getSize();
if (oldSize.x > area.width) {
// table is getting smaller so make the columns
// smaller first and then resize the table to
// match the client area width
int index = 0 ;
for ( Iterator<TableColumn> iterator = listOfTableColumns.iterator(); iterator.hasNext(); )
{
TableColumn column = iterator.next();
column.setWidth( (int) numberFromPercentage( width, colProportions[index++] ) );
}
listOfTableColumns.get( listOfTableColumns.size() - 1).pack();
theTable.setSize(area.width, area.height);
} else {
// table is getting bigger so make the table
// bigger first and then make the columns wider
// to match the client area width
int index = 0;
theTable.setSize(area.width, area.height);
for ( Iterator<TableColumn> iterator = listOfTableColumns.iterator(); iterator.hasNext(); )
{
TableColumn column = iterator.next();
column.setWidth( (int) numberFromPercentage( width, colProportions[index++] ) );
}
listOfTableColumns.get( listOfTableColumns.size() - 1).pack();
}
}`
No need for complicated hacks to remove the extra unwanted column space at the end...
Just create a columnLayout:
TableColumnLayout columnLayout = new TableColumnLayout();
and then set it to each of your columns:
columnLayout.setColumnData(YOUR_VIEWER_COLUMN1.getColumn(), new ColumnPixelData(200));
columnLayout.setColumnData(YOUR_VIEWER_COLUMN2.getColumn(), new ColumnWeightData(200, 100));
Finally, set the layout on your parent composite:
parent.setLayout(columnLayout);
Full sample:
public void createPartControl(Composite parent) {
TableViewer viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
TableViewerColumn keyColumn = new TableViewerColumn(viewer, SWT.LEFT);
TableViewerColumn valueColumn = new TableViewerColumn(viewer, SWT.LEFT);
TableColumnLayout columnLayout = new TableColumnLayout();
columnLayout.setColumnData(keyColumn.getColumn(), new ColumnPixelData(200));
columnLayout.setColumnData(valueColumn.getColumn(), new ColumnWeightData(200, 100));
parent.setLayout(columnLayout);
}
Just guessing: maybe your columns do not get resized to fill all the table?
How do you set the widths of columns?
Consider using TableColumnLayout for the table container.
On windows, you will always get an extra column/row if the net width of all the columns that has been set up is less than the dimension of the table. So its always good to make your columns fit your table, also there is some space left for scroll bars, though I am not very sure about this, but its always better to specify whether you want vertical or horizontal scroll bars.
I used the packAndFillLastColumn() method and it worked for me. But I found one issue with it. My table was created with a border. After using the packAndFillLastColumn() method the border for the row no longer exists. I used the setLinesVisible(true) method within the packAndFillLastColumn() method but still that does not work.
So simple! Just remove this line in your table commands inside the createContents function:
table.getColumn(i).pack();
Good-luck
As a workaround use :
-For Column
use TableColumnLayout for the treeViewer's composite and set appropriate column data for each column using:
"tableColumnLayout.setColumnData(column,new ColumnWeightData(...as per your requirement));"
-For Row
Set GridData to the treeViewer's composite and provide height hint using
"gridData.heightHint = table.getItemHeight()*numberOfVisibleRows"
I found eclipse has marked it as WONTFIX.. so can not do much to remove this space..We have tp live with it...:)
To the end column we need to set the setWidth to window size or shell-size, parent-shell size like 1500,5000
final TableViewerColumn viewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
final TableColumn column = viewerColumn.getColumn();
column.setText(title);
column.setResizable(true);
column.setMoveable(true);
//set the setWidth size upto shell size or set upto to some size like 1000,1500,2000,5000
col.setWidth(comp.getShell().getSize().x); // or col.setWidth(1500) ;
return viewerColumn;

Using PdfWriter I cannot get rid of what appears to be a table border

Guys, this should be simple but pulling my hair out.Tried all variations and some places online say I should use cell events instead. I just want to switch off the black border. Can anyone help, seen this before? Many thanks in advance.
//Paragraph paymentLinePara;
//paymentLinePara = new Paragraph("\n"); UAT removed, js
//document.Add(paymentLinePara);
Table paymentLineTable = new Table(1);
paymentLineTable.SetAlignment("LEFT");
//build up headers
//Cell lineHeader = new Cell(new Phrase("xxx", font_small));
//lineHeader.Header = true;
//lineHeader.SetHorizontalAlignment("LEFT");
//lineHeader.SetVerticalAlignment("CENTER");
//lineHeader.BackgroundColor = new Color(0xC0, 0xC0, 0xC0);
//paymentLineTable.AddCell(lineHeader);
//add detail rows
foreach (var item in paymentItem.PaymentItemLines)
{
paymentLineTable.DefaultCell.BackgroundColor = Color.WHITE;
if (item.Display)
paymentLineTable.AddCell(new Phrase(item.Line, font_small));
}
paymentLineTable.Padding = 1;
paymentLineTable.DefaultCellBorderColor = Color.WHITE;
paymentLineTable.DefaultCellBorder = -1;
paymentLineTable.DefaultCellBorderWidth = 0;
paymentLineTable.Border = Rectangle.NO_BORDER;
document.Add(paymentLineTable);
This is iTextSharp, right? Try creating an actual Cell object:
Cell cell;
foreach (var item in paymentItem.PaymentItemLines)
{
cell = new Cell(new Phrase(item.Line, font_small));
cell.Border = 0;
if (item.Display)
paymentLineTable.AddCell(cell);
}
Comment out that default cell stuff temporarily.