1

ここJTableに 2 つの列があります。右側の列は編集可能な列ですが、もう一方の列は編集できません。

だから、私の問題は、ユーザーがセルの値を変更するたびに、その特定のセルがセルの色を変更することです。

ユーザーがテーブルに変更を加えたことをユーザーに知らせたいので、これを行いたいと思います。

私はこれをどこかで見つけて、どうにかして問題を解決しましたが、値を変更して別のセルをクリックすると、色が元の色に戻るという期待に至らなかったことが 1 つあります。保存されるまでそのままにしておきたいです。

@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

テーブルは a を使用TableCellRendererして画面に値を描画します。エディターとレンダラーは、実際には互いに何の関係もありません (ペイントの観点から)。

そのため、エディターが閉じられる (承認またはキャンセルされる) と、割り当てられたセルを使用してセルが再描画されます。TableCellRenderer

テーブル モデルで、どの行が更新されたかを判断し、レンダラーの状態を一致するように変更する何らかの方法を提供する必要があります。

参考までに- はベース レンダラーとしてDefaultTableCellRenderer使用するため、デフォルトでは透過的です。JLabel正しくレンダリングするには、不透明にする必要があります。

詳細については、カスタム レンダラーの使用をご覧ください。

例で更新

これは概念実証にすぎません。絶対的な要件を満たしていないため、上記のリンク先のチュートリアルを真剣に検討する必要があります。

サンプル画像

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 に答える