Java swing requestFocusInWindow()

Java swing requestFocusInWindow(),java,swing,autocomplete,focus,jtextfield,Java,Swing,Autocomplete,Focus,Jtextfield,我知道在如何关注某个文本领域等方面有很多问题,但我面临的问题似乎有点不同。因此,我有一个JTextField,如果用户之前键入了当前文本中的内容,它就可以自动完成文本。我还有一组按钮,当按下时,可以将一些预定义的文本部分插入文本字段。问题是,每次文本字段中出现任何新文本时,自动完成都会触发并追加用户以前使用的文本。为了更加友好,我决定选择自动完成后附加的部分。所有代码都在ED线程中执行。考虑文本字段没有聚焦时的情况: 这两个代码示例都位于按钮的actionPerformed方法中 //不起作用

我知道在如何关注某个文本领域等方面有很多问题,但我面临的问题似乎有点不同。因此,我有一个
JTextField
,如果用户之前键入了当前文本中的内容,它就可以自动完成文本。我还有一组按钮,当按下时,可以将一些预定义的文本部分插入文本字段。问题是,每次文本字段中出现任何新文本时,自动完成都会触发并追加用户以前使用的文本。为了更加友好,我决定选择自动完成后附加的部分。所有代码都在ED线程中执行。考虑文本字段没有聚焦时的情况:

这两个代码示例都位于按钮的
actionPerformed
方法中


//不起作用
if(textField.requestFocusInWindow()){
textField.getDocument().insertString(…);
}

insertString()
被覆盖,并具有通过自动完成选择附加字符串的所有逻辑。所以,我只需要在插入字符串之前选择文本字段

我试过:


//行得通
textField.requestFocusInWindow();
SwingUtilities.invokeLater(()->{
textField.getDocument().insertString(…);
});

官方文件说:

对requestFocusInWindow方法的调用会启动焦点转移,但不会立即移动焦点

这样做是有道理的,因为要获得焦点,必须调用客户端操作系统的窗口管理器(这就是我的理解,如果我错了,请纠正我)

第二个示例之所以有效,主要是因为两个事件(获取焦点和插入字符串)都添加到事件队列中,并且插入出现在焦点请求之后(实际上在队列的末尾),还是因为我遗漏了什么?这是一个有效的解决方案吗?能做得更好吗


注意:简单地在文本字段中添加一个侦听器(当它处于焦点时作出反应)并不是一个解决方案,因为我在这里描述的逻辑只是使用的整个功能的一部分。

为什么需要文本字段再次请求焦点?因为可能是它最初不在焦点中,而且据我所知,
insertString
没有这样做。要回答一般性问题,
invokeLater
允许从调用
requestFocusInWindow
到调用
Runnable
之间的一段时间,这允许API的其余部分响应操作系统的通知,即它已获得焦点-这是一种竞争条件。。。并松散地使用这个术语。我问这个问题的原因是,为什么您需要字段具有焦点来更新它?我想知道是否将组件设置为不可聚焦“可能”提供了一个更稳定的解决方案,但您需要弄清楚如何允许键盘交互,这并不难