小编典典

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

java

所以我有一个带有复选框的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;
    }

}

阅读 264

收藏
2020-11-26

共1个答案

小编典典

您需要提供自己的自定义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());
2020-11-26