Swing:用jtable绑定复杂对象列表

时间:2014-03-18 09:39:12

标签: java swing netbeans binding

我在Swing with Netbeans中开发一个小应用程序。我目前可以在带有Binding的jTable中显示对象列表。但是对象的一个​​属性是另一个对象:

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...
}

我有一个arraylist,其中包含4个名为mainObjectsList的实例化MainObjects。 jTable Elements绑定表达式为${mainObjectsList}

然后在jTable中,我可以看到我的对象属性,但是在myCustomProps列中,我只能看到对象地址(mytest.CustomProp@64ca87d5)。是否可以配置Binding表达式以在jTable中显示对象属性的参数?

1 个答案:

答案 0 :(得分:4)

要了解发生了什么,您需要了解JTable如何将您提供的内容转换为可显示的组件。

这是使用TableCellRenderer。这实质上是为每个包含JLabel数据表示的表格单元格创建String

默认渲染器对您的CustomProp类型一无所知,因此只需在其上调用toString即可获得String表示并显示它。

这会打开一条途径 - 更改toString的{​​{1}}。这种方法可行,但由于多种原因而存在问题:

  1. 你的对象不应该真正诱惑自己,这违反了关注点的分离。
  2. 您可以在其他地方使用CustomProp方法,例如在日志记录中使用,并且表中有意义的表示在那里没有意义
  3. toString不应该真正成为对象合同的一部分 - 在添加新字段时应该可以更改等等。如果使用表中的表示,那么情况并非如此(参见1 。)
  4. 话虽如此,Joshua Bloch's第10项("始终覆盖toString")确实声明toString可以成为对象合同的一部分,如果它有大量文件记录

    就个人而言,我希望通过扩展DefaultTableModel来设置toString的列类:

    TableModel

    然后,您需要在构建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); } } 时设置此模型而不是默认值:

    JTable

    现在,您的表知道final MyTableModel myTableModel = /*create as usual*/ final JTable jTable = new JTable(myTableModel); 列的类。创建自定义渲染器以渲染列:

    CustomProp

    并告诉您的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); } } 将您的渲染器用于课程JTable的列:

    CustomProp

    修改

    关注@ kleopatra的评论并注意到代码,我快速google并找到this previous SO post。看起来它正是要求的(或者可能完全不相关)。

    您应该可以使用jTable.setDefaultRenderer(CustomProp.class, new CustomPropRenderer()); 作为列的绑定。