2

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

}
4

3 回答 3

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

现在,您可以轻松地使用JLabelor 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();
    }

}

您可以以与渲染器类似的方式应用...

table.setDefaultEditor(Boolean.class, new CustomBooleanCellEditor());
于 2013-04-12T05:27:02.117 回答
1

您将不得不使用

isSelected

查看该框是否被选中的方法,您可以使用 if 语句,如果选中,则使用

checkBox.setIcon(myIcon);

请注意,您也可以使用 ItemListener 来完成了解该框是否被选中的任务。

使用以下资源回答的问题: http ://www.roseindia.net/java/example/java/swing/CustomizedCheckBox.shtml

如何检查 JCheckBox 是否被选中?

于 2013-04-12T04:58:44.770 回答
0

假设您只有一个普通的 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);
}
于 2016-10-02T09:20:27.153 回答