Last active
May 14, 2024 00:45
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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