I have 2 displays connected, so I can either launch my Java application on the primary or the secondary display.
The question is: How can I know which display contains my app window, i.e., is there a way to detect the current display with Java?
I have 2 displays connected, so I can either launch my Java application on the primary or the secondary display.
The question is: How can I know which display contains my app window, i.e., is there a way to detect the current display with Java?
java.awt.Window is the base class of all top level windows (Frame, JFrame, Dialog, etc.) and it contains the getGraphicsConfiguration() method that returns the GraphicsConfiguration that window is using. GraphicsConfiguration has the getGraphicsDevice() method which returns the GraphicsDevice that the GraphicsConfiguration belongs to. You can then use the GraphicsEnvironment class to test this against all GraphicsDevices in the system, and see which one the Window belongs to.
Window myWindow = ....
// ...
GraphicsConfiguration config = myWindow.getGraphicsConfiguration();
GraphicsDevice myScreen = config.getDevice();
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
// AFAIK - there are no guarantees that screen devices are in order...
// but they have been on every system I've used.
GraphicsDevice[] allScreens = env.getScreenDevices();
int myScreenIndex = -1;
for (int i = 0; i < allScreens.length; i++) {
if (allScreens[i].equals(myScreen))
{
myScreenIndex = i;
break;
}
}
System.out.println("window is on screen" + myScreenIndex);
Yes, you can do this with the Window, Frame and Graphics Configuration classes.
See more here:
This works for me
public static GraphicsDevice getWindowDevice(Window window) {
Rectangle bounds = window.getBounds();
return asList(GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()).stream()
// pick devices where window located
.filter(d -> d.getDefaultConfiguration().getBounds().intersects(bounds))
// sort by biggest intersection square
.sorted((f, s) -> Long.compare(//
square(f.getDefaultConfiguration().getBounds().intersection(bounds)),
square(s.getDefaultConfiguration().getBounds().intersection(bounds))))
// use one with the biggest part of the window
.reduce((f, s) -> s) //
// fallback to default device
.orElse(window.getGraphicsConfiguration().getDevice());
}
public static long square(Rectangle rec) {
return Math.abs(rec.width * rec.height);
}
Slightly different use case: If you want to know the primary display before you create a window somewhere and "display" technically means a java.awt.GraphicsDevice, the corresponding java.awt.GraphicsConfiguration should be
java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration()
A sorted list of GraphicsConfiguration-s is given by
public static GraphicsConfiguration[] getConfigurations()
{
final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
final GraphicsDevice def = ge.getDefaultScreenDevice();
final List<GraphicsConfiguration> cfgs = new ArrayList<GraphicsConfiguration>();
cfgs.add(def.getDefaultConfiguration());
for (final GraphicsDevice gd : ge.getScreenDevices())
{
if (gd!=def)
{
cfgs.add(gd.getDefaultConfiguration());
}
}
final GraphicsConfiguration[] res = cfgs.toArray(new GraphicsConfiguration[cfgs.size()]);
return res;
}
where the default display is the first in the list.