2

私はチュートリアルに従って、JTable レンダラー/エディターに関するこのすべてを学びましたが、一連の条件に従ってセルを異なる色で表示するための条件付きレンダラーを作成しようとして行き詰まりました。

ここに私がまとめたSSCCEがあります:

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumnModel;

public class Demo2 extends javax.swing.JFrame {

    public Demo2() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(300, 300);
        this.getContentPane().setLayout(new java.awt.GridLayout(1, 1));
        Object[] colunas = {"Col 0"};
        Object[][] dados = {{"A"},{"B"},{"C"},{"D"}};
        JTable tbl = new JTable(dados,colunas);
        TableColumnModel tcm = tbl.getColumnModel();
        tcm.getColumn(0).setCellRenderer(new CustomCellRenderer());
        JScrollPane sp = new JScrollPane(tbl);
        this.add(sp);
    }

    class CustomCellRenderer extends DefaultTableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable jtable, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            Component c = super.getTableCellRendererComponent(jtable, value, isSelected, hasFocus, row, column);
            if (value.toString().equals("B")) {
                c.setForeground(Color.GREEN);
                c.setFont(c.getFont().deriveFont(Font.BOLD));
            } else if (value.toString().equals("D")) {
                c.setForeground(Color.BLUE);
                c.setFont(c.getFont().deriveFont(Font.BOLD));
            }
            return this;
        }
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Demo2().setVisible(true);
            }
        });
    }

}

予想通り、2 番目のセルは前景が緑で太字で、4 番目も青で太字です。ただし、他のセルも前景色の変更の影響を受けているようです。

ここに画像の説明を入力

ブレークポイントを使用してデバッグすると、setForeground が正しい行でのみ実行されていることがわかりますが、両方とも 2 回実行されますが、これは予想外でした。

さらに、最後のセルを「D」から「DD」に変更すると、すべてのセルの前景が緑色に変わります。

レンダラーに関する基本的な何かが欠けていると思います。

4

1 に答える 1

3

フォントを太字にしたり、色をデフォルトに戻したりする必要がない場合、どこでフォントを「太字から外す」のですか? これは自動的に行われるわけではありませんが、コードでこれを行う必要があることに注意してください。すべてのケースに対応できるようにするには、else ブロックを増やす必要があると思います。

つまり、

    @Override
    public Component getTableCellRendererComponent(JTable jtable, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        Component c = super.getTableCellRendererComponent(jtable, value, isSelected, hasFocus, row, column);
        if (value.toString().equals("B")) {
            c.setForeground(Color.GREEN);
            c.setFont(c.getFont().deriveFont(Font.BOLD));
        } else if (value.toString().equals("D")) {
            c.setForeground(Color.BLUE);
            c.setFont(c.getFont().deriveFont(Font.BOLD));
        } else {
           c.setForeground(null);
           c.setFont(c.getFont().deriveFont(Font.PLAIN));
        }
        return this;
    }

JTable セルは個々のコンポーネントではなくコンポーネントのレンダリングされたイメージです。それらはクッキーカッターで作られていると考えてください. 1 つのセルのカッターを変更し、元に戻さない場合、後続のすべてのセルが影響を受けます。

于 2013-01-16T01:04:35.950 に答える