Как определить текущий дисплей с помощью Java?

У меня есть 2 подключенных дисплея, поэтому я могу запустить приложение Java на основном или вторичном дисплее.

Вопрос:. Как я могу узнать, какой дисплей содержит окно моего приложения, т.е. есть способ обнаружить текущий дисплей с Java?

Ответ 1

java.awt.Window является базовым классом всех окон верхнего уровня (Frame, JFrame, Dialog и т.д.) и содержит getGraphicsConfiguration(), который возвращает GraphicsConfiguration, которое использует это окно. GraphicsConfiguration имеет метод getGraphicsDevice(), который возвращает GraphicsDevice, к которому принадлежит GraphicsConfiguration. Затем вы можете использовать класс GraphicsEnvironment, чтобы проверить это на всех графических устройствах в системе и посмотреть, к какому из них принадлежит Окно.

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);

Ответ 2

Метод, предложенный Nate, не работает, когда другой монитор только что добавлен в систему, и пользователь переустанавливает окно Java на этот монитор. Это ситуация, с которой часто сталкиваются мои пользователи, и единственный способ обойти ее для меня - перезапустить java.exe, чтобы заставить ее повторно просматривать мониторы.

Основная проблема - myWindow.getGraphicsConfiguration(). getDevice() всегда возвращает устройство оригинал, где был запущен Java-апплет или приложение. Вы ожидаете, что он покажет текущий монитор, но мой собственный опыт (очень трудоемкий и расстраивающий) заключается в том, что просто полагаться на myWindow.getGraphicsConfiguration(). GetDevice() не является надежным. Если у кого-то есть другой подход, более надежный, пожалуйста, дайте мне знать.

Выполнение соответствия для экранов (с помощью вызова allScreen [i].equals(myScreen)), затем продолжает возвращать исходный монитор, на котором был вызван апплет, а не новый монитор, где он мог бы переместиться.

Ответ 4

Решение Nate, похоже, работает в большинстве, но не во всех случаях, как мне пришлось испытать. в недоумении упоминает, что у него были проблемы при подключении мониторов, у меня были проблемы с клавишами "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;
}

Ответ 5

Это работает для меня

    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);
}