有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java是否将焦点赋予不是焦点窗口子级的面板?

我正在用Java创建一个内部工具。两者由两个JPanels组成,预计将在两个单独的屏幕上运行。我希望能够单击JButton,它是JFrame A的一部分,它将向JFrame B发送键盘操作

不幸的是,我似乎不能这样做,因为JFrame B没有焦点,并且我不能使用任何请求Focus方法,因为JFrame B不是Focus WindowJFrame A是)的子对象

所以,我怎样才能给予JFrame B焦点,尽管它不是Focus Window的子对象,或者将Keyboard Event发送给它将在没有焦点的情况下响应的JFrame B


共 (3) 个答案

  1. # 1 楼答案

    在两个JFrames之间管理焦点是如此困难,最好只创建一个JFrame,其他Top-level Containers将是JDialogs,创建一个/两个JDialog(s),并通过删除所有JComponents来重用

    基本上是:

    EventQueue.invokeLater(new Runnable() {
    
       @Override
         public void run() {
             someComponent.grabFocus();
             someComponent.requestFocus();//or inWindow depends if Swing or Awt
         }
    });
    

    但在两个JFrames之间有点复杂,只是一个基本且未完成的示例(基于old.good.sun.forums.com的代码)

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class PMDialog extends JDialog {
    
        private static final long serialVersionUID = 1L;
        private boolean modal = false;
        private WindowAdapter parentWindowListener;
        private Window owner;
        private JFrame blockedFrame = new JFrame("Blocked Frame");
        private JFrame noBlockedFrame = new JFrame("No Blocked Frame");
    
        public PMDialog() {
            noBlockedFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            noBlockedFrame.getContentPane().add(new JButton(new AbstractAction("Test button") {
    
                private static final long serialVersionUID = 1L;
    
                @Override
                public void actionPerformed(ActionEvent evt) {
                    System.out.println("Non blocked button pushed");
                    /*if (blockedFrame.isVisible()) {
                    noBlockedFrame.setVisible(false);
                    } else {
                    blockedFrame.setVisible(true);
                    }*/
                    noBlockedFrame.setVisible(true);
                    blockedFrame.setVisible(true);
                }
            }));
            noBlockedFrame.setSize(200, 200);
            noBlockedFrame.setVisible(true);
            blockedFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
            blockedFrame.getContentPane().add(new JButton(new AbstractAction("Test Button") {
    
                private static final long serialVersionUID = 1L;
    
                @Override
                public void actionPerformed(ActionEvent evt) {
                    final PMDialog pmd = new PMDialog(blockedFrame, "Partial Modal Dialog", true);
                    pmd.setSize(200, 100);
                    pmd.setLocationRelativeTo(blockedFrame);
                    pmd.getContentPane().add(new JButton(new AbstractAction("Test button") {
    
                        private static final long serialVersionUID = 1L;
    
                        @Override
                        public void actionPerformed(ActionEvent evt) {
                            System.out.println("Blocked button pushed");
                            pmd.setVisible(false);
                            blockedFrame.setVisible(false);
                            noBlockedFrame.setVisible(true);
                        }
                    }));
                    pmd.setDefaultCloseOperation(PMDialog.DISPOSE_ON_CLOSE);
                    pmd.setVisible(true);
                    System.out.println("Returned from Dialog");
                }
            }));
            blockedFrame.setSize(200, 200);
            blockedFrame.setLocation(300, 0);
            blockedFrame.setVisible(false);
        }
    
        public PMDialog(JDialog parent, String title, boolean isModal) {
            super(parent, title, false);
            initDialog(parent, title, isModal);
        }
    
        public PMDialog(JFrame parent, String title, boolean isModal) {
            super(parent, title, false);
            initDialog(parent, title, isModal);
        }
    
        private void initDialog(Window parent, String title, boolean isModal) {
            owner = parent;
            modal = isModal;
            parentWindowListener = new WindowAdapter() {
    
                @Override
                public void windowActivated(WindowEvent e) {
                    if (isVisible()) {
                        System.out.println("Dialog.getFocusBack()");
                        getFocusBack();
                    }
                }
            };
        }
    
        private void getFocusBack() {
            Toolkit.getDefaultToolkit().beep();
            super.setVisible(false);
            super.pack();
            super.setLocationRelativeTo(owner);
            super.setVisible(true);
            super.toFront();
        }
    
        @Override
        public void dispose() {
            owner.setEnabled(true);
            owner.setFocusableWindowState(true);
            super.dispose();
        }
    
        @Override
        @SuppressWarnings("deprecation")
        public void hide() {
            owner.setEnabled(true);
            owner.setFocusableWindowState(true);
            super.hide();
        }
    
        @Override
        public void setVisible(boolean visible) {
            boolean blockParent = (visible && modal);
            owner.setEnabled(!blockParent);
            owner.setFocusableWindowState(!blockParent);
            super.setVisible(visible);
            if (blockParent) {
                System.out.println("Adding listener to parent ...");
                owner.addWindowListener(parentWindowListener);
                try {
                    if (SwingUtilities.isEventDispatchThread()) {
                        System.out.println("EventDispatchThread");
                        EventQueue theQueue = getToolkit().getSystemEventQueue();
                        while (isVisible()) {
                            AWTEvent event = theQueue.getNextEvent();
                            Object src = event.getSource();
                            if (event instanceof ActiveEvent) {
                                ((ActiveEvent) event).dispatch();
                            } else if (src instanceof Component) {
                                ((Component) src).dispatchEvent(event);
                            }
                        }
                    } else {
                        System.out.println("OUTSIDE EventDispatchThread");
                        synchronized (getTreeLock()) {
                            while (isVisible()) {
                                try {
                                    getTreeLock().wait();
                                } catch (InterruptedException e) {
                                    break;
                                }
                            }
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                    System.out.println("Error from EDT ... : " + ex);
                }
            } else {
                System.out.println("Removing listener from parent ...");
                owner.removeWindowListener(parentWindowListener);
                owner.setEnabled(true);
                owner.setFocusableWindowState(true);
            }
        }
    
        @Override
        public void setModal(boolean modal) {
            this.modal = modal;
        }
    
        public static void main(String args[]) {
            PMDialog pMDialog = new PMDialog();
        }
    }
    

    编辑:关于如何将焦点添加到JDialog是否有camickr的优秀Woodoo Dialog Focus但是AncestorListener不是我喜欢的Java,对我来说太抽象了

  2. # 2 楼答案

    没有人说你不能让一个Action向另一个发送消息。在这个exampleEnter也需要Clear,因此它转发ActionEvent。还要注意,每个NumberButton将两个击键绑定到Click。在您的情况下,您可能必须删除现有绑定,并可能在另一个窗口上调用^{}。注意支持@mKorbel答案的注意事项

  3. # 3 楼答案

    这是一个Swing GUI(您没有提到或向GUI库添加标记)?如果是这样,请考虑使用^ a1},它与焦点侦听器相比可以更加灵活。p>