简体   繁体   English

JTable值改变然后改变单元格颜色

[英]JTable valuechanged then change cell color

I have here a JTable with two(2) columns. 我这里有一个带有两(2)列的JTable The right column is an editable one while the other is not. 右列是可编辑的列,而另一列则不是。

So, what my problem is that whenever the user changed the value of a cell, that specific cell will changed its cell color. 所以,我的问题是,每当用户更改单元格的值时,该特定单元格将更改其单元格颜色。

I wanna do this because I want to let the user know that he/she made some changes in the table. 我想这样做是因为我想让用户知道他/她在表格中做了一些更改。

I found this somewhere and it somehow solved my problem but 1 thing that didn't come up with my expectation is that after changing the value and clicked another cell, the color changes back to its original color. 我在某个地方发现了它并且它以某种方式解决了我的问题,但是有一件事没有提出我的期望是在更改值并单击另一个单元格后,颜色会变回其原始颜色。 I want to let it stay until it is saved. 我想让它一直保留直到它被保存。

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

Is it possible? 可能吗? If yes, please show some example. 如果是,请举一些例子。

UPDATE: 更新:

    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);

Tables use a TableCellRenderer to paint values on the screen. 表使用TableCellRenderer在屏幕上绘制值。 The editors and renderers don't actually have anything to do with each other (from a painting point of view). 编辑和渲染器实际上并没有任何关系(从绘画的角度来看)。

So once the editor has been dismissed (accepted or cancelled), the cell is repainted using the assigned TableCellRenderer 因此,一旦编辑器被解雇(接受或取消),将使用指定的TableCellRenderer重新绘制单元格

You need to supply, in your table model, some way to determine which rows have been updated and change the state of the renderer to match. 您需要在表模型中提供某种方法来确定哪些行已更新,并更改渲染器的状态以匹配。

FYI- The DefaultTableCellRenderer uses a JLabel as it's base renderer, so it is transparent by default; 仅供参考 - DefaultTableCellRenderer使用JLabel作为其基本渲染器,因此默认情况下它是透明的; you will need to make it opaque to make it render properly. 你需要使它不透明才能使它正确渲染。

Check out Using custom renderers for more details 有关更多详细信息,请查看使用自定义渲染器

Update with example 以示例更新

This is nothing more then a proof of concept. 这仅仅是一个概念证明。 It will not meet your absolute requirements and you should take a serious look at the tutorial linked above. 它不符合您的绝对要求,您应该认真看看上面链接的教程。

示例图片

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;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM