Java Swing:插入符号侦听器在显示JPopupMenu后停止激发

Java Swing:插入符号侦听器在显示JPopupMenu后停止激发,java,swing,editor,caret,Java,Swing,Editor,Caret,我正在制作一个文本编辑器应用程序,我遇到了一个问题,在显示JPopupMenu后键入或粘贴文本时,我的CaretListener没有被触发 我已将CaretListener添加到JTextArea中 textArea.addCaretListener(new CaretListener() { public void caretUpdate(CaretEvent e) { runThisMethod(); } }); 这可以正常工

我正在制作一个文本编辑器应用程序,我遇到了一个问题,在显示JPopupMenu后键入或粘贴文本时,我的CaretListener没有被触发

我已将CaretListener添加到JTextArea中

textArea.addCaretListener(new CaretListener() {
        public void caretUpdate(CaretEvent e) {
            runThisMethod();
        }
    });
这可以正常工作,并在插入符号移动时调用“runThisMethod()”(按键、文本选择等)。在我的应用程序中,我有一个JMenuBar,还有一个使用
textArea.setComponentPopupMenu(popupMenu)添加的JPopupMenu

我的问题是,每当弹出窗口关闭时(通过选择菜单项,或通过单击JTextArea以外的任意位置取消它),CaretListener就会停止触发任何键输入(包括粘贴)。单击JTextArea中的任意位置将使其再次工作,并再次调用它进行键输入。使用JMenuBar不会触发此问题

下面是一个代码示例,演示了该问题(抱歉,篇幅太长):

要复制:按常规键入或粘贴,请注意底部的位置更新。右击弹出菜单,然后选择粘贴或全选。请重试键入,该位置不会更新(CaretListener未运行)

注意:这个并不是一个焦点问题(尽管我很可能是错的),比如
mainFrame.getFocusOwner().toString()
seam在调用时显示JTextArea,以及
popupMenu.setFocusable(false)没有帮助

我已经在这个问题上纠缠了一段时间,所以如果你能帮助解释我做错了什么,以及我如何让CaretListener被解雇,我将非常感激!)

谢谢,祝那些庆祝万圣节的人万圣节快乐

更新:JTextFields也会发生这种情况(这并不奇怪,但我认为无论如何都会对其进行测试),删除JScrollPane不会产生任何效果。在JTextArea的插入符号上调用setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE)同样没有什么区别


更新2:我想我找到了一个解决方案(见我的答案)。。。虽然我仍然不知道为什么会发生这个问题

好吧,我想我找到了解决办法。。。我会把它贴在这里,以防其他人遇到这种情况。 我最后做的是直接在JTextArea的插入符号上设置ChangeListener:

textArea.getCaret().addChangeListener(new ChangeListener(){     //Seams to work!

            @Override
            public void stateChanged(ChangeEvent e) {

                SwingUtilities.invokeLater(new Runnable(){

                    @Override
                    public void run() {

                        //Do stuff

                    }
                });
            }
        });
出于某种原因,即使JTextArea上的CaretListener没有被触发,也可能会被触发。我不知道为什么会发生这种情况,所以我可能会发布另一个关于这一点的问题


希望这对可能有同样问题的人有所帮助。

对JTextComponent使用更好的监听器,例如DocumentListener…,而不是KeyListener似乎是因为@camickrcode in event from focus的答案应该被包装到invokeLater中(focus与JTextComponent一起)好的问题以及@mKorbel的提示,我将编辑我的问题以围绕焦点事件包装invokeLater,我将阅读更多关于DocumentListeners的内容!
textArea.getCaret().addChangeListener(new ChangeListener(){     //Seams to work!

            @Override
            public void stateChanged(ChangeEvent e) {

                SwingUtilities.invokeLater(new Runnable(){

                    @Override
                    public void run() {

                        //Do stuff

                    }
                });
            }
        });