更新Jtable中的复选框进入递归,导致堆栈溢出错误

时间:2016-02-22 19:58:37

标签: java swing jtable jcheckbox

我在选项卡式窗格中设置了一个Jtable,其中包含一个id和复选框。该表看起来与此类似,其中.是复选框。

         |       VAR1        |
ID | ALL | subVar1 | subVar2 |
------------------------------
id1|  .  |    .    |    .    |

现在,我还有一个TableListener附加到此表。我想要发生的是,每当用户按下ALL复选框时,需要选择该行中的所有复选框(即true)。这是表监听器代码。

@Override
public void tableChanged(TableModelEvent e) {
    if(e.getSource() == assignedTableModel) {
        for (int i = 0; i < aTable.getRowCount(); i++) {
            boolean isAllChecked = (Boolean) aTable.getValueAt(i, 1);
            if(isAllChecked) {
                assignedTableModel.setValueAt(Boolean.TRUE, i, j);
            }
            else {
            ...
            }
        }
    }
}

单击ALL复选框导致表更改,assignedTableModel.setValueAt(Boolean.TRUE, i, j);被调用,表再次更改,因此调用侦听器,再次调用此函数。

我的问题是,还有另一种更新复选框的方法吗?或者有没有办法设置一个基础来摆脱递归?

编辑动态添加行。我想知道是否将一个actionListener添加到ALL复选框,因为它被添加将是一个解决方案。我会回来看看结果如何。

EDIT2 我忘了提到整个表是动态生成的。这意味着我无法知道将存在多少列和行,我知道的唯一列是ID和ALL col。已经存在的大多数答案都涉及硬编码实现。

2 个答案:

答案 0 :(得分:3)

  

每当用户按下ALL复选框时,该行中的所有复选框都被选中

那么为什么要循环遍历代码中的所有行?将仅为您单击的行生成事件,您只需选择该行上的列的复选标记。摆脱循环代码。

  

表再次更改,因此调用侦听器,再次调用此函数。

您需要if条件来确定何时选中第一列中的复选框:

if (e.getType() == TableModelEvent.UPDATE)
{
    int row = e.getFirstRow();
    int column = e.getColumn();

    if (column == 0)
    {
        TableModel model = (TableModel)e.getSource();
        model.setValueAt(Boolean.true, row, 1);
                ...
    }
}

现在将忽略其他列上的状态更改。

答案 1 :(得分:0)

根据@ camickr的回复,下面的代码似乎正在诀窍。感谢。

    @Override
    public void tableChanged(TableModelEvent e) {
        if (e.getType() == TableModelEvent.UPDATE && e.getSource() == assignedTableModel)
        {
            int row = e.getFirstRow();
            int column = e.getColumn();

            if (column == 1)
            {
                DefaultTableModel model = (DefaultTableModel) e.getSource();
                for(int i=2 ; i<model.getColumnCount() ; i++) {
                    if((boolean) model.getValueAt(row, 1))
                        model.setValueAt(Boolean.TRUE, row, i);
                    else
                        model.setValueAt(Boolean.FALSE, row, i);
                }
            }
        }
}