【发布时间】:2013-05-24 18:00:19
【问题描述】:
可以根据外部值正确刷新背景,无需强制重绘
table.repaint();Based, used and tested with great code made by kleopatra and Hovercraft Full Of Eels
适用于 Java6/7,因为 API 没有任何变化
我的 SSCCE 工作正常,由JTable.repaint() 重绘
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
public class MyTableAndRenderer {
private JFrame frame = new JFrame();
private JPanel panel = new JPanel();
private String[] items = {"Item 1", "Item 2", "Item 3", "Item 4"};
private DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel(items);
private JComboBox combo = new JComboBox(comboBoxModel);
private JPanel panel1 = new JPanel();
private String[] columnNames = {"First Name", "Last Name", "Sport",
"# of Years", "Vegetarian"};
private Object[][] data = {
{"Kathy", "Smith", "Item 1", new Integer(5), (false)},
{"John", "Doe", "Item 1", new Integer(3), (true)},
{"Sue", "Black", "Item 3", new Integer(2), (false)},
{"Jane", "White", "Item 3", new Integer(20), (true)},
{"Joe", "Brown", "Item 3", new Integer(10), (false)}
};
private DefaultTableModel model = new DefaultTableModel(data, columnNames) {
private static final long serialVersionUID = 1L;
@Override
public Class getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
};
private JTable table = new JTable(model);
public MyTableAndRenderer() {
panel.setBorder(new EmptyBorder(10, 0, 2, 0));
panel.add(combo);
//@HFOE
/*table.setDefaultRenderer(Object.class, new 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);
String str = combo.getSelectedItem().toString();
if (value.toString().equalsIgnoreCase(str)) {
setBackground(Color.RED);
} else {
setBackground(null);
}
return this;
}
});*/
//@kleopatra
/*table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
String str = combo.getSelectedItem().toString();
if (value.toString().equalsIgnoreCase(str)) {
setBackground(Color.RED);
} else {
setBackground(null);
}
super.getTableCellRendererComponent(table, value, isSelected,
hasFocus, row, column);
return this;
}
});*/
table.setDefaultRenderer(Object.class, new 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);
String str = combo.getSelectedItem().toString();
if (value.toString().equalsIgnoreCase(str)) {
setBackground(Color.RED);
table.repaint();
} else {
setBackground(null);
table.repaint();
}
return this;
}
});
table.getTableHeader().setReorderingAllowed(false);
table.setAutoCreateRowSorter(true);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
panel1.setLayout(new GridLayout(1, 1, 10, 10));
panel1.add(new JScrollPane(table));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel, BorderLayout.NORTH);
frame.add(panel1);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
MyTableAndRenderer fs = new MyTableAndRenderer();
}
});
}
}
编辑
@Devolus 写道 你测试过我发布的内容吗?我从自己的工作代码中获取了这个 sn-p,我只是删除了中间的东西,因为它与答案无关。我在这里使用 Java 6,这对我有用。
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row, int column)
{
Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
... determine the color value ...
cell.setBackground(back);
cell.setForeground(fore);
}
- 引起
- Java6/7 无关紧要
来自代码(发布 SSCCE 的原因)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
public class MyTableAndRenderer {
private JFrame frame = new JFrame();
private JPanel panel = new JPanel();
private String[] items = {"Item 1", "Item 2", "Item 3", "Item 4"};
private DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel(items);
private JComboBox combo = new JComboBox(comboBoxModel);
private JPanel panel1 = new JPanel();
private String[] columnNames = {"First Name", "Last Name", "Sport",
"# of Years", "Vegetarian"};
private Object[][] data = {
{"Kathy", "Smith", "Item 1", new Integer(5), (false)},
{"John", "Doe", "Item 1", new Integer(3), (true)},
{"Sue", "Black", "Item 3", new Integer(2), (false)},
{"Jane", "White", "Item 3", new Integer(20), (true)},
{"Joe", "Brown", "Item 3", new Integer(10), (false)}
};
private DefaultTableModel model = new DefaultTableModel(data, columnNames) {
private static final long serialVersionUID = 1L;
@Override
public Class getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
};
private JTable table = new JTable(model);
public MyTableAndRenderer() {
panel.setBorder(new EmptyBorder(10, 0, 2, 0));
panel.add(combo);
table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
Component c = super.getTableCellRendererComponent(table, value, isSelected,
hasFocus, row, column);
String str = combo.getSelectedItem().toString();
if (value.toString().equalsIgnoreCase(str)) {
c.setBackground(Color.RED);
} else {
c.setBackground(null);
}
return this;
}
});
table.getTableHeader().setReorderingAllowed(false);
table.setAutoCreateRowSorter(true);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
panel1.setLayout(new GridLayout(1, 1, 10, 10));
panel1.add(new JScrollPane(table));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel, BorderLayout.NORTH);
frame.add(panel1);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
MyTableAndRenderer fs = new MyTableAndRenderer();
}
});
}
}
EDIT2
- 来自 WinXp(对于所有 Win OS 都不要使用 Nimbus,渲染器在那里非常有趣,从未见过,太好了!!!这怎么可能)
EDIT3:
请注意,我是尽可能简化的代码,在我的问题之前进行了测试,然后将渲染组件转换为 JComponent/JLabel 也不起作用(使用 JLabel.repaint()/setOpaque())
【问题讨论】:
-
我们还遇到了 jtable 问题,导致渲染器无法正确绘制其内容。然后我们决定使用 JXTable,它提供了使用Highlighters 突出显示单元格的概念。
-
@ymene 是的,我同意使用 SwingX(偏向于我 :-) 两件事:a)您的参考资料严重过时(自 0.8 以来 Highlighter API 发生了许多变化),不幸的是当前的 javadoc(版本 1.6.5-1) 不容易获得,只能通过从 maven b) 内部下载文档,当它的装饰发生变化时,一个亮点会触发一个 changeEvent,这反过来又会触发表重新绘制自身:)
-
只是为了强调您所学到的知识以及为未来的读者:最初的 SSCCE 这样做严重错误 - 就像在绘画周期中永远不会重新触发绘画一样,所以永远不要在 getXXCellRenderer 中调用 repaint
标签: java swing background jtable tablecellrenderer