当前位置: 首页 > 面试题库 >

Java Swing,尝试用图像图标复选框替换JTable中的布尔复选框

盖夕
2023-03-14
问题内容

所以我有一个带有复选框的JTable。我想让复选框
在“选中”时包含一个图像,而在“未选中”时包含另一个图像
(即,显示图像而不是选中或未选中的框)。是否
有办法做到这一点?我试着用TableCellRenderer愚弄它
返回带有ImageIcon的JLabel,但是它并不是非常有效。

更具体地说,当复选框处于选中状态或未选中状态时,右侧的图像
就会出现,但是当用户更改复选框状态(鼠标处于
按下状态)时,将显示原始选中/未选中的图像

这是我尝试过的TableCellRenderer(我也使用JPanels尝试过,但这
同样无效

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;
    }

}

问题答案:

您需要提供自己的自定义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;
        }
    }
}

现在,您可以轻松地使用aJLabel或DefaultTableCellRenderer,
检查/的Object值并相应地设置图标……但 这样做的乐趣何在?)truefalse

已更新,包括编辑器…

我已经稍微重新排列了代码,以包括单元格编辑器…

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();
    }

}

You can apply the in a similar way you did the renderer…

table.setDefaultEditor(Boolean.class, new CustomBooleanCellEditor());


 类似资料:
  • 问题内容: 我在表中有一个复选框列表。(该行中的多个CB之一) 我想用一对自定义的开/关图像替换复选框图像,我想知道是否有人对如何使用CSS更好地了解? 我已经找到了这个“ CSS ninja”教程,但是我不得不承认发现它对我来说有点复杂。 据我所知,您可以使用伪类 我的期望是,通过添加上述CSS,该复选框至少将默认显示为处于OFF状态的图像,然后添加以下内容以使ON 不幸的是,似乎我在某处缺少关

  • 我想发送到后端如果一个输入复选框已经被选中或没有。 这是正确的做法吗?因为我有个例外: TypeMismatchException:未能将类型“java.lang.String”的值转换为所需类型“java.lang.Boolean”;嵌套异常是java.lang.IllegalArgumentException:无效的布尔值[2] 我在后端以这种方式读取参数:

  • 我希望在选中表中的所有复选框时选中标题复选框,如果没有选中单个复选框,则应取消选中标题复选框。

  • 期望:如果取消选中/禁用复选框,我希望显示样例布尔值false

  • 问题内容: 我有一个JTable,我想用自定义渲染器尝试检查isEnabled()的所有禁用的复选框单元变灰,然后更改背景颜色,但仍然无法使用。有什么建议么?谢谢!!! 问题答案: 如“ 概念:编辑器和渲染器 ”中所述,“通常使用单个单元格渲染器来绘制包含相同类型数据的所有单元格。” 您需要维护表模型中的enabled状态。 附录:作为一个具体示例,此示例中的数据模型是一组简单的Date实例。ge