1

我这里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);
4

1 回答 1

4

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

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

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

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

查看使用自定义渲染器了解更多详情

更新示例

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

示例图片

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;
        }
    }
}
于 2013-03-08T04:54:06.983 回答