2

選択したセルを特定の色でペイントするように JXTable を設定しました。ただし、選択したセルが一番上の行にある場合は常に、テーブル内のすべてのセルが塗りつぶされているように見えます。

この問題の理由と解決方法を理解できる人はいますか?

この問題を示す最小の実例を以下に示します。

追加情報: DefaultTableCellRenderer は、Paint() が呼び出されるたびに再適用されます。これは、完全なプログラムで使用する CustomTableCellRenderer のプレースホルダーであるためです。興味深いことに、DefaultTableCellRenderer の行を削除すると、問題は解決されます。どうしてこれなの?確かに、レンダラーが指定されていない場合、とにかくデフォルトが使用されますか??

import java.awt.Color;
import java.awt.Component;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.decorator.ColorHighlighter;
import org.jdesktop.swingx.decorator.ComponentAdapter;
import org.jdesktop.swingx.decorator.HighlightPredicate;

public class MainClass {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        CustomTableModel tableModel = new CustomTableModel();
        JXXTable table = new JXXTable(tableModel);
        JScrollPane scrollPane = new JScrollPane(table);
        SelectionListener listener = new SelectionListener(table);
        table.getSelectionModel().addListSelectionListener(listener);    
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.add(scrollPane);
        frame.setVisible(true);
        frame.pack();
    }
}

class JXXTable extends JXTable {
    public JXXTable(CustomTableModel model){ super(model); }
    public void Paint(){
        this.setDefaultRenderer(Object.class, new DefaultTableCellRenderer());
        this.setHighlighters();
        HighlightPredicate predicate = new HighlightPredicate() {
            public boolean isHighlighted(Component renderer, ComponentAdapter adapter) {
                return adapter.hasFocus();
            }
        };
        this.addHighlighter(new ColorHighlighter(predicate, null, null, new Color(115,164,209), Color.WHITE)); 
    }
}

class SelectionListener implements ListSelectionListener {
    JXXTable table;
    public SelectionListener(JXXTable table) { this.table = table; }
    public void valueChanged(ListSelectionEvent e) { table.Paint(); }
}

class CustomTableModel extends AbstractTableModel {
    ArrayList<Object[]> al;

    public CustomTableModel() {
        al = new ArrayList<Object[]>(); 
        Object[] row = {1,2,3,"A","Collection","of","Random","Strings",9,10}; al.add(row);
        Object[] row2 = {11,12,13,"Another","Collection","Of","Random","Strings",19,20}; al.add(row2);
        Object[] row3 = {11,12,13,"Another","Collection","Of","Random","Strings",19,20}; al.add(row3);
        Object[] row4 = {11,12,13,"It","just","gets","more","random...",19,20}; al.add(row4);
    }

    public int getRowCount() { return al.size(); }
    public int getColumnCount() { return 10; }
    public Object getValueAt(int rowIndex, int columnIndex) { return al.get(rowIndex)[columnIndex]; }
}
4

2 に答える 2

2

問題の一部は、選択が変更されるたびに別のハイライターを追加することに関係していると「思います」。

代わりに、テーブルを初期化するときにのみ強調表示を追加することを検討してください...

そうは言っても、 を拡張する必要もありJXTableません。クラスに新しい機能を実際に追加しているわけではありません。代わりに、必要なテーブルを構成する何らかのファクトリを作成できます

ここに画像の説明を入力

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.decorator.ColorHighlighter;
import org.jdesktop.swingx.decorator.HighlightPredicate;

public class MainClass {

    public static void main(String[] args) {
        new MainClass();
    }

    public MainClass() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                CustomTableModel tableModel = new CustomTableModel();
                JXTable table = new JXTable(tableModel);
                table.setDefaultRenderer(Object.class, new CustomTableCellRenderer());
                HighlightPredicate predicate = new HighlightPredicate() {
                    @Override
                    public boolean isHighlighted(Component cmpnt, org.jdesktop.swingx.decorator.ComponentAdapter ca) {
                        System.out.println(ca.getComponent());
                        return ca.hasFocus();
                    }
                };
                table.addHighlighter(new ColorHighlighter(predicate, null, null, new Color(115, 164, 209), Color.WHITE));

                JScrollPane scrollPane = new JScrollPane(table);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(scrollPane);
                frame.setVisible(true);
                frame.pack();
            }
        });
    }

    class CustomTableCellRenderer extends DefaultTableCellRenderer {

        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            return (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        }
    }

    class CustomTableModel extends AbstractTableModel {

        ArrayList<Object[]> al;

        public CustomTableModel() {
            al = new ArrayList<Object[]>();
            Object[] row = {1, 2, 3, "A", "Collection", "of", "Random", "Strings", 9, 10};
            al.add(row);
            Object[] row2 = {11, 12, 13, "Another", "Collection", "Of", "Random", "Strings", 19, 20};
            al.add(row2);
            Object[] row3 = {11, 12, 13, "Another", "Collection", "Of", "Random", "Strings", 19, 20};
            al.add(row3);
            Object[] row4 = {11, 12, 13, "It", "just", "gets", "more", "random...", 19, 20};
            al.add(row4);
        }

        public int getRowCount() {
            return al.size();
        }

        public int getColumnCount() {
            return 10;
        }

        public Object getValueAt(int rowIndex, int columnIndex) {
            return al.get(rowIndex)[columnIndex];
        }
    }
}
于 2014-10-26T03:49:40.017 に答える