Java JTable 使用 TableCellRenderer 排序

2024-04-06

我对 Java 有点陌生,并且遇到了一些问题JTable与排序和TableCellRenderer.

我有一个包含 15 列的表,其中填充了值,在某些列上我使用TableCellRenderer根据单元格上的值将前景颜色更改为绿色或红色。

一切都工作正常,直到我尝试按某些列排序(排序部分没问题)... 问题在于格式化颜色不反映排序操作所做的更改。排序之前,颜色在表格上的原始位置保持不变。有没有一种简单的方法可以解决这个问题?

我进行了搜索,但没有找到可以实施的解决方案。

TIA

JL

编辑:发布相关源代码(未完整实现)

private void buildTab(){
    myIUserInterface.removeBottomTab("just a test");
    myJPanel = myIUserInterface.getBottomTab("just a test");
    myJScollPane = new JScrollPane();
    myTable = new JTable();
    myTable.setAutoCreateRowSorter(true);
    myTableContent = myFillTableData();
    String[] tableHeaders = {
            "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15"
        };
    myTable.setModel(new DefaultTableModel(myTableContent, tableHeaders) {

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return false;
        }
    });
    MyChangeCellColor myCCC = new MyChangeCellColor();
    Enumeration<TableColumn> allColumns = myTable.getColumnModel().getColumns();
    while(allColumns.hasMoreElements()){
        TableColumn column = allColumns.nextElement();
        column.setCellRenderer(myCCC);
    }
    myJScollPane.setViewportView(myTable);

    GroupLayout myLayout = new GroupLayout(myJPanel);
    myJPanel.setLayout(myLayout);
    myLayout.setHorizontalGroup(
        myLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(myJScollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 890, Short.MAX_VALUE)
    );
    myLayout.setVerticalGroup(
        myLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(myJScollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 672, Short.MAX_VALUE)
    );
}


class MyChangeCellColor extends JLabel implements TableCellRenderer {
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int column) {
        setHorizontalAlignment(CENTER);
        setOpaque(true);
        setBackground(Color.WHITE);
        if (column == 0){
            setForeground(Color.BLACK);
        }
        if (column == 1){
            setForeground(Color.BLACK);
        }
        if (column == 2){
            setForeground(Color.BLACK);
        }
        if (column == 3){
            setForeground(Color.BLACK);
        }
        if (column == 4){
            if ("LONG".equals(myTable.getModel().getValueAt(row, 4))) {
                setForeground(Color.GREEN.darker());
            }
            if ("SHORT".equals(myTable.getModel().getValueAt(row, 4))) {
                setForeground(Color.RED);
            }
        }
        if (column == 5){
            setForeground(Color.BLACK);
        }
        if (column == 6){
            setForeground(Color.BLACK);
        }
        if (column == 7){
            setForeground(Color.BLACK);
        }
        if (column == 8){
            setForeground(Color.BLACK);
        }
        if (column == 9){
            setForeground(Color.BLACK);
        }
        if (column == 10){
            setForeground(Color.BLACK);
        }
        if (column == 11){
            double d = Double.valueOf(myTable.getModel().getValueAt(row, 11).toString());
            if (d > 0) {
                setForeground(Color.GREEN.darker());
            }
            if (d == 0) {
                setForeground(Color.BLACK);
            }
            if (d < 0) {
                setForeground(Color.RED);
            }
        }
        if (column == 12){
            double d = Double.valueOf(myTable.getModel().getValueAt(row, 12).toString());
            if (d > 0) {
                setForeground(Color.GREEN.darker());
            }
            if (d == 0) {
                setForeground(Color.BLACK);
            }
            if (d < 0) {
                setForeground(Color.RED);
            }
        }
        if (column == 13){
            setForeground(Color.BLACK);
        }
        if (column == 14){
            setForeground(Color.BLACK);
        }
        setText(value.toString());
        return this;
    }
}

编辑2:解决方案喜欢并粘贴以供参考(如果有人需要的话)!只需要在 TableCellRenderer 类上的 JTable 返回的行上引用模型行(不确定是否已正确解释,无论如何您可以看到下面的更改):

class MyChangeCellColor extends JLabel implements TableCellRenderer {
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int column) {
        setHorizontalAlignment(CENTER);
        setOpaque(true);
        setBackground(Color.WHITE);
        if (column == 0){
            setForeground(Color.BLACK);
        }
        if (column == 1){
            setForeground(Color.BLACK);
        }
        if (column == 2){
            setForeground(Color.BLACK);
        }
        if (column == 3){
            setForeground(Color.BLACK);
        }
        if (column == 4){
            if ("LONG".equals(myTable.getModel().getValueAt(myTable.convertRowIndexToModel(row), 4))) {
                setForeground(Color.GREEN.darker());
            }
            if ("SHORT".equals(myTable.getModel().getValueAt(myTable.convertRowIndexToModel(row), 4))) {
                setForeground(Color.RED);
            }
        }
        if (column == 5){
            setForeground(Color.BLACK);
        }
        if (column == 6){
            setForeground(Color.BLACK);
        }
        if (column == 7){
            setForeground(Color.BLACK);
        }
        if (column == 8){
            setForeground(Color.BLACK);
        }
        if (column == 9){
            setForeground(Color.BLACK);
        }
        if (column == 10){
            setForeground(Color.BLACK);
        }
        if (column == 11){
            double d = Double.valueOf(myTable.getModel().getValueAt(myTable.convertRowIndexToModel(row), 11).toString());
            if (d > 0) {
                setForeground(Color.GREEN.darker());
            }
            if (d == 0) {
                setForeground(Color.BLACK);
            }
            if (d < 0) {
                setForeground(Color.RED);
            }
        }
        if (column == 12){
            double d = Double.valueOf(myTable.getModel().getValueAt(myTable.convertRowIndexToModel(row), 12).toString());
            if (d > 0) {
                setForeground(Color.GREEN.darker());
            }
            if (d == 0) {
                setForeground(Color.BLACK);
            }
            if (d < 0) {
                setForeground(Color.RED);
            }
        }
        if (column == 13){
            setForeground(Color.BLACK);
        }
        if (column == 14){
            setForeground(Color.BLACK);
        }
        setText(value.toString());
        return this;
    }
}

问题在于格式化颜色不反映排序操作所做的更改。

您的渲染器中的逻辑有问题。您可能正在使用“视图行”而不是“模型行”访问表模型中的数据。

既然你没有发布你的SSCCE演示问题我不能给你一个具体的解决方案,只能给你一个通用的解决方案。查看以下 JTable 方法:

convertRowIndexToModel(int viewRowIndex) 
convertRowIndexToView(int modelRowIndex)  

渲染器接收视图行号。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java JTable 使用 TableCellRenderer 排序 的相关文章

随机推荐