如何在JTable列中只选择一个复选框

我使用DefaultTableModel如下:

DefaultTableModel model = new DefaultTableModel (COLUMNS, 0 ) { @Override public boolean isCellEditable(int row, int column) { return (getColumnName(column).equals("Selected")); } public Class getColumnClass(int columnIndex) { if(getColumnName(columnIndex).equals("Selected")) return Boolean.class; return super.getColumnClass(columnIndex); } }; 

现在我想在“Selected”列中只选择一个复选框。 如何才能做到这一点。 我也尝试了以下方法,但它不起作用。

  public void fireTableCellUpdated(int row,int column) { if(getColumnName(column).equals("Selected")) { for(int i = 0; i<getRowCount() && i!=row;i++) setValueAt(Boolean.FALSE, row, column); } } 

  • @eatSleepCode写了@mKorbel你能不能给出实现setValueAt方法的示例代码。

  • (OP used)DefaultTableModel的代码,

  • 对于基于AbstractTableModel代码,需要保存通知程序fireTableCellUpdated(rowIndex, columnIndex)代码排序;因为/否则在JTables view不会重新绘制任何内容,

  • 这两个模型及其通知符之间存在一些重要的差异,并且(我的观点)没有理由打扰并使用AbstractTableModel作为基本内容(99pct的表模型)

在此处输入图像描述 。 。 。 。 在此处输入图像描述 。 。 。 。 在此处输入图像描述

 import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingUtilities; import javax.swing.table.DefaultTableModel; public class TableRolloverDemo { private JFrame frame = new JFrame("TableRolloverDemo"); private JTable table = new JTable(); private String[] columnNames = new String[]{"Column"}; private Object[][] data = new Object[][]{{false}, {false}, {true}, {true}, {false}, {false}, {true}, {true}, {false}, {false}, {true}, {true}}; public TableRolloverDemo() { final DefaultTableModel model = new DefaultTableModel(data, columnNames) { private boolean ImInLoop = false; @Override public Class getColumnClass(int columnIndex) { return Boolean.class; } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return true; } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { if (columnIndex == 0) { if (!ImInLoop) { ImInLoop = true; Boolean bol = (Boolean) aValue; super.setValueAt(aValue, rowIndex, columnIndex); for (int i = 0; i < this.getRowCount(); i++) { if (i != rowIndex) { super.setValueAt(!bol, i, columnIndex); } } ImInLoop = false; } } else { super.setValueAt(aValue, rowIndex, columnIndex); } } }; table.setModel(model); table.setPreferredScrollableViewportSize(table.getPreferredSize()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new JScrollPane(table)); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { TableRolloverDemo tableRolloverDemo = new TableRolloverDemo(); } }); } } 

您会收到堆栈溢出exception,因为setValueAt()方法会一次又一次地触发fireTableCellUpdated()方法。

相反,尝试使用一个表监听器,它将监听复选框的值更改,并将所有其他复选框的值设置为false。

您可以创建自己的自定义单元格编辑器,该编辑器连接ButtonGroup列中的所有复选框。 这是如何做:

 public class VeryComplicatedCellEditor extends DefaultCellEditor { private ArrayList groups; public getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { JCheckBox checkBox = new JCheckBox(); growToSize(column); groups.get(column).add(checkBox); return checkBox; } private growToSize(int size) { groups.ensureCapacity(size); while (groups.size() < size) groups.add(new ButtonGroup()); } } 

由于我们不知道表有多大这一事实,因此存在一些复杂问题,这些问题主要在growToSize方法中进行处理。

这种方式的工作方式是维护一个ButtonGroup列表,每列一个。 每个单元格的编辑器组件将添加到其列的按钮组中。