从ArrayList创建DefaultTable

从ArrayList创建DefaultTable

如何从ArrayList创建DefaultTable:

public class FileModel extends AbstractTableModel implements TableModel{

    List<Object[]> data = new ArrayList<>();

    String titles[] = new String[] { "File Name", "Pages", "Media Box Height", "Media Box Width", "Trim Box Height",
            "Trim Box Width", "Path", "Error" };
    Class<?> types[] = new Class[] { String.class, Integer.class, Integer.class, Integer.class, Integer.class,  Integer.class, String.class, String.class };


我想将其用于彩色渲染器,因为目前渲染器只为“字符串”上色...
DefaultModel应该看起来像:

DefaultTableModel model = new DefaultTableModel(data, columnNames) {
            public Class getColumnClass(int column) {
                return getValueAt(0, column).getClass();
            }
        };


我当前的Colorrenderer外观如​​下:

    public class ColorRenderer extends DefaultTableCellRenderer {

    static final long serialVersionUID = 1L;
    final int STATUS_COL = 7;

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
            int row, int col) {

        Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
        String type = (String) table.getModel().getValueAt(row, 7);
        if ("Error" == type) {
            component.setBackground(Color.RED);
            component.setForeground(Color.WHITE);

        } else if (isSelected) {
            component.setBackground(table.getSelectionBackground());
            component.setForeground(table.getSelectionForeground());

        } else {
            component.setBackground(table.getBackground());
            component.setForeground(table.getForeground());
        }

        return component;

    }
}

最佳答案

仅有一些提示希望可以帮助您解决问题。

1)一个常见的错误是要求模型提供第一行值以检索列类。那是完全错误的。如果模型为空怎么办?我们将得到一个NullPointerException。由于我们知道模型(正在对其建模),因此我们完全有能力返回适当的类。例如:

DefaultTableModel model = new DefaultTableModel(data, columnNames) {
    @Override
    public Class<?> getColumnClass(int column) {
        // return getValueAt(0, column).getClass(); NO! Never do we have to do this.
        switch (column) {
            case 0: return String.class;
            case 1: return Integer.class;
            ...
            case 7: return String.class;
                default: throw new ArrayIndexOutOfBoundsException(column);
    }
};




2)在ColorRenderer类中,比较字符串有一个错误:

public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
    ...
    if ("Error" == type) { // This should be "Error".equals(type)
        ...
    }
    ...
}


How do I compare strings in Java?

此外,row变量表示视图中的行索引而不是模型,因此此行:

String type = (String) table.getModel().getValueAt(row, 7);


如果表已排序,则可能不会返回期望值。您需要像这样转换索引:

int modelIndex = table.convertRowIndexToModel(row);
String type = (String) table.getModel().getValueAt(modelIndex, 7);




3)关于此问题:“如何从ArrayList创建DefaultTable:”

如果要实现自己的表模型而不是使用DefaultTableModel,请参见this Q&A中检查的选项。

编辑


唯一的想法是只有字符串是彩色的...但是我有4个带有整数的列,它们仍然保持表格背景色。


答案取决于您如何设置默认渲染器,但我怀疑您正在这样做:

table.setDefaultRenderer(Object.class, new ColorRenderer());


它适用于String类,但不适用于Integer类,因为第二个具有表提供的默认渲染器,必须显式替换它,而第一个则不需要。有关渲染器/编辑器选择的完整且更好的说明,请参见Concepts: Editors and Renderers。出于实际目的,只需执行以下操作:

TableCellRenderer renderer = new ColorRenderer();
table.setDefaultRenderer(Number.class, renderer); // This will work for Integer, Double, Float...
table.setDefaultRenderer(Object.class, renderer);

07-24 09:18