Reputation: 109
I'm developping a small application in Swing with Netbeans. I currently can display a list of objects in a jTable with Binding. But one of the object's properties is another object:
public class CustomProp {
private String description;
private int value;
//constructor, getters and setters...
}
public class MainObject {
private int id;
private String name;
private boolean aBoolProp;
private CustomProp myCustomProp;
//constructors, getters and setters...
}
I have a arraylist with 4 instanced MainObjects named mainObjectsList. The jTable Elements binding espression is ${mainObjectsList}
Then in the jTable, I can see my objects properties but in myCustomProps column, I can see only the object address (mytest.CustomProp@64ca87d5). Is it possible to configure the Binding expression to display the parameters of the object property in the jTable?
Upvotes: 0
Views: 3633
Reputation: 61198
To understand what is going on you need to understand how a JTable
turns what you give it into a displayable component.
This is does using a TableCellRenderer
. What this essentially does it create a JLabel
for each table cell that contains a String
representation of the data.
The default renderer doesn't have any idea about your CustomProp
type so all it does it call toString
on it to get a String
representation and display it.
This opens one avenue - change the toString
of your CustomProp
. This approach will work, but is hacky for a number of reasons:
toString
method may well be used elsewhere, in logging for example, and the representation that makes sense in the table will not make sense theretoString
should not really be part of an object's contract - it should be changeable when new fields are added etc. If you use the representation in the table then that is not the case (see 1.)Having said that, Joshua Bloch's Item 10 ("Always override toString") does state that toString
can be part of an object's contract if it is heavily documented.
Personally, I would prefer to set the column class of the TableModel
by extending DefaultTableModel
:
private static final class MyTableModel extends DefaultTableModel {
private static final int CUSTOM_PROP_COL = 1;
//various required constructors, call super(...)
@Override
public Class<?> getColumnClass(final int columnIndex) {
if (columnIndex == CUSTOM_PROP_COL) {
return CustomProp.class;
}
return super.getColumnClass(columnIndex);
}
}
Then you need to set this model rather than the default when you build your JTable
:
final MyTableModel myTableModel = /*create as usual*/
final JTable jTable = new JTable(myTableModel);
Now your table knows the class of the column with CustomProp
. Create a custom renderer to render the column:
private static final class CustomPropRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
final CustomProp prop = (CustomProp) value;
final StringBuilder representation = new StringBuilder();
//build a string representation of prop
return super.getTableCellRendererComponent(table, representation.toString(), isSelected, hasFocus, row, column);
}
}
And tell your JTable
to use your renderer for columns of class CustomProp
:
jTable.setDefaultRenderer(CustomProp.class, new CustomPropRenderer());
EDIT
Following @kleopatra's comment and noticing the netbeans tag I did a quick google and found this previous SO post. Looks like it is either exactly what is required (or possible completely irrelevant).
You should be able to use ${customProp.property}
as the binding for the column.
Upvotes: 4