JTable Reverts JComboBox and JCheckBox to Values after Selection - java

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.

Related

How to add CheckBox object in table in JAVA Swing

I am having a table which is getting data from database. But I want to add a row with checkbox having attributes as name But everytime I run the program it show the value as
javax.swing.JCheckBox[ , 0, 0, 0x0, invalid, alignmentX = 0.0, alignmentY = 0.5, border = java................
Here is the code.
while(rs.next()) {
Vector row = new Vector();
String name = rs.getString("name");
String catid = rs.getString("catalogid");
String brand = rs.getString("brand");
String counter = rs.getString("counter");
String qty = rs.getString("qty");
String price = rs.getString("column_price");
row.add(name);
row.add(catid);
row.add(brand);
row.add(counter);
row.add(qty);
row.add(price);
cb = new JCheckBox(name, true);
row.add(cb);
model.addRow(row);
}
You don't add components to the TableModel of a JTable. You add data and use renderers to render the data.
So in your case you need to:
add Boolean.TRUE as the data to the TableModel.
override the getColumnClass(...) method of the TableModel to return Boolean.class so the table can render the Boolean object as a check box.
Read the Swing tutorial on How to Use Tables for more information and examples to get you started.

tableviewercolumn setwidth percentages instead of pixels

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.

JFace : Adding images to a table viewer is creating an issue

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
);

Insert row on jtable with DefaulTableModel on different methods

i want to add or insert column from different methods into one table.. cant explain it clearly but i show my codes to you to understand..for example.
(....)
DefaultTableModel dtm = new DefaultTableModel();
JTable table = new JTable();
Constructor(){
table.setModel(dtm);
(.....)
}
public void methodOne(){
String id = num.getText();
rs = stat.executeQuery("SELECT * FROM payments;");
Vector<String> header = new Vector<String>();
header.add("PAYMENT");
header.add("AMOUNT");
header.add("MODIFIER");
header.add("DATE MODIFIED");
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while(rs.next()) {
Vector<Object> row = new Vector<Object>();
row.add(rs.getString("description"));
row.add(rs.getString("amount"));
row.add(rs.getString("remarks"));
row.add(rs.getString("date"));
data.add(row);
} // loop
dtm.setDataVector(data , header);
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setBounds(0,0,490,250);
panel.add(scrollPane);
validate();
}
public void methodTwo(){
(.....)
rs = stat.executeQuery("SELECT * FROM record where idNum ='"+id+"';");
while(rs.next()){
Vector<Object> row = new Vector<Object>();
row.add(rs.getString("description"));
row.add(rs.getString("amount"));
row.add(rs.getString("remarks"));
row.add(rs.getString("date"));
data.add(row);
} // while
}
those value inside row are the value i want to add on my table, i dont have any idea on how to id.. i want it to be like this:
first when you run the java it will autoumatically create a table
http://i1023.photobucket.com/albums/af355/guiacustodio/javaaaaaaaaaaaaaaaaaaaaaaa_zpse9a22225.jpg
i have a button and textfield i enter number on the textfield i.e
[PAY BUTTON] TextField:[__100]
i clicked the button and this is what will happen:
http://i1023.photobucket.com/albums/af355/guiacustodio/javaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_zps43879eab.jpg
First of all, the data Vector you are using is defined inside methodOne so the same data is not accesible via methodTwo.
Secondly it is not because there is data being added to data in a tablemodel that the table will refresh, you have to call one of the methods that trigger an refresh event in the gui, normally one calls the method fireTableChanged on the tablemodel after you added data.
Thridly: there is an interesting library called GlazedLists that handles a lot of these things automatically !

Dynamically add images to JTable cells

I am dynamically adding data to a cell with the following code:
for(int i = 0; i < matchedSlots.size(); i++)
{
String title = matchedSlots.get(i).getTitle();
String director = matchedSlots.get(i).getDirector();
int rating = matchedSlots.get(i).getRating();
int runTime = matchedSlots.get(i).getRunningTime();
DefaultTableModel tm = (DefaultTableModel) searchResults.getModel();
tm.addRow(new Object[] {title,director,rating,runTime});
}
what do I need to add to the above to be able to add an image in the first cell of each row
By default JTable can render Images. You just need to override getColumnClass() in the TableModel and return Icon.class for 1st column.
Look at Renderers and Editors for more details.
ImageIcon image = new ImageIcon("image.gif");
...
tm.addRow(new Object[] {image,title,director,rating,runTime});
You may need to change your table model to account for the new column if you haven't already.
This short article should help you with the image renderer: http://mdsaputra.wordpress.com/2011/06/13/swing-hack-show-image-in-jtable/

Categories