Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在JTable列中仅选择一个复选框_Java_Swing_Jtable_Jcheckbox_Defaulttablemodel - Fatal编程技术网

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

Java 如何在JTable列中仅选择一个复选框,java,swing,jtable,jcheckbox,defaulttablemodel,Java,Swing,Jtable,Jcheckbox,Defaulttablemodel,我使用的DefaultTableModel如下所示: DefaultTableModel model = new DefaultTableModel (COLUMNS, 0 ) { @Override public boolean isCellEditable(int row, int column) { return (getColumnName(column).equals("Selected")); }

我使用的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);
     }
 }
public void fireTableCellUpdated(int行,int列)
{
if(getColumnName(column).equals(“选定”))
{

对于(int i=0;i您会得到一个堆栈溢出异常,因为setValueAt()方法会一次又一次地触发fireTableCellUpdated()方法


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

您可以创建自己的自定义单元格编辑器,将所有复选框连接到
按钮组中的列中。方法如下:

public class VeryComplicatedCellEditor extends DefaultCellEditor {
    private ArrayList<ButtonGroup> 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());
    }
}
public类verycomplectedCellEditor扩展了DefaultCellEditor{
私有ArrayList组;
公共getTableCellEditorComponent(JTable表、对象值、布尔ISselect、int行、int列){
JCheckBox checkBox=新的JCheckBox();
growToSize(列);
groups.get(列).add(复选框);
返回复选框;
}
私有growToSize(整数大小){
群体。人口(规模);
while(groups.size()
我们不知道表有多大,这一事实导致了一些复杂情况,这主要是在
growToSize
方法中处理的

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

  • @eatSleepCode编写了@mKorbel。请给出实现setValueAt方法的示例代码

  • (OP使用)DefaultTableModel的代码

  • 对于基于
    AbstractTableModel
    的代码,需要保留通知程序
    fireTableCellUpdated(rowIndex,columnIndex)
    ;的代码顺序,因为/否则将不会在
    JTables视图中重新绘制任何内容

  • 这两个模型及其通知程序之间有一些重要的区别,(我的观点)没有理由为基本内容(99%的表模型)而烦恼和使用
    AbstractTableModel

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();
            }
        });
    }
}
import javax.swing.JFrame;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.SwingUtilities;
导入javax.swing.table.DefaultTableModel;
公共类表格{
私有JFrame=新JFrame(“TableRollorVerdemo”);
私有JTable表=新JTable();
私有字符串[]columnNames=新字符串[]{“Column”};
私有对象[][]数据=新对象[][{{false},{false},{true},{true},
{false}、{false}、{true}、{true}、{false}、{false}、{true}、{true};
公共表格{
最终DefaultTableModel=新的DefaultTableModel(数据、列名){
私有布尔值ImInLoop=false;
@凌驾
公共类getColumnClass(int columnIndex){
返回Boolean.class;
}
@凌驾
公共布尔值isCellEditable(int-rowIndex、int-columnIndex){
返回true;
}
@凌驾
public void setValueAt(对象有效、int行索引、int列索引){
如果(columnIndex==0){
如果(!iminLop){
ImInLoop=真;
布尔bol=(布尔)aValue;
super.setValueAt(aValue、rowIndex、columnIndex);
对于(int i=0;i
如果我理解正确,您想实现单选按钮功能吗?“它不工作”-您能说得更具体一点吗?它是否会抛出一个
异常
,或者其他一些有用的信息?您看到了什么?我能知道您使用的是什么IDE吗?您得到了
StackOverFlowException
,因为
setValueAt()
将导致调用
fireTableCellUpdated()
,再次调用前者。它可能会引发StackOverflow,因为fireTableCellUpdated方法层叠不断。这不会有完全相同的效果吗?这很有趣。它可行吗?有任何例子吗?完全错误a)不遵守合同:编辑终止时必须通知听众b)在每次通话时创建一个新的复选框(和按钮组)-这应该如何解决问题?c)不配置复选框(第无数次)-答案代码应与问题代码相同:-)滚动效果不错,但与问题无关。