Close

Java Swing - Using Java Prefs to remember last screen/monitor of the frame

[Updated: Jul 4, 2018, Created: Jul 4, 2018]

Following example shows how to remember screen of a JFrame, that is, when application is restarted, the frame is opened in the same screen/monitor where it was located the last time. For efficiency this example does not remember the exact position of the frame, but just the monitor index.

Example

package com.logicbig.example;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.prefs.Preferences;

public enum ScreenMonitor {
  Instance;
  private static final String MonitorIndex = "monitorIndex";
  private int currentMonitorIndex;
  private Map<Rectangle, Integer> boundToScreenIndexMap = new HashMap<>();
  private final Preferences prefs = Preferences.userRoot().node(this.getClass().getName());

  ScreenMonitor() {
      GraphicsDevice[] screenDevices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
      for (int i = 0; i < screenDevices.length; i++) {
          GraphicsDevice graphicsDevice = screenDevices[i];
          Rectangle bounds = graphicsDevice.getDefaultConfiguration().getBounds();
          boundToScreenIndexMap.put(bounds, i);
      }
  }

  public void registerFrame(JFrame frame) {
      currentMonitorIndex = prefs.getInt(MonitorIndex, -1);
      Point l = monitorIndexToLocation(currentMonitorIndex);
      frame.setLocation(l);
      frame.addComponentListener(new ComponentAdapter() {
          @Override
          public void componentMoved(ComponentEvent e) {
              int screenIndex = locationToMonitorIndex(e.getComponent().getLocation());
              if (screenIndex != currentMonitorIndex) {
                  prefs.putInt(MonitorIndex, screenIndex);
                  currentMonitorIndex = screenIndex;
                  System.out.println("changed: "+currentMonitorIndex);
              }
          }
      });
  }

  private int locationToMonitorIndex(Point location) {
      for (Map.Entry<Rectangle, Integer> e : boundToScreenIndexMap.entrySet()) {
          if (e.getKey().contains(location)) {
              return e.getValue();
          }
      }
      return currentMonitorIndex;
  }

  private Point monitorIndexToLocation(int currentMonitor) {
      for (Map.Entry<Rectangle, Integer> e : boundToScreenIndexMap.entrySet()) {
          if (e.getValue().equals(currentMonitor)) {
              return e.getKey().getLocation();
          }
      }
      return new Point(0, 0);
  }
}

Main class

public class ExampleMain {
  public static void main(String[] args) {
      JFrame frame = createFrame();
      ScreenMonitor.Instance.registerFrame(frame);
      frame.setVisible(true);
  }

  private static JFrame createFrame() {
      JFrame frame = new JFrame("Remembering Window's Monitor");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(new Dimension(500, 400));
      return frame;
  }
}

Output

After restarting the application the frame is opened in the same monitor.

Example Project

Dependencies and Technologies Used:

  • JDK 10
  • Maven 3.5.4

Remembering screen of the JFrame Select All Download
  • java-prefs-remember-window-position
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • ScreenMonitor.java

    See Also