我正在尝试创建一个允许对项目进行收藏的JTable,但是不幸的是,正确的图像不会在初始渲染时显示,然后在它们失去单元格焦点之前不会正确更新。
为此,我将第1列设置为String,将第2列设置为布尔值。然后我根据这个问题改写了布尔渲染器/编辑器:
Java Swing, Trying to replace boolean check-box in a JTable with an image-icon checkbox
我目前有什么:
# locate tcmalloc | grep "\.so"
/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4
/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4.3.0
演示: 首先,我单击您看到复选标记的位置。当前没有显示正确的图像,而是默认的复选框图像。
我现在单击右下角以使该单元格失去焦点,然后用正确的图像填充自身。
另外一个注意事项:我自己添加了revalidate()和repaint(),没有它的行为基本上是相同的,除了它在初始渲染后将不再显示复选标记。直到失去焦点,它仍不会更新图像
答案 0 :(得分:2)
如果只有一列布尔值,则可以仅自定义复选框编辑器和渲染器使用的图标:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;
import java.text.*;
public class TableBasic extends JPanel
{
public TableBasic()
{
setLayout( new BorderLayout() );
String[] columnNames = {"Date", "String", "Integer", "Boolean"};
Object[][] data =
{
{new Date(), "A", new Integer(1), Boolean.TRUE },
{new Date(), "B", new Integer(2), Boolean.FALSE},
{new Date(), "C", new Integer(12), Boolean.TRUE },
{new Date(), "D", new Integer(5124), Boolean.FALSE}
};
DefaultTableModel model = new DefaultTableModel(data, columnNames)
{
// Returning the Class of each column will allow different
// renderers and editors to be used based on Class
@Override
public Class getColumnClass(int column)
{
for (int row = 0; row < getRowCount(); row++)
{
Object o = getValueAt(row, column);
if (o != null)
return o.getClass();
}
return Object.class;
}
};
JTable table = new JTable(model);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane( table );
add( scrollPane );
// Customize the icons of the renderer/editor used for Boolean data
Icon selectedIcon = new ImageIcon( "copy16.gif" );
Icon icon = new ImageIcon( "about16.gif" );
DefaultCellEditor dce = (DefaultCellEditor)table.getDefaultEditor(Boolean.class);
JCheckBox cbe = (JCheckBox)dce.getComponent();
cbe.setSelectedIcon( selectedIcon );
cbe.setIcon( icon );
TableCellRenderer tcr = table.getDefaultRenderer(Boolean.class);
JCheckBox cbr = (JCheckBox)tcr;
cbr.setSelectedIcon( selectedIcon );
cbr.setIcon( icon );
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("TableBasic");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TableBasic() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
如果需要多个布尔渲染器/编辑器,则需要为每个渲染器/编辑器创建唯一的实例。
创建编辑器很容易。您只需使用自定义JCheckBox创建DefaultCellEditor:
JCheckBox checkBox = new JCheckBox();
checkBox.setHorizontalAlignment(JCheckBox.CENTER);
checkBox.setSelectedIcon( selectedIcon );
checkBox.setIcon( icon );
DefaultCellEditor dce = new DefaultCellEditor( checkBox );
table.getColumnModel().getColumn(???).setCellEditor(dce);
创建渲染器更加困难。您需要创建一个自定义渲染器。这是在JTable源代码中找到的BooleanRenderer的默认渲染器代码:
static class BooleanRenderer extends JCheckBox implements TableCellRenderer, UIResource
{
private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
public BooleanRenderer() {
super();
setHorizontalAlignment(JLabel.CENTER);
setBorderPainted(true);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (isSelected) {
setForeground(table.getSelectionForeground());
super.setBackground(table.getSelectionBackground());
}
else {
setForeground(table.getForeground());
setBackground(table.getBackground());
}
setSelected((value != null && ((Boolean)value).booleanValue()));
if (hasFocus) {
setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
} else {
setBorder(noFocusBorder);
}
return this;
}
}
在构造函数中,您将设置图标。