Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.3k views
in Technique[技术] by (71.8m points)

java - give focus to a panel that is not a child of the focused Window?

I'm working in Java to create an internal tool. The two consists of two JPanels which are anticipated to run on two separate screens. I want to be able to click a JButton which is part of JFrame A which will send a keyboard action to JFrame B.

Unfortunately I can't seem to do this because JFrame B doesn't have the focus and I can't use any of the request Focus methods because JFrame B is not a child of the Focus Window (JFrame A is).

So how can I either give JFrame B focus despite it not being a child of the Focus Window or send Keyboard Events to JFrame B that it will respond to without having focus?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

is so hard to manage Focus between two JFrames, better would be create only one JFrame and other Top-level Containers would be JDialogs, create one/two JDialog(s) and reuse that by removing all JComponents

basicaly it would be :

EventQueue.invokeLater(new Runnable() {

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

but between two JFrames is things little bit complicated, just basic and uncompleted example (based on code from 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();
    }
}

EDIT: for How to adds Focus to the JDialog is there excelent Woodoo by camickr Dialog Focus but AncestorListener isn't my cup of Java and too much abstract for me


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...