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;
        
    

现在,您可以轻松使用JLabelDefaultTableCellRenderer,检查true/falseObject 值并相应地设置图标...但是其中的乐趣在哪里;)

已更新以包含编辑器...

我稍微重新排列了代码以包含一个单元格编辑器...

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 中的布尔复选框的主要内容,如果未能解决你的问题,请参考以下文章

Java:替换窗口左上角的咖啡杯图标

Java Swing OSX 窗口菜单复选标记

用图像图标替换编辑和删除 html 按钮

Java Swing:为啥我不能在 JFrame 实例上绘制图像()?

java中经常使用的Swing组件总结

如何将图标转换为图像