the setWidth method for the TableViewerColumn class takes integer types, I would really like to use percentages, is there anyway to do this, or pack the table or something?
Use TableLayout to layout your table and use ColumnWeightData to specify the 'weight' of each column.
For example, two columns with a 60 / 40 weighting:
TableViewer viewer = ....
TableLayout layout = new TableLayout();
TableViewerColumn col1 = new TableViewerColumn(viewer, SWT.LEAD);
layout.setColumnData(col1.getColumn(), new ColumnWeightData(60));
TableViewerColumn col2 = new TableViewerColumn(viewer, SWT.LEAD);
layout.setColumnData(col2.getColumn(), new ColumnWeightData(40));
viewer.getTable().setLayout(layout);
And yes, you can pack the table/tree too.
for (final TreeColumn item : tree.getColumns()) {
item.pack();
}
for (final TableColumn item : table.getColumns()) {
item.pack();
}
Which is quite similar to the CTRL+NUM-PAD '+' Keycode on Windows.
Related
I have a JTable with a column of JComboBox<Integer>s and a column of JCheckBoxs. The JTable is set with the appropriate renderers and editors. The table looks fine at first, but after selecting a value from the combobox or checkbox, the cells seem to revert to the values of Integer and Boolean. The issue appears to be more than cosmetic, as methods that anticipate the cell having a combobox or a checkbox throw errors at finding an Integer or a Boolean.
Here is a picture of what it looks like:
And here is the code:
dataTable.removeAll();
numberOfVariables = 7;
Object[] header = new Object[numberOfVariables];
header[0] = new String("Ring Number");
header[1] = new String("Radius (cm)");
header[2] = new String("Plume Distribution");
header[3] = new String("Thickness (A)");
header[4] = new String("Deposition Time (s)");
header[5] = new String("Rate (A/s)");
header[6] = new String("Optimize (y/n)");
Object[][] data = new Object[numberOfRings][numberOfVariables];
for(int k=0;k<numberOfRings;++k){
Object[] row = new Object[numberOfVariables];
row[0] = Integer.toString(k+1);
row[1] = String.format("%.2f", plume.getRingRadius(k));
row[2] = createDistributionComboBoxForRing(k);
row[3] = String.format("%.2f", plume.getThicknessOfRing(k));
row[4] = String.format("%.2f", plume.getTimeForRing(k));
row[5] = String.format("%.2f", plume.getRateForRing(k));
row[6] = new JCheckBox();
((JCheckBox) row[6]).setSelected(true);
data[k] = row;
}
tableModel = new DefaultTableModel(data,header);
dataTable.setModel(tableModel);
dataTable.getColumnModel().getColumn(2).setCellRenderer(new ControlTableRenderer());
//dataTable.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor( createDistributionComboBoxForRing(0) ));
dataTable.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor( (JComboBox<Integer>) data[0][2] ));
dataTable.getColumnModel().getColumn(6).setCellRenderer(new ControlTableRenderer());
dataTable.getColumnModel().getColumn(6).setCellEditor(new DefaultCellEditor( (JCheckBox) data[0][6] ));
dataTable.updateUI();
row[2] = createDistributionComboBoxForRing(k);
row[3] = String.format("%.2f", plume.getThicknessOfRing(k));
row[4] = String.format("%.2f", plume.getTimeForRing(k));
row[5] = String.format("%.2f", plume.getRateForRing(k));
row[6] = new JCheckBox();
((JCheckBox) row[6]).setSelected(true);
The TableModel for a JTable stores data, not components.
So if column 3 contains an Integer object then you store an Integer in the TableModel and you set the editor for the column to be a combo box containing the list of valid Integers.
Same for the column containing the check box renderer/editor. In this case you store a Boolean object.
For example:
row[2] = new Integer(1);
row[6] = Boolean.TRUE
Now in the TableModel you need to tell the table what type of data is in each column so you need to override the getColumnClass(...) method. Something like:
tableModel = new DefaultTableModel(data,header)
{
#Override
public Class getColumnClass(int column)
{
switch (column)
{
case 2: return Integer.class;
case 6: return Boolean.class;
default: return Object.class;
}
}
};
Now the table can choose the appropriate renderer and editor for each column.
However, in the case of the combo box you do have to create a custom editor with the values for the combo box. See the section from the Swing tutorial on Using a Combo Box as an Editor for a working example on how to do this.
Also, you are incorrectly using some other methods:
dataTable.removeAll();
Not sure what that is for. That is a Container method to remove components from the panel. All you need is the setModel(...) statement to reset the table.
dataTable.updateUI();
There is no need to use the updateUI() method. That method is used internally when the LAF is changed. You are not changing the LAF so get rid of that statement.
The idea of cell renderers and editors is that you only have one component and that gets moved around and data changed for each row. The code uses a different JComponent instance for each cell. Just put the data in the table model and let the cell renderer and editors manage the components.
I have a C# application that generates a PDF invoice. In this invoice is a table of items and prices. This is generated using a PdfPTable and PdfPCells.
I want to be able to right-align the price column but I cannot seem to be able to - the text always comes out left-aligned in the cell.
Here is my code for creating the table:
PdfPTable table = new PdfPTable(2);
table.TotalWidth = invoice.PageSize.Width;
float[] widths = { invoice.PageSize.Width - 70f, 70f };
table.SetWidths(widths);
table.AddCell(new Phrase("Item Name", tableHeadFont));
table.AddCell(new Phrase("Price", tableHeadFont));
SqlCommand cmdItems = new SqlCommand("SELECT...", con);
using (SqlDataReader rdrItems = cmdItems.ExecuteReader())
{
while (rdrItems.Read())
{
table.AddCell(new Phrase(rdrItems["itemName"].ToString(), tableFont));
double price = Convert.ToDouble(rdrItems["price"]);
PdfPCell pcell = new PdfPCell();
pcell.HorizontalAlignment = PdfPCell.ALIGN_RIGHT;
pcell.AddElement(new Phrase(price.ToString("0.00"), tableFont));
table.AddCell(pcell);
}
}
Can anyone help?
I'm the original developer of iText, and the problem you're experiencing is explained in my book.
You're mixing text mode and composite mode.
In text mode, you create the PdfPCell with a Phrase as the parameter of the constructor, and you define the alignment at the level of the cell. However, you're working in composite mode. This mode is triggered as soon as you use the addElement() method. In composite mode, the alignment defined at the level of the cell is ignored (which explains your problem). Instead, the alignment of the separate elements is used.
How to solve your problem?
Either work in text mode by adding your Phrase to the cell in a different way.
Or work in composite mode and use a Paragraph for which you define the alignment.
The advantage of composite mode over text mode is that different paragraphs in the same cell can have different alignments, whereas you can only have one alignment in text mode. Another advantage is that you can add more than just text: you can also add images, lists, tables,... An advantage of text mode is speed: it takes less processing time to deal with the content of a cell.
private static PdfPCell PhraseCell(Phrase phrase, int align)
{
PdfPCell cell = new PdfPCell(phrase);
cell.BorderColor = BaseColor.WHITE;
// cell.VerticalAlignment = PdfCell.ALIGN_TOP;
//cell.VerticalAlignment = align;
cell.HorizontalAlignment = align;
cell.PaddingBottom = 2f;
cell.PaddingTop = 0f;
return cell;
}
Here is my derivation of user2660112's answer - one method to return a cell for insertion into a bordered and background-colored table, and a similar, but borderless/colorless variety:
private static PdfPCell GetCellForBorderedTable(Phrase phrase, int align, BaseColor color)
{
PdfPCell cell = new PdfPCell(phrase);
cell.HorizontalAlignment = align;
cell.PaddingBottom = 2f;
cell.PaddingTop = 0f;
cell.BackgroundColor = color;
cell.VerticalAlignment = PdfPCell.ALIGN_CENTER;
return cell;
}
private static PdfPCell GetCellForBorderlessTable(Phrase phrase, int align)
{
PdfPCell cell = new PdfPCell(phrase);
cell.HorizontalAlignment = align;
cell.PaddingBottom = 2f;
cell.PaddingTop = 0f;
cell.BorderWidth = PdfPCell.NO_BORDER;
cell.VerticalAlignment = PdfPCell.ALIGN_CENTER;
return cell;
}
These can then be called like so:
Font timesRoman9Font = FontFactory.GetFont(FontFactory.TIMES_ROMAN, 9, BaseColor.BLACK);
Font timesRoman9BoldFont = FontFactory.GetFont(FontFactory.TIMES_BOLD, 9, BaseColor.BLACK);
Phrase phrasesec1Heading = new Phrase("Duckbills Unlimited", timesRoman9BoldFont);
PdfPCell cellSec1Heading = GetCellForBorderedTable(phrasesec1Heading, Element.ALIGN_LEFT, BaseColor.YELLOW);
tblHeadings.AddCell(cellSec1Heading);
Phrase phrasePoisonToe = new Phrase("Poison Toe Toxicity Level (Metric Richter Scale, adjusted for follicle hue)", timesRoman9Font);
PdfPCell cellPoisonToe = GetCellForBorderlessTable(phrasePoisonToe, Element.ALIGN_LEFT);
tblFirstRow.AddCell(cellPoisonToe);
I ended up here searching for java Right aligning text in PdfPCell. So no offense if you are using java please use given snippet to achieve right alignment.
private PdfPCell getParagraphWithRightAlignCell(Paragraph paragraph) {
PdfPCell cell = new PdfPCell(paragraph);
cell.setBorderColor( BaseColor.WHITE);
cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
return cell;
}
In getParagraphWithRightAlignCell pass paragraph
Thanks
Perhaps its because you are mixing the different ways to add the cells? Have you tried explicitly creating a cell object, massaging it however you want then adding it for every cell?
Another thing you could try is setting the vertical alignment as well as the horizontal.
cell.HorizontalAlignment = Element.ALIGN_RIGHT;
How to put common table heading for two columns in JAVAFX
Like the image below
Any help would really be appreciated! Thanks!
You can try below code
TableColumn parentCol = new TableColumn("Parent");
TableColumn firstCol = new TableColumn("First");
TableColumn secondCol = new TableColumn("Second");
parentCol.getColumns().addAll(firstCol , secondCol );
I have a table viewer with 5 columns. In the 1st column I check some conditions and add an image and the rest of the columns will have text, But when I try to add the image and then add the rest of the columns with text then the 2nd column's text sits right beside the image in the 1st column. Here's my sample code snippet :
TableItem item = new TableItem(table, SWT.NONE);
if(condition) {
item.setImage(image);
}
else {
item.setImage(image);
}
item.setText(new String[]{"street", "city","state","Zip Code"});
Problem is that the string "street" sits right beside the image in the 1st column itself but I want the string "street" in the second column and the rest of the strings in the subsequent columns. What am I doing wrong here? How do I add table items from the 2nd column?
Each column in the table can have both an image and text.
Calling item.setImage(image) sets the image for the first column.
Calling item.setText(String []) sets the text for each column starting at the first column. So your "street" goes next to the image.
If you don't want text in the first column then set the text for that column to blank:
item.setText(new String[]{"", "street", "city", "state", "Zip Code"});
Update:
You can also set the text for individual columns with
item.setText(column, text);
If you are using TableViewer you should not be using TableItem, instead use the label provider and content provider.
Not as clear. If you want just an image in the first colum then then just provide an empty string:
item.setText(new String[]{"", "street", "city","state","Zip Code"});
But it is not worth working with jface without using the benefits of ContentProvider and LabelProvider. So you should read some jface tutorials before doing stuff like that.
Example:
TableViewer tableViewer = new TableViewer(container, SWT.BORDER | SWT.FULL_SELECTION);
tableViewer.setContentProvider(ArrayContentProvider.getInstance());
TableViewerColumn tableViewerColumnImg = new TableViewerColumn(tableViewer, SWT.NONE);
tableViewerColumnImg.setLabelProvider(new ColumnLabelProvider()
{
#Override
public Image getImage(Object element)
{
Person p = (Person) element;
return p.getImage();
}
});
TableColumn tblclmnImg = tableViewerColumnImg.getColumn();
tblclmnImg.setWidth(100);
tblclmnImg.setText("Img");
TableViewerColumn tableViewerColumnStreet = new TableViewerColumn(tableViewer, SWT.NONE);
tableViewerColumnStreet.setLabelProvider(new ColumnLabelProvider()
{
#Override
public String getText(Object element)
{
Person p = (Person) element;
return p.getStreet();
}
});
TableColumn tblclmnStreet = tableViewerColumnStreet.getColumn();
tblclmnStreet.setWidth(100);
tblclmnStreet.setText("Street");
tableViewer.setInput(//set an array of persons here
);
i try to use an org.eclipse.jface.viewers.CheckboxTableViewer, as a component of a org.eclipse.jface.wizard.WizardPage. I created it this way:
public void createControl(Composite parent) {
composite = new Composite(parent, SWT.NULL);
final GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 2;
composite.setLayout(gridLayout);
setControl(composite);
/* CheckboxTableViewer */
viewer = CheckboxTableViewer.newCheckList(composite, SWT.BORDER);
final Table table = viewer.getTable();
GridData data1 = new GridData();
data1.grabExcessHorizontalSpace = true;
data1.grabExcessVerticalSpace = true;
data1.horizontalSpan = 2;
data1.horizontalAlignment = SWT.FILL;
data1.verticalAlignment = SWT.FILL;
table.setLayoutData(data1);
table.setHeaderVisible(true);
table.setLinesVisible(true);
checkboxColumn = new TableColumn(table, SWT.LEFT);
...
the content of the viewer is inserted dynamically by a contentprovider. Everything works fine on gnome. While testing this on windows 7 (64 and 32 bit also), i am not able to select any entries of that view. Mouseclicks just seems to have no impact on the view.
I added a mouselistener to the table, and the mouseUp-/Down event is fired, selectionChanged and doubleClick on the viewer is not fired. Anyone who can explain this behaviour to me?
thx in advance,
hage
(i already posted this question in the eclipse forum without any response yet: http://www.eclipse.org/forums/index.php/t/250953/ )
You have to add another style flag while creating the CheckboxTableViewer: SWT.FULL_SELECTION
viewer = CheckboxTableViewer.newCheckList(composite, SWT.BORDER | SWT.FULL_SELECTION);
You can now select rows in the table by a single clicking.