Java 复选框仅位于一个JTable单元格中

Java 复选框仅位于一个JTable单元格中,java,swing,jtable,jcheckbox,Java,Swing,Jtable,Jcheckbox,我想创建一个包含两列的JTable,它看起来像一个调查。 所以在左边是问题,在右边用户可以给出答案。 但是在一行的右边应该有一个复选框,这样用户只能回答是或否 对于JTable,这可能吗?我如何实现这一点 关于您可以实现接口TableCellRenderer,为具有不同对象(如JTextField和JLabel)的单元格创建自定义渲染器。您必须实现getTableCellRenderComponent方法,并从中返回一个组件(如JPanel或您希望的组件),其中包含您希望在单元格上显示的组件。在

我想创建一个包含两列的
JTable
,它看起来像一个调查。 所以在左边是问题,在右边用户可以给出答案。 但是在一行的右边应该有一个复选框,这样用户只能回答是或否

对于
JTable
,这可能吗?我如何实现这一点


关于

您可以实现接口TableCellRenderer,为具有不同对象(如JTextField和JLabel)的单元格创建自定义渲染器。您必须实现getTableCellRenderComponent方法,并从中返回一个组件(如JPanel或您希望的组件),其中包含您希望在单元格上显示的组件。在表中,您将使用JTable.setDefaultRenderer()为自定义类设置新的渲染器

如果只有2个值,可能还可以将数据设置为布尔值,并让表将其显示为复选框(默认呈现)

这是第二种方法的代码,看起来更像您想要的

class CheckBoxModel extends AbstractTableModel{

        private final Object[][] rowData = {{"John" , true}, {"Mary", false}};
        final String columnNames[] = { "Student", "Approve" };

        @Override
        public int getRowCount() {
            return rowData.length;
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public Class<?> getColumnClass(final int columnIndex) {
            if (columnIndex == 1) {
                return Boolean.class; //renders column as a CheckBox
            }
            return super.getColumnClass(columnIndex);
        }

        @Override
        public Object getValueAt(final int rowIndex, final int columnIndex) {
            return rowData[rowIndex][columnIndex];
        }

        @Override
        public void setValueAt(final Object aValue, final int rowIndex, final int columnIndex) {
            rowData[rowIndex][columnIndex] = aValue;
            fireTableCellUpdated(rowIndex, columnIndex);
        }

        @Override
        public boolean isCellEditable(final int rowIndex, final int columnIndex) {
            return true;    //makes all cells editable
        }
}

您在评论中指出:

我用一列JCheckbox试过了,效果不错,但我只想把它放进去 单细胞

注意这个要求有点棘手。我认为您可以重写和方法,请求单元格值的类

这样,单元格呈现器/编辑器将成为
JCheckbox
,即使在对表的行进行排序或对表的列进行重新排列时也是如此

大概是这样的:

    JTable table = new JTable(model) {
        @Override
        public TableCellRenderer getCellRenderer(int row, int column) {
            if(getValueAt(row, column) instanceof Boolean) {
                return super.getDefaultRenderer(Boolean.class);
            } else {
                return super.getCellRenderer(row, column);
            }
        }

        @Override
        public TableCellEditor getCellEditor(int row, int column) {
            if(getValueAt(row, column) instanceof Boolean) {
                return super.getDefaultEditor(Boolean.class);
            } else {
                return super.getCellEditor(row, column);
            }
        }
    };
例子 这里是一个完整的示例

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

public class Demo {

    private void createAndShowGUI() { 

        DefaultTableModel model = new DefaultTableModel(new Object[]{"Column # 1", "Column # 2"}, 0);
        model.addRow(new Object[]{"Property # 1", "Value # 1"});
        model.addRow(new Object[]{"Property # 2", Boolean.TRUE});
        model.addRow(new Object[]{"Property # 3", "Value # 3"});

        JTable table = new JTable(model) {
            @Override
            public TableCellRenderer getCellRenderer(int row, int column) {
                if(getValueAt(row, column) instanceof Boolean) {
                    return super.getDefaultRenderer(Boolean.class);
                } else {
                    return super.getCellRenderer(row, column);
                }
            }

            @Override
            public TableCellEditor getCellEditor(int row, int column) {
                if(getValueAt(row, column) instanceof Boolean) {
                    return super.getDefaultEditor(Boolean.class);
                } else {
                    return super.getCellEditor(row, column);
                }
            }
        };
        table.setAutoCreateRowSorter(true);

        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(new JScrollPane(table));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {                
                new Demo().createAndShowGUI();
            }
        });
    }    
}
截图

是否仅选择一个选项?这听起来像是JRadioButton的作业,而不是JCheckbox。我尝试了一列JCheckbox,但我只想在一个单元格类[]columnTypes=新类[]{Object.Class,Object.Class,Boolean.Class};公共类getColumnClass(int columnIndex){返回columnTypes[columnIndex];};你能给我举个例子吗?@Jaran我已经发布了一些代码来实现我的建议。答案可能非常简单,请阅读Oracle官方教程-如何使用表。此外,我对第一段有点困惑:虽然正确,但它看起来与问题无关(据我所知)@kleopatra你是对的,我忘记了这件事。我已经更新了代码。第一种解决方案对于用户的需求来说可能有点太多了,但我还是让它来吧,因为它可能用于更复杂的数据显示,比如使用一个选项多于两个的列表。
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

public class Demo {

    private void createAndShowGUI() { 

        DefaultTableModel model = new DefaultTableModel(new Object[]{"Column # 1", "Column # 2"}, 0);
        model.addRow(new Object[]{"Property # 1", "Value # 1"});
        model.addRow(new Object[]{"Property # 2", Boolean.TRUE});
        model.addRow(new Object[]{"Property # 3", "Value # 3"});

        JTable table = new JTable(model) {
            @Override
            public TableCellRenderer getCellRenderer(int row, int column) {
                if(getValueAt(row, column) instanceof Boolean) {
                    return super.getDefaultRenderer(Boolean.class);
                } else {
                    return super.getCellRenderer(row, column);
                }
            }

            @Override
            public TableCellEditor getCellEditor(int row, int column) {
                if(getValueAt(row, column) instanceof Boolean) {
                    return super.getDefaultEditor(Boolean.class);
                } else {
                    return super.getCellEditor(row, column);
                }
            }
        };
        table.setAutoCreateRowSorter(true);

        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(new JScrollPane(table));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {                
                new Demo().createAndShowGUI();
            }
        });
    }    
}