焦点问题使用JComboBox作为JTable中的单元格编辑器

时间:2009-02-18 16:42:13

标签: java swing focus jtable jcombobox

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


    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组件不会导致该框消失。有了它,点击任何需要聚焦的东西会导致盒子消失,使问题不那么烦人,但可能会掩盖行为的原因。

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

谢谢!

2 个答案:

答案 0 :(得分:11)

要理解这一点,您需要了解可编辑表格的内容。一点理论:

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

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

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

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

答案 1 :(得分:2)

我知道这个问题已经过时了,但这里的参考是我的解决方案。我扩展了DefaultCellEditor并监听JComboBox被取消然后强制编辑器取消。

VLCMediaPlayer

然后......

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();
            }
        });
    }
}