我有一个JXTable设置用于以特定颜色绘制选定的单元格。但是,只要所选单元格位于顶行,就会显示表格中的所有单元格都已绘制。
任何人都可以帮助我理解为什么以及如何解决这个问题吗?
演示此问题的最小工作示例如下。
其他信息:每次调用Paint()时都会重新应用DefaultTableCellRenderer,因为它是我在完整程序中使用的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]; }
}
答案 0 :(得分:2)
我&#34;思考&#34;部分问题与您在选择更改时添加另一个荧光笔有关。
相反,请考虑仅在初始化表格时添加突出显示...
话虽如此,也没有必要扩展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];
}
}
}
答案 1 :(得分:0)
对于遇到此问题的其他人,这是我的解决方案。
问题是每次调用表的Paint()方法时(即每次选择更改时)都会创建一个新的TableCellRenderer对象。解决方案是将渲染器对象创建为表对象的字段,并简单地在Paint()方法中重新应用它(而不是重新创建它)。此表达式也需要在表的构造函数中应用。
我在此过程中进行的另一项代码改进是将上述相同规则应用于ColorHighlighter和HighlightPredicate对象。
即。表类变为:
class JXXTable extends JXTable {
DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
HighlightPredicate predicate = new HighlightPredicate(){
public boolean isHighlighted(Component renderer, ComponentAdapter adapter) {
return adapter.hasFocus();
}
};
Highlighter cellHighlight = new ColorHighlighter(predicate, null, null, new Color(115,164,209), Color.WHITE);
public JXXTable(CustomTableModel model){
super(model);
this.setDefaultRenderer(Object.class, renderer);
}
public void Paint(){
this.setDefaultRenderer(Object.class, renderer);
this.setHighlighters();
this.addHighlighter(cellHighlight);
}
}