【问题标题】:JTable boolean values not updating when using JOptionPane使用 JOptionPane 时 JTable 布尔值不更新
【发布时间】:2023-12-22 06:10:01
【问题描述】:

我正在尝试编写一些代码,允许用户通过单击 JTable 中的布尔单元格来填写文本字段。

我可以让程序将表格中的数据输入到文本字段中,但我目前的执行方法涉及一个 JOptionPane,它出于某种奇怪的原因阻止表格更改复选框值(即检查 -框不会从黑色变为勾选)。不仅如此,选择不会更新,因此最后一列中的值保持为 false,即使选择应将其切换为 true。

我认为这可能与 JOptionPane 以某种方式覆盖选择事件有关,但我对 JOptionPane 对象的了解还不够,无法说明如何操作。我的代码是:

table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
ListSelectionModel selectionModel = table.getSelectionModel();
selectionModel.addListSelectionListener(new ListSelectionListener() {

    public void valueChanged(ListSelectionEvent e) {
        ListSelectionModel lsm = (ListSelectionModel) e.getSource();
        if (lsm.isSelectionEmpty()) {
            //no rows are selected do nothing
        } else {
            //First find the row clicked
            int selectedRow = lsm.getLeadSelectionIndex();
            /*
                * put a popup here to ask the user which peak to associate
                * the energy with.
                */
            System.out.println(selectedRow);
            //Get user to associate with a peak
            availablePeaks = getAvailablePeaks();
            String returnVal = (String) JOptionPane.showInputDialog(
                null,
                "Select the peak:",
                "Peak Matching",
                JOptionPane.QUESTION_MESSAGE,
                null,
                availablePeaks, null);
            System.out.println(returnVal);
            //Determine the selection
            int index = 0;
            for (int i = 0; i < availablePeaks.length; i++) {
                if (availablePeaks[i] == returnVal) {
                    index = i;
                } else {
                }
            }
            //Set the peak value in the peak specifier to the energy in the row
            double energy = (Double) table.getValueAt(selectedRow, 0);
            System.out.println(energy);
            frame.getPeakSetter().getPeakSpecifiers()[index].setEnergy(energy);
            frame.getPeakSetter().getPeakSpecifiers()[index].getTextField().setText("" + energy);
        }
    }
});

有谁知道为什么ListSelectionListener 中的JOptionPane 会阻止表格更新复选框?

谢谢!

【问题讨论】:

    标签: java swing jtable joptionpane


    【解决方案1】:

    我假设您的模型为isCellEditable() 返回true,而getColumnClass()JCheckBox 列返回Boolean.class。这会启用默认的 rednerer/editor,列出 here

    看起来选择行的手势正在弹出对话框。目前尚不清楚这如何阻止DefaultCellEditor 得出结论;这个对我有用。由于您没有检查 getValueIsAdjusting(),我很惊讶您没有看到两个 ListSelectionEvent 实例。

    无论如何,每次选择更改时都弹出一个对话框似乎很麻烦。有几种可能的选择:

    • 保留ListSelectionListener,通过从isCellEditable() 返回false 使单元格不可编辑,并仅在对话框成功结束时在模型中设置其值。

    • 删除ListSelectionListener 以支持JButton 编辑器,显示为here

    • 删除ListSelectionListener 以支持自定义CellEditor,如下所述。

      table.setDefaultEditor(Boolean.class, new DefaultCellEditor(new JCheckBox()) {
      
          @Override
          public boolean stopCellEditing() {
              String value = JOptionPane.showInputDialog(...);
              ...
              return super.stopCellEditing();
          }
      });
      

    【讨论】:

    • 谢谢!我决定保留 ListSelectionListener 并使最后一列中的单元格不可编辑。如果用户单击单元格并进行选择,则表格现在会正确更新。 :)