【问题标题】:Make JWindow retain focus when children are focused, including another window as child使 JWindow 在子级获得焦点时保持焦点,包括另一个窗口作为子级
【发布时间】:2013-08-16 20:32:42
【问题描述】:

我创建了JWindow,它有几个JTextInput 字段。这个JWindow 父母是JFrame。现在的情况 - 如果单击文本字段 - 他们获得焦点但 JWindow 也保持焦点。那很好。但是,如果我创建另一个JWindow(第一个JWindow 的孩子),并将其设置为可见,那么关注第一个JWindow 会丢失,而孩子JWindow 会被聚焦。这是不好的。有什么方法可以保持对父JWindow 的关注,并使子JWindowJTextInput 字段一样获得关注?

【问题讨论】:

    标签: java swing focus jwindow


    【解决方案1】:

    没有父级的 JWindow 永远不会是可聚焦的,小心的话 JTextComponents 永远不会是可编辑的

    例如

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.event.DocumentEvent;
    import javax.swing.event.DocumentListener;
    
    public class WindowTest {
    
        private JFrame frame;
        private boolean bol = true;
    
        public WindowTest() {
            frame = new JFrame("Window Test");
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.setSize(300, 300);
            frame.setVisible(true);
            JWindow win = new JWindow(frame);
            win.setLayout(new GridLayout(0, 1));
            JTextField text = new JTextField("Show Window");
            text.getDocument().addDocumentListener(new DocumentListener() {
                @Override
                public void insertUpdate(DocumentEvent e) {
                    if (!bol) {
                        JWindow win = new JWindow();
                        win.setLayout(new GridLayout(0, 1));
                        win.add(new JTextField("JTextField"));
                        win.add(new JTextField("JTextField"));
                        win.add(new JLabel("<html> Concurency Issues in Swing<br>"
                                + " never to use Thread.sleep(int) <br>"
                                + " durring EDT, simple to freeze GUI </html>"));
                        win.pack();
                        win.setLocation(350, 150);
                        win.setVisible(true);
                        bol = true;
                    }
                }
    
                @Override
                public void removeUpdate(DocumentEvent e) {
                }
    
                @Override
                public void changedUpdate(DocumentEvent e) {
                }
            });
            win.add(text);
            win.add(new JTextField("JTextField"));
            win.add(new JTextField("JTextField"));
            win.pack();
            win.setLocation(250, 150);
            win.setVisible(true);
    
            bol = false;
        }
    
        public static void main(String args[]) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new WindowTest();
                }
            });
        }
    }
    

    【讨论】:

    • 很好的例子,以前不知道。实际上,如果子 JWindow 获得焦点,我已经通过限制更改父 JWindow 的自定义标题栏的颜色(变为非活动状态)来解决问题。再次感谢 :)
    • 在阅读完这些行之后,我还不得不使用WindowFocusListenerFocusListener“在此版本中,显示 JPopupMenu 会导致焦点转移到父 JRootPane。这样做是为了JPopupMenus 将支持键盘遍历...”来自here。我之前认为 JWindow 有一些设置可以在获得焦点时表现得像 JTextField (父 JWindow 保留窗口焦点)。
    • 因为从 Java1.4 开始,没有 Focus 就无法保持可见,松散的 Fosus 隐藏 JPopup 或 BasicComboBoxPopup
    【解决方案2】:

    在设置子窗口可见之前,添加WindowListener。在子窗口上调用setVisible 后,您将收到windowActivated 回调。那时在您的父窗口上调用toFront 将其向前推进。鉴于操作系统 z 顺序处理的怪异,您可能需要/想要首先在子窗口上调用 toBack,然后在父窗口或其可聚焦的子窗口之一上调用 requestFocus

    【讨论】:

      猜你喜欢
      • 2011-09-28
      • 2023-04-02
      • 1970-01-01
      • 2011-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-04
      • 1970-01-01
      相关资源
      最近更新 更多