Java TextField对其他窗口失去焦点

Java TextField对其他窗口失去焦点,java,swing,Java,Swing,在java swing应用程序中,我有一个带有某种帮助弹出窗口的文本字段。 即,当用户在文本字段内用鼠标双击时,将显示此弹出窗口(实现为未修饰的JFrame) 一旦文本字段失去焦点,此弹出窗口将再次隐藏。 问题是显示此弹出窗口时,焦点会自动移动到该帧,并在textfield上触发lostFocus事件。当然,这会再次关闭弹出窗口 我希望仅当textfield在同一窗口中的另一个组件上失去焦点时,才会触发lostFocus事件 你知道如何做到这一点吗 检查哪个对象接收到焦点,并根据它隐藏窗口 这是

在java swing应用程序中,我有一个带有某种帮助弹出窗口的文本字段。
即,当用户在文本字段内用鼠标双击时,将显示此弹出窗口(实现为未修饰的JFrame)

一旦文本字段失去焦点,此弹出窗口将再次隐藏。
问题是显示此弹出窗口时,焦点会自动移动到该帧,并在textfield上触发lostFocus事件。当然,这会再次关闭弹出窗口

我希望仅当textfield在同一窗口中的另一个组件上失去焦点时,才会触发lostFocus事件

你知道如何做到这一点吗


检查哪个对象接收到焦点,并根据它隐藏窗口

这是一个粗略的例子

public class MainFrame extends JFrame {

    private JWindow popupWindow;

    public MainFrame() throws HeadlessException {
        super("Main Frame");
        createGUI();
    }

    private void createGUI() {
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setPreferredSize(new Dimension(600, 400));

        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));

        JTextField hintTextField = new JTextField();

        popupWindow = new JWindow(this);
        popupWindow.getRootPane().setBorder(BorderFactory.createLineBorder(Color.RED));
        popupWindow.getRootPane().setLayout(new BorderLayout());
        popupWindow.getRootPane().add(hintTextField, BorderLayout.CENTER);

        for(int i = 0; i < 10; i++) {
            JTextField textField = new JTextField();
            textField.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if(e.getClickCount() == 2) {
                        Point point = textField.getLocationOnScreen();
                        popupWindow.setBounds(point.x, point.y + textField.getPreferredSize().height, 200, 200);
                        popupWindow.setVisible(true);
                    }
                }
            });

            textField.addFocusListener(new FocusAdapter() {
                @Override
                public void focusLost(FocusEvent e) {
                    if(e.getOppositeComponent() != hintTextField) {
                        popupWindow.setVisible(false);
                    }
                }
            });

            panel.add(textField);
        }

        add(panel, BorderLayout.PAGE_START);

        pack();
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new MainFrame().setVisible(true));
    }
}
公共类大型机扩展JFrame{
私人窗口弹出窗口;
公共大型机()抛出HeadlessException{
超级(“主机架”);
createGUI();
}
私有void createGUI(){
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setPreferredSize(新尺寸(600400));
JPanel面板=新的JPanel();
panel.setLayout(新的BoxLayout(panel,BoxLayout.PAGE_轴));
JTextField hintTextField=新的JTextField();
popupWindow=新的JWindow(此窗口);
popupWindow.getRootPane().setBorder(BorderFactory.createLineBorder(Color.RED));
popupWindow.getRootPane().setLayout(新的BorderLayout());
添加(hintTextField,BorderLayout.CENTER);
对于(int i=0;i<10;i++){
JTextField textField=新的JTextField();
addMouseListener(新的MouseAdapter(){
@凌驾
公共无效mouseClicked(MouseEvent e){
如果(如getClickCount()==2){
Point=textField.getLocationOnScreen();
popupWindow.setBounds(点.x,点.y+textField.getPreferredSize().height,200200);
popupWindow.setVisible(真);
}
}
});
addFocusListener(新的FocusAdapter(){
@凌驾
公共无效焦点丢失(焦点事件e){
如果(如getOppositeComponent()!=hintTextField){
popupWindow.setVisible(假);
}
}
});
panel.add(textField);
}
添加(面板、边框布局、页面开始);
包装();
setLocationRelativeTo(空);
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(()->new MainFrame().setVisible(true));
}
}

解决方案比我想象的要简单:
focusLost
回调中,检查
istemporation()
标志。
如果已设置,则忽略该事件

更新:
如果设置了
ifTemporary()
标志,则确定获得焦点的组件(通过
getOppositeComponent()
)。

如果该组件(如果
null
)或其父窗口不是我们的弹出框,则无论如何都要关闭弹出框。

检查哪个对象接收到焦点并根据它隐藏窗口。感谢您的提示,但我认为我找到了一个更简单的解决方案(请参阅我的答案)。
(作为未修饰的JFrame实现)
-使用未修饰的JDialog而不是框架。一个应用程序应该只包含一个JFrame。