【问题标题】:JTable valuechanged then change cell colorJTable valuechanged 然后更改单元格颜色
【发布时间】:2013-02-23 13:55:46
【问题描述】:

我这里有一个JTable,有两 (2) 列。右列是可编辑的,而另一列不可编辑。

所以,我的问题是,每当用户更改单元格的值时,该特定单元格就会改变其单元格颜色。

我想这样做是因为我想让用户知道他/她在表格中做了一些更改。

我在某个地方找到了这个,它以某种方式解决了我的问题,但我没有想到的一件事是,在更改值并单击另一个单元格后,颜色变回原来的颜色。我想让它一直存在,直到它被保存。

@Override
public Component prepareEditor(TableCellEditor editor, int data, int columns) {
    Component c = super.prepareEditor(editor, data, columns);
    c.setBackground(Color.RED);
    return c;
}

有可能吗?如果是,请举个例子。

更新:

    String[] columnname = {"Student Name", "Grade"};

    Object[][] data = {};

    gradetable = new JTable(data, columnname){
        private Object[][] rowData;

        public boolean isCellEditable(int data, int columns){
            return columns == 1;
        }


        public Component prepareRenderer(TableCellRenderer r, int data, int columns){
            final Component c = super.prepareRenderer(r, data, columns);

            if (data % 2 == 0){
                c.setBackground(Color.LIGHT_GRAY);
            }
            else{
                c.setBackground(Color.WHITE);
            }

            if (isCellSelected(data, columns)){
                c.setBackground(Color.ORANGE);
            }                

            return c;
        }

        @Override
        public Component prepareEditor(TableCellEditor editor, int data, int columns) {
            Component c = super.prepareEditor(editor, data, columns);
            c.setBackground(Color.RED);
            return c;
        }
    };

    gradetable.setModel(new DefaultTableModel(data, columnname));
    gradetable.setPreferredScrollableViewportSize(new Dimension (350, 130));
    gradetable.setFillsViewportHeight(true);
    gradetable.getTableHeader().setReorderingAllowed(false);
    gradetable.setGridColor(new Color(128,128,128,128));
    JScrollPane jsp = new JScrollPane(gradetable);
    panel3.add(jsp);

【问题讨论】:

    标签: java swing colors jtable valuechangelistener


    【解决方案1】:

    表格使用TableCellRenderer 在屏幕上绘制值。编辑器和渲染器实际上彼此之间没有任何关系(从绘画的角度来看)。

    因此,一旦编辑器被解雇(接受或取消),就会使用分配的 TableCellRenderer 重新绘制单元格

    您需要在表模型中提供某种方式来确定哪些行已更新并更改渲染器的状态以进行匹配。

    仅供参考-DefaultTableCellRenderer 使用JLabel 作为其基本渲染器,因此默认情况下它是透明的;您需要使其不透明以使其正确呈现。

    查看Using custom renderers了解更多详情

    更新示例

    这只不过是一个概念证明。它不会满足您的绝对要求,您应该认真查看上面链接的教程。

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableColumnModel;
    import javax.swing.table.TableModel;
    
    public class TableEdit {
    
        public static void main(String[] args) {
            new TableEdit();
        }
    
        public TableEdit() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
                setLayout(new BorderLayout());
                JTable table = new JTable(new MyTableModel());
                table.setSurrendersFocusOnKeystroke(true);
                TableColumnModel model = table.getColumnModel();
                model.getColumn(1).setCellRenderer(new MyTableCellRenderer());
                add(new JScrollPane(table));
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
        }
    
        public class MyData {
    
            private String key;
            private String value;
            private boolean changed;
    
            public MyData(String key, String value) {
                this.key = key;
                this.value = value;
                this.changed = false;
            }
    
            public String getKey() {
                return key;
            }
    
            public String getValue() {
                return value;
            }
    
            public void setValue(String newValue) {
                if (value == null ? newValue != null : !value.equals(newValue)) {
                    value = newValue;
                    changed = true;
                }
            }
    
            public boolean hasChanged() {
                return changed;
            }
        }
    
        public class MyTableModel extends AbstractTableModel {
    
            private List<MyData> data;
    
            public MyTableModel() {
                data = new ArrayList<>(25);
                for (int index = 0; index < 5; index++) {
                    data.add(new MyData("A" + (index + 1), "B" + (index + 1)));
                }
            }
    
            @Override
            public int getRowCount() {
                return data.size();
            }
    
            @Override
            public int getColumnCount() {
                return 2;
            }
    
            @Override
            public Object getValueAt(int rowIndex, int columnIndex) {
                MyData myData = data.get(rowIndex);
                Object value = null;
                switch (columnIndex) {
                    case 0:
                        value = myData.getKey();
                        break;
                    case 1:
                        value = myData.getValue();
                        break;
                }
                return value;
            }
    
            @Override
            public Class<?> getColumnClass(int columnIndex) {
                return String.class;
            }
    
            @Override
            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return columnIndex == 1;
            }
    
            public boolean hasChanged(int rowIndex) {
                MyData myData = data.get(rowIndex);
                return myData.hasChanged();
            }
    
            @Override
            public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
                MyData myData = data.get(rowIndex);
                myData.setValue(aValue == null ? null : aValue.toString());
            }
        }
    
        public class MyTableCellRenderer extends DefaultTableCellRenderer {
    
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                setOpaque(isSelected);
                TableModel model = table.getModel();
                if (model instanceof MyTableModel) {
                    MyTableModel myModel = (MyTableModel) model;
                    if (myModel.hasChanged(row)) {
                        if (!isSelected) {
                            setBackground(Color.RED);
                            setOpaque(true);
                        } 
                    }
                }
                return this;
            }
        }
    }
    

    【讨论】:

    • 您好 MadProgrammer,感谢您的回复。你能告诉我一个解决我的问题的示例程序吗?
    • 当然,答案中已链接
    • 您好,MadProgrammer,我研究了您的代码,但不知道如何将您的代码与我的代码相关联。所以,我编辑了我的问题并发布了创建我的 jtable 的代码。我希望您可以对其进行修改,使其与您在上面所做的工作一样。提前致谢。
    猜你喜欢
    • 2011-08-06
    • 2011-11-03
    • 2018-08-20
    • 2011-08-14
    • 2011-09-24
    • 2014-08-24
    • 2020-08-25
    • 2011-08-13
    • 1970-01-01
    相关资源
    最近更新 更多