Skip to content

Instantly share code, notes, and snippets.

@akmsw
Last active May 14, 2024 00:45
Show Gist options
  • Save akmsw/9ebbd38bf8372f9134736ffa864984e0 to your computer and use it in GitHub Desktop.
Save akmsw/9ebbd38bf8372f9134736ffa864984e0 to your computer and use it in GitHub Desktop.
Retrieve the screen on which the majority of a view is displayed (for multi-screen setups)
import java.awt.Dimension;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.IllegalComponentStateException;
import java.awt.Rectangle;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Optional;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
/**
* Given a multi-monitor setup, this program detects the monitor
* where a JFrame is being currently displayed and stores it as a
* GraphicsDevice object.
*
* Compile:
* javac GetActiveMonitor.java
*
* Run:
* java GetActiveMonitor
*/
public class GetActiveMonitor {
/**
* The monitor where the frame is displayed.
*/
private GraphicsDevice activeMonitor;
private JFrame frame;
private JPanel masterPanel;
// ---------------------- Constructor ----------------------
/**
* Creates a frame and initializes the default active monitor.
*/
private GetActiveMonitor() {
initializeActiveMonitor();
initializeFrame();
}
// ------------------- Main entry point --------------------
public static void main(String[] args) {
final GetActiveMonitor example = new GetActiveMonitor();
}
// -------------------- Private methods --------------------
/**
* Establishes the main monitor as the active monitor by default.
*/
private void initializeActiveMonitor() {
activeMonitor = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice();
}
private void initializeFrame() {
this.masterPanel = new JPanel();
this.frame = new JFrame();
addButton();
frame.setPreferredSize(new Dimension(220, 75));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(masterPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void addButton() {
JButton whereAmI = new JButton("Where am I?");
whereAmI.addActionListener(e -> {
updateActiveMonitorFromView(frame);
Rectangle activeMonitorBounds = activeMonitor.getDefaultConfiguration()
.getBounds();
JDialog infoDialog = new JDialog(frame, "Which monitor is this?");
infoDialog.add(new JLabel(
"The frame is on the monitor #"
+ Integer.parseInt(activeMonitor.getIDstring()
.replaceAll("[^\\d]", "")))
);
infoDialog.setModal(true);
infoDialog.setResizable(false);
infoDialog.pack();
infoDialog.setLocation(
(activeMonitorBounds.width - infoDialog.getWidth()) / 2 + activeMonitorBounds.x,
(activeMonitorBounds.height - infoDialog.getHeight()) / 2 + activeMonitorBounds.y
);
infoDialog.setVisible(true);
});
masterPanel.add(whereAmI);
}
/**
* Determines the monitor on which the majority of the given view is displayed and sets it as the active monitor.
*
* @param view Reference frame from which the active monitor will be determined.
*/
private void updateActiveMonitorFromView(JFrame view) {
Optional<GraphicsDevice> optionalActiveMonitor = Arrays.stream(GraphicsEnvironment.getLocalGraphicsEnvironment()
.getScreenDevices())
.filter(screen -> !screen.getDefaultConfiguration()
.getBounds()
.intersection(view.getBounds())
.isEmpty())
.max(Comparator.comparingDouble(
screen -> {
Rectangle intersection = screen.getDefaultConfiguration()
.getBounds()
.intersection(view.getBounds());
return intersection.getWidth() * intersection.getHeight();
}));
optionalActiveMonitor.ifPresentOrElse(
screen -> activeMonitor = screen,
() -> { throw new IllegalComponentStateException("No active monitor found."); }
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment