10

我在使用以下代码时遇到问题,我在其中使用 JComboBox 更改表格单元格中的字符串值。JComboBox 工作正常,但是如果我单击该框,然后单击离开而不选择任何内容,即使我删除了该行,JComboBox 的下拉列表仍然可见。单击另一个 Swing 组件(如 JButton)通常会导致它消失,但并非总是如此。


    TableColumn col = myTable.getColumnModel().getColumn(0);
    JComboBox eq = new JComboBox();
    eq.addItem("==");
    eq.addItem("!=");
    DefaultCellEditor editor = new DefaultCellEditor(eq);
    col.setCellEditor(editor);

编辑:我没有提到我之前设置的:


    myTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

如果我将此行注释掉或将其设置为 false,那么单击其他 Swing 组件不会导致该框消失。有了它,单击任何引起焦点的东西都会导致框消失,从而使问题不那么烦人,但可能掩盖了行为的原因。

我在这里做错了什么,还是忘记了一步?或者,有没有办法强迫它自行关闭?

谢谢!

4

2 回答 2

14

要理解这一点,您需要了解可编辑表格发生了什么。一点理论:

每个单元格都有一个潜在的渲染器和编辑器。渲染器只是告诉单元格如何绘制而不与事件交互。然而,编辑器是一个可以与事件交互的组件。当触发编辑的事件发生时,编辑器组件将添加到表格顶部。编辑完成后,组件将被移除。

为了让组件消失,您必须确保单元格不仍处于“编辑”状态。这就是 terminateEditOnFocusLast 导致 JComboBox 消失的原因。如果你想让其他东西让盒子去,你可能需要调用 removeEditor() 来响应某些事件,可能是焦点,或者单元格选择。

要真正了解发生的情况,我建议快速查看 removeEditor()、editCellAt() 等的源代码,并可能在调试器中单步执行一次。您可能已经覆盖了一些事件处理代码,或者在不应该调用它时调用了它。JTable 中的编辑器/事件处理代码相当脆弱,很容易意外地调用以错误的顺序发生并产生有趣的副作用。

另外,Java 曾经非常巧妙地在版本之间改变了 JTable 的事件和焦点行为,我认为是在 1.4 和 1.5 之间,当时对 swing 的焦点处理发生了变化。因此,我建议您尝试的第一件事是使用不同 Java 版本的代码。该错误可能是由 Sun 引起的(我们必须更改一些复杂的编辑器代码),如果版本之间存在差异,则更容易向 Sun 报告。

于 2009-02-18T23:09:08.810 回答
3

我知道这个问题很老,但这里是我的解决方案供参考。我扩展 DefaultCellEditor 并监听要取消的 JComboBox 然后强制编辑器取消。

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class ComboBoxCellEditor extends DefaultCellEditor {

    public ComboBoxCellEditor(JComboBox comboBox) {
        super(comboBox);
        comboBox.addPopupMenuListener(new PopupMenuListener() {

            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
            }

            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
            }

            public void popupMenuCanceled(PopupMenuEvent e) {
                cancelCellEditing();
            }
        });
    }
}

然后 ...

DefaultCellEditor editor = new ComboBoxCellEditor(combobox);
column.setCellEditor(editor);
于 2016-02-05T18:36:21.247 回答