我有两个显示器连接,因此我可以在主显示器或次显示器上启动我的Java应用程序。
问题是:如何知道哪个显示器包含我的应用程序窗口,即是否有一种方法可以使用Java检测当前显示器?
我有两个显示器连接,因此我可以在主显示器或次显示器上启动我的Java应用程序。
问题是:如何知道哪个显示器包含我的应用程序窗口,即是否有一种方法可以使用Java检测当前显示器?
java.awt.Window 是所有顶层窗口(Frame、JFrame、Dialog等)的基类,其中包含 getGraphicsConfiguration()
方法,该方法返回窗口正在使用的GraphicsConfiguration。GraphicsConfiguration 有一个 getGraphicsDevice()
方法,它返回 GraphicsConfiguration 所属于的GraphicsDevice。您可以使用 GraphicsEnvironment 类来将其与系统中的所有 GraphicsDevices 进行比较,从而确定窗口属于哪个设备。
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);
Nate的解决方案在大多数情况下似乎是有效的,但并非所有情况都如此,我也遇到了一些问题。perplexed提到连接显示器时出现问题,我则在使用“Win+Left”和“Win+Right”键命令时遇到了问题。我的解决方案如下(也许这个解决方案本身存在问题,但至少对我来说比Nate的解决方案更好):
GraphicsDevice myDevice = myFrame.getGraphicsConfiguration().getDevice();
for(GraphicsDevice gd:GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()){
if(frame.getLocation().getX() >= gd.getDefaultConfiguration().getBounds().getMinX() &&
frame.getLocation().getX() < gd.getDefaultConfiguration().getBounds().getMaxX() &&
frame.getLocation().getY() >= gd.getDefaultConfiguration().getBounds().getMinY() &&
frame.getLocation().getY() < gd.getDefaultConfiguration().getBounds().getMaxY())
myDevice=gd;
}
你可以使用Window、Frame和Graphics Configuration类来实现这一点。
在此处查看更多信息:
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);
}
java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration()
按顺序排列的GraphicsConfiguration-s列表如下:
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;
}
默认显示为列表中的第一个。