【问题标题】:Java Swing, Trying to replace boolean check-box in a JTable with an image-icon checkboxJava Swing,尝试用图像图标复选框替换 JTable 中的布尔复选框
【发布时间】: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图层界面中的“眼睛”和“锁”

标签: java swing jtable jcheckbox tablecellrenderer


【解决方案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 本身。这可能是问题的根源,我不确定
    猜你喜欢
    • 2013-12-31
    • 1970-01-01
    • 2012-06-06
    • 2016-04-20
    • 2014-01-21
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多