Java JTable值更改时更改整个列的颜色-Swing

Java JTable值更改时更改整个列的颜色-Swing,java,swing,jtable,tablecellrenderer,Java,Swing,Jtable,Tablecellrenderer,我在这里花了很长时间试图找到我问题的答案,但没有得到我预期的确切结果 我有一个JTable,每当我改变整列中的值时(每次只改变一列中的值)。 我想监听一个表的变化,当列中的数据发生变化时,列中的颜色也将发生变化,所有其他列都将使用默认颜色 以下是表侦听器的代码: Class CustomCellRenderer extends DefaultTableCellRenderer { public Component getTableCellRendererComponent(JTable

我在这里花了很长时间试图找到我问题的答案,但没有得到我预期的确切结果

我有一个JTable,每当我改变整列中的值时(每次只改变一列中的值)。 我想监听一个表的变化,当列中的数据发生变化时,列中的颜色也将发生变化,所有其他列都将使用默认颜色

以下是表侦听器的代码:

Class CustomCellRenderer extends DefaultTableCellRenderer {

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

        Component rendererComp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

        table.getModel().addTableModelListener(new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent e) {
                if(***here i want to know which column changed or something like that***){
                    rendererComp.setBackground(Color.CYAN);
                }

            }
        });

        return rendererComp ;
    }

}
这是创建表的代码:

private void createTable() {

        tablePanel.setLayout(new FlowLayout(FlowLayout.LEFT));

        DefaultTableModel tableModel = new DefaultTableModel(){

            @Override
            public boolean isCellEditable(int row, int column) {
               //all cells false
               return false;
            }
        };
        contentTable = new JTable(tableModel);

        contentTable.setGridColor(Color.LIGHT_GRAY);

        for(int i=0; i<columnSize; i++) {
            tableModel.addColumn("0");
        }

        for(int i=0; i<rawSize; i++) {
            tableModel.addRow(new Object[] { "" });
        }

        for(int i=0; i<rawSize; i++) {
            for(int j=0; j<tableModel.getRowCount(); j++) {
                tableModel.setValueAt("0", j, i);
            }
        }

        for(int i=0; i<ramSize; i++) {
            contentTable.getColumnModel().getColumn(i).setCellRenderer(new CustomCellRenderer());
        }

        JScrollPane scrollPane = new JScrollPane(contentTable);
        scrollPane.setPreferredSize(new Dimension(400, 150));

        tablePanel.add(scrollPane);
}
private void createTable(){
tablePanel.setLayout(新的FlowLayout(FlowLayout.LEFT));
DefaultTableModel tableModel=新的DefaultTableModel(){
@凌驾
公共布尔值可编辑(int行,int列){
//所有单元格均为假
返回false;
}
};
contentTable=新的JTable(tableModel);
contentTable.setGridColor(颜色:浅灰色);

对于(int i=0;i将所需状态存储在
TableModel
中;让
TableCellRenderer
使用状态相应地调整视图。在下面的示例中,只要
setValueAt()
更新任何单元格,
edited
标记为
true
。应用于第0列的呈现会相应地更改显示。请注意
clearEdited()
如何调用
fireTableDataChanged()
以强制在清除处理程序中调用该表时呈现所有单元格

附录:下面的更新显示了一种独立处理多个列的方法。
CustomModel
现在包含一个
Map
来存储应用了
CustomRenderer
的每个列的编辑状态。
CustomRenderer
现在调用
convertColumnIndexToModel()
并正确设置选择颜色

导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Component;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.event.ActionEvent;
导入java.util.HashMap;
导入java.util.Map;
导入javax.swing.AbstractAction;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.table.DefaultTableCellRenderer;
导入javax.swing.table.DefaultTableModel;
/**
*@见http://stackoverflow.com/a/37439731/230513
*/
公开课考试{
专用void display(){
JFrame f=新JFrame(“测试”);
f、 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CustomModel model=新CustomModel();
setColumnIdentifiers(新字符串[]{“A”,“B”});
对于(int i=0;i<16;i++){
addRow(新字符串[]{“A:+i”,B:+i});
}
JTable表格=新JTable(型号){
@凌驾
公共维度getPreferredScrollableViewportSize(){
返回新维度(100,getRowHeight()*getRowCount()/2);
}
};
table.getColumnModel().getColumn(0).setCellRenderer(新的CustomRenderer(模型));
table.getColumnModel().getColumn(1).setCellRenderer(新的CustomRenderer(模型));
f、 添加(新JScrollPane(表));
JPanel p=新的JPanel();
p、 添加(newjbutton(newupdateaction(“updatea”,model,0));
p、 添加(新的JButton(新的UpdateAction(“更新B”,model,1));
p、 添加(新JButton(新抽象操作(“清除”){
@凌驾
已执行的公共无效操作(操作事件e){
模型.clearEdited(0);
模型1;
}
}));
f、 添加(p,边界布局。南部);
f、 包装();
f、 setLocationRelativeTo(空);
f、 setVisible(真);
}
私有静态类CustomModel扩展了DefaultTableModel{
已编辑的私有最终映射=新HashMap();
公共布尔值已编辑(int列){
return edited.get(column)!=null&&edited.get(column);
}
公共无效清除编辑(int列){
编辑。放置(列,假);
fireTableDataChanged();
}
@凌驾
公共布尔值可编辑(int行,int列){
返回false;
}
@凌驾
public void setValueAt(对象有效、整行、整列){
super.setValueAt(aValue、row、column);
编辑。放置(列,真);
}
}
私有静态类CustomRenderer扩展了DefaultTableCellRenderer{
私有最终定制模型;
公共CustomRenderer(CustomModel模型){
this.model=模型;
}
@凌驾
公共组件GetTableCellRenderComponent(JTable表、对象值、,
布尔值(已选择,布尔值为焦点,整数行,整数列){
组件c=super.getTableCellRenderComponent(
表、值、isSelected、hasFocus、行、列);
if(model.isEdited(table.convertColumnIndexToModel(col))){
c、 挫折背景(颜色:青色);
}否则,如果(当选){
c、 挫折背景(table.getSelectionBackground());
}否则{
c、 挫折背景(table.getBackground());
}
返回c;
}
}
私有静态类UpdateAction扩展了AbstractAction{
私有最终定制模型;
私有的最后一个int列;
公共更新操作(字符串名称、CustomModel模型、int列){
超级(姓名);
this.model=模型;
this.column=列;
}
@凌驾
已执行的公共无效操作(操作事件e){
对于(int i=0;iimport java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

/**
 * @see http://stackoverflow.com/a/37439731/230513
 */
public class Test {

    private void display() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        CustomModel model = new CustomModel();
        model.setColumnIdentifiers(new String[]{"A", "B"});
        for (int i = 0; i < 16; i++) {
            model.addRow(new String[]{"A:" + i, "B:" + i});
        }
        JTable table = new JTable(model) {
            @Override
            public Dimension getPreferredScrollableViewportSize() {
                return new Dimension(100, getRowHeight() * getRowCount() / 2);
            }
        };
        table.getColumnModel().getColumn(0).setCellRenderer(new CustomRenderer(model));
        table.getColumnModel().getColumn(1).setCellRenderer(new CustomRenderer(model));
        f.add(new JScrollPane(table));
        JPanel p = new JPanel();
        p.add(new JButton(new UpdateAction("Update A", model, 0)));
        p.add(new JButton(new UpdateAction("Update B", model, 1)));
        p.add(new JButton(new AbstractAction("Clear") {
            @Override
            public void actionPerformed(ActionEvent e) {
                model.clearEdited(0);
                model.clearEdited(1);
            }
        }));
        f.add(p, BorderLayout.SOUTH);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static class CustomModel extends DefaultTableModel {

        private final Map<Integer, Boolean> edited = new HashMap<>();

        public boolean isEdited(int column) {
            return edited.get(column) != null && edited.get(column);
        }

        public void clearEdited(int column) {
            edited.put(column, false);
            fireTableDataChanged();
        }

        @Override
        public boolean isCellEditable(int row, int column) {
            return false;
        }

        @Override
        public void setValueAt(Object aValue, int row, int column) {
            super.setValueAt(aValue, row, column);
            edited.put(column, true);
        }
    }

    private static class CustomRenderer extends DefaultTableCellRenderer {

        private final CustomModel model;

        public CustomRenderer(CustomModel model) {
            this.model = model;
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int col) {
            Component c = super.getTableCellRendererComponent(
                table, value, isSelected, hasFocus, row, col);
            if (model.isEdited(table.convertColumnIndexToModel(col))) {
                c.setBackground(Color.cyan);
            } else if (isSelected) {
                c.setBackground(table.getSelectionBackground());
            } else {
                c.setBackground(table.getBackground());
            }
            return c;
        }
    }

    private static class UpdateAction extends AbstractAction {

        private final CustomModel model;
        private final int column;

        public UpdateAction(String name, CustomModel model, int column) {
            super(name);
            this.model = model;
            this.column = column;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            for (int i = 0; i < model.getRowCount(); i++) {
                model.setValueAt(model.getValueAt(i, column), i, column);
            }
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Test()::display);
    }
}