Java Swing,尝试用图像图标复选框替换 JTable 中的布尔复选框
Posted
技术标签:
【中文标题】Java Swing,尝试用图像图标复选框替换 JTable 中的布尔复选框【英文标题】:Java Swing, Trying to replace boolean check-box in a JTable with an image-icon checkbox 【发布时间】:2013-04-04 12:10:32 【问题描述】:所以我有一个带有复选框的 JTable。我希望复选框在“选中”时包含一个图像,而在“未选中”时包含另一个图像(即显示图像而不是选中或未选中的框)。有没有办法做到这一点?我尝试过使用返回带有 ImageIcon 的 JLabel 的 TableCellRenderer,但它并不是非常有效。
更具体地说,当复选框被选中或取消选中时,正确的图像就在那里,但是当用户更改复选框状态(鼠标按下时)时,会出现原始选中/未选中的图像
这是我尝试过的 TableCellRenderer(我也用 JPanel 尝试过,但这也无效
public class CrassusEventTableCellEyeRenderer extends JCheckBox implements TableCellRenderer
static Icon greyEye;
static Icon blackEye;
//STATIC CODE BLOCK
try
greyEye = new ImageIcon(ImageIO.read(new File("icons/shittyTest.png")));
blackEye = new ImageIcon(ImageIO.read(new File("icons/blackEye.png")));
catch (IOException e)
greyEye = null;
blackEye = null;
public CrassusEventTableCellEyeRenderer()
super();
this.addItemListener(new IsCheckedItemListener());
setIcon(greyEye);
//commented out code that I have tried in place of the IsCheckedItemListener
/*
@Override
public void setSelected(boolean sel)
super.isSelected();
if(sel)
setIcon(blackEye);
else
setIcon(greyEye);
*/
public class IsCheckedItemListener implements ItemListener
@Override
public void itemStateChanged(ItemEvent e)
if(isSelected())
setIcon(blackEye);
else
setIcon(greyEye);
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
System.out.println("value: "+value+", row: "+row+", column: "+column);
if(value instanceof Boolean)
setSelected(((Boolean) value).booleanValue());
return this;
【问题讨论】:
“我试过了..”如需更好的帮助,请尽快发帖SSCCE。one image when they are "checked" and another image when they are "unchecked"
实现这个之后你在做什么?只是为了好玩还是您正在努力实现某些目标? B'coz 通过查看图像最终用户将无法识别它的含义。
@Che 在我们的界面中没有足够的空间通过复选框进行描述;我还将尝试在鼠标悬停时在光标旁边获取描述。想想photo-shop图层界面中的“眼睛”和“锁”
【参考方案1】:
假设您只有一个普通的 JTable,您可以在渲染器和编辑器中设置适当的图标:
public void setIcons(Jtable table, int column, Icon icon, Icon selectedIcon)
JCheckBox cellRenderer = (JCheckBox) table.getCellRenderer(0, column);
cellRenderer.setSelectedIcon(selectedIcon);
cellRenderer.setIcon(icon);
DefaultCellEditor cellEditor = (DefaultCellEditor) table.getCellEditor(0, column);
JCheckBox editorComponent = (JCheckBox) cellEditor.getComponent();
editorComponent.setSelectedIcon(selectedIcon);
editorComponent.setIcon(icon);
【讨论】:
【参考方案2】:您需要提供自己的自定义 TableCellRenderer
,它能够提供您想要的功能...
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
public class TestTableRenderer
public static void main(String[] args)
new TestTableRenderer();
public TestTableRenderer()
EventQueue.invokeLater(new Runnable()
@Override
public void run()
try
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex)
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
);
public class TestPane extends JPanel
public TestPane()
TableModel model = new AbstractTableModel()
@Override
public int getRowCount()
return 2;
@Override
public int getColumnCount()
return 1;
@Override
public Object getValueAt(int rowIndex, int columnIndex)
return rowIndex == 0 ? true : false;
@Override
public Class<?> getColumnClass(int columnIndex)
return Boolean.class;
;
JTable table = new JTable(model);
table.setDefaultRenderer(Boolean.class, new CustomBooleanCellRenderer());
setLayout(new BorderLayout());
add(new JScrollPane(table));
@Override
public Dimension getPreferredSize()
return new Dimension(200, 200);
public class CustomBooleanCellRenderer extends JCheckBox implements TableCellRenderer
private ImageIcon sad;
private ImageIcon happy;
public CustomBooleanCellRenderer()
try
happy = new ImageIcon(ImageIO.read(getClass().getResource("/Happy.png")));
sad = new ImageIcon(ImageIO.read(getClass().getResource("/Sad.png")));
catch (IOException ex)
Logger.getLogger(TestTableRenderer.class.getName()).log(Level.SEVERE, null, ex);
@Override
public void setSelected(boolean selected)
super.setSelected(selected);
if (selected)
setIcon(happy);
else
setIcon(sad);
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
if (value instanceof Boolean)
boolean selected = (boolean) value;
setSelected(selected);
return this;
现在,您可以轻松使用JLabel
或DefaultTableCellRenderer
,检查true
/false
的Object
值并相应地设置图标...但是其中的乐趣在哪里;)
已更新以包含编辑器...
我稍微重新排列了代码以包含一个单元格编辑器...
public class CustomCheckBox extends JCheckBox
private ImageIcon sad;
private ImageIcon happy;
public CustomCheckBox()
try
happy = new ImageIcon(ImageIO.read(getClass().getResource("/Happy.png")));
sad = new ImageIcon(ImageIO.read(getClass().getResource("/Sad.png")));
catch (IOException ex)
ex.printStackTrace();
@Override
public void setSelected(boolean selected)
super.setSelected(selected);
if (selected)
setIcon(happy);
else
setIcon(sad);
public class CustomBooleanCellRenderer extends CustomCheckBox implements TableCellRenderer
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
if (value instanceof Boolean)
boolean selected = (boolean) value;
setSelected(selected);
return this;
public class CustomBooleanCellEditor extends AbstractCellEditor implements TableCellEditor
private CustomCheckBox editor;
public CustomBooleanCellEditor()
editor = new CustomCheckBox();
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
if (value instanceof Boolean)
boolean selected = (boolean) value;
editor.setSelected(selected);
return editor;
@Override
public Object getCellEditorValue()
return editor.isSelected();
您可以以与渲染器类似的方式应用...
table.setDefaultEditor(Boolean.class, new CustomBooleanCellEditor());
【讨论】:
我试过了,它的效果和我以前的一样好,但是有同样的问题。当鼠标放在复选框上时,会出现原始选中/未选中的框图像,尽管在选中该框后它可以正常工作。我很抱歉第一次没有明确说明我的问题;我已经编辑了问题 有一种更简单、更有效的方法,无需扩展渲染器/编辑器。您只需使用 JCheckBox 的方法 setIcon() 和 setSelectedIcon() - 就可以了。见这里:Trying to Replace Boolean CheckBox renderer/editor in JTable @DenisAbakumov 取决于您要执行的操作 - 您的示例将其设置为单个列,我的,设置为所有Boolean
类型【参考方案3】:
你必须使用
isSelected
查看是否选中该框的方法,您可以使用 if 语句,如果选中则使用
checkBox.setIcon(myIcon);
请注意,您也可以使用 ItemListener 来完成了解该框是否被选中的任务。
使用以下资源回答问题: http://www.roseindia.net/java/example/java/swing/CustomizedCheckBox.shtml
How to check that a JCheckBox is checked?
【讨论】:
我试过了,它的效果和我以前的一样好,但是有同样的问题。当鼠标放在复选框上时,会出现原始选中/未选中的框图像,尽管在选中该框后它可以正常工作。我很抱歉第一次没有明确说明我的问题;我已经编辑了这个问题。 另外,请注意这是在 TableCellRenderer 中,而不仅仅是 JCheckBox 本身。这可能是问题的根源,我不确定以上是关于Java Swing,尝试用图像图标复选框替换 JTable 中的布尔复选框的主要内容,如果未能解决你的问题,请参考以下文章