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

发布于 2024-07-13 10:17:14 字数 728 浏览 14 评论 0原文

我在使用以下代码时遇到问题,其中我使用 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 组件不会导致该框消失。 有了它,单击任何获得焦点的内容都会导致该框消失,从而使问题不再那么烦人,但可能掩盖了行为的原因。

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

谢谢!

I'm having issues with the following code, where I use a JComboBox to change a String value in a table cell. The JComboBox works fine, but if I click in the box and then click away without selecting anything the JComboBox's dropdown remains visible, even if I delete the row. Clicking on another Swing component like a JButton often causes it to go away, but not always.


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

Edit:
I had neglected to mention that earlier I set:


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

If I comment this line out or set it false, then clicking on other Swing components does NOT cause the box to vanish. With it in, clicking on anything that takes focus causes the box to go away, making the problem less annoying but possibly masking the cause of the behavior.

Am I doing something wrong here, or forgetting a step? Alternately, is there a way to force it to close itself?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

后来的我们 2024-07-20 10:17:14

要理解这一点,您需要了解可编辑表的情况。 一点理论:

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

为了让组件消失,您必须确保单元格不仍处于“编辑”状态。 这就是 TerminateEditOnFocusLast 导致 JComboBox 消失的原因。 如果您希望执行其他操作来使该框移动,您可能需要调用removeEditor() 来响应某些事件,可能是焦点或单元格选择。

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

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

To understand this you'll need to understand what goes on with an editable table. A short bit of theory:

Every cell has a potential renderer and editor. The renderer just tells the cell how to draw and does not interact with events. The editor however is a component that can interact with events. When an event happens that triggers an edit, the editor component is added on top of the table. When the edit finishes, the component is removed.

In order to get the component to go away, you'll have to make sure the cell is not still in the "editing" state. This is why terminateEditOnFocusLast causes the JComboBox to vanish. If you want other things to get the box to go, you'll need to probably call removeEditor() in response to certain events, possibly focus, or cell selection.

To really get a handle on what happens I'd recommend having a quick look at the source code to removeEditor(), editCellAt() etc., and maybe step through once in a debugger. It's possible you've overridden some of the event handling code, or are calling it when you shouldn't. The editor/event handling code in JTable is fairly fragile, and it's quite easy by accident to get calls to happen in the wrong order with funny side effects.

Also, Java very subtly changed the event and focus behaviour of JTable between versions once, I think it was between 1.4 and 1.5, when the focus handling for swing changed. So the first thing I'd recommend trying is your code with a different Java version. The bug may have been caused by Sun (some of our complicated editor code had to be changed) and if it differs between releases it is easier to report to Sun.

因为看清所以看轻 2024-07-20 10:17:14

我知道这个问题很旧,但这里是我的解决方案供参考。 我扩展了 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);

I know this question is old but for reference here is my solution. I extend the DefaultCellEditor and listen for the JComboBox to be canceled then force the editor to cancel.

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

Then ...

DefaultCellEditor editor = new ComboBoxCellEditor(combobox);
column.setCellEditor(editor);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文