Search code examples
javaswingjframeawtmultiple-monitors

How to use JFrame to open another JFrame window on the other monitor?


I am writing a program designed to work on a two monitor system. I have to separate JFrame objects, and have it so be default, the first frame instance opens. The user then has to drag that frame over to a specific monitor, or leave it in place. When they click a button on that frame, I want the program to open up the second frame on the opposite monitor.

So, How would I figure out which monitor a frame object is on, and then tell another frame object to open on the opposite one?


Solution

  • Looking up GraphicsEnvironment, you can easily find out the bounds and location of each screen. After that, it is just a matter of playing with the location of the frames.

    See small demo example code here:

    import java.awt.Frame;
    import java.awt.GraphicsDevice;
    import java.awt.GraphicsEnvironment;
    import java.awt.Point;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    
    public class TestMultipleScreens {
    
        private int count = 1;
    
        protected void initUI() {
            Point p = null;
            for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
                p = gd.getDefaultConfiguration().getBounds().getLocation();
                break;
            }
            createFrameAtLocation(p);
        }
    
        private void createFrameAtLocation(Point p) {
            final JFrame frame = new JFrame();
            frame.setTitle("Frame-" + count++);
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            final JButton button = new JButton("Click me to open new frame on another screen (if you have two screens!)");
            button.addActionListener(new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    GraphicsDevice device = button.getGraphicsConfiguration().getDevice();
                    Point p = null;
                    for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
                        if (!device.equals(gd)) {
                            p = gd.getDefaultConfiguration().getBounds().getLocation();
                            break;
                        }
                    }
                    createFrameAtLocation(p);
                }
            });
            frame.add(button);
            frame.setLocation(p);
            frame.pack(); // Sets the size of the unmaximized window
            frame.setExtendedState(Frame.MAXIMIZED_BOTH); // switch to maximized window
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new TestMultipleScreens().initUI();
                }
            });
        }
    
    }
    

    Yet, consider reading carefully The Use of Multiple JFrames, Good/Bad Practice? because they bring very interesting considerations.