Java setFullScreenWindow() сохранить сверху

Я пишу приложение, предназначенное для запуска с помощью двух мониторов, с помощью "Дисплей" JFrame, идущего в полноэкранном режиме на одном мониторе, и "Control" JFrame на другом мониторе, отправляя инструкции на дисплей. Я пробовал два отдельных метода установки полноэкранного режима дисплея; успех каждого, похоже, зависит от ОС.

display.setUndecorated(true);
display.setExtendedState(JFrame.MAXIMIZED_BOTH);

Работает в Windows, но JFrame скрывается под док-станциями/панелями в OS X и Linux.

Мой другой метод, используя

GraphicsDevice.setFullScreenWindow(display);

Работает во всех трех ОС, которые я пробовал, но в Windows, фокусируя окно "Управление" на другом мониторе, скрывает окно "Экран" и вызывает

display.setAlwaysOnTop(true);

Не исправляет проблему. Я частично отношусь к методу GraphicsDevice, потому что мне не нужно разбираться с проблемами в OS X или Linux, и я надеюсь, что проблема Windows - это простое исправление. Это?

Ответ 1

Попробуйте это...

Для нескольких экранов

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();


// Get size of each screen

for (int i=0; i<gs.length; i++) {
    DisplayMode dm = gs[i].getDisplayMode();
    int screenWidth = dm.getWidth();
    int screenHeight = dm.getHeight();
}

Используйте public final void setAlwaysOnTop(boolean alwaysOnTop) для установки окна сверху. Если окно видно, это включает в себя создание окна toFront, а затем "прикрепление" его к самому верхнему положению.

Ответ 2

Я сталкиваюсь с той же проблемой. Мой способ решить эту проблему состоял в том, чтобы переопределить функцию show() в jframe и с помощью стратегии буфера не возвращаться из функции show. Итак, что-то вроде этого:

 @override
 public void show(){
        super.show();
        //Create a double buffering strategy
        createBufferStrategy(2);
        BufferStrategy bs = getBufferStrategy();
        while(true){
              //draw our frame
              Graphics g = bs.getGraphics();
              paint(g);
              //dispose of our graphics
              g.dispose();
              //Show our frame
              bs.show();
              try{
                  //Don't use all our cpu-power
                  Thread.sleep(10);
              }catch(Exception e){
                  //Do something (this probably will never happen)
              }
        }
 }

На самом деле было бы лучше использовать setVisible(boolean) вместо show() (show устарел). Окно не всегда будет сверху (вы можете перетащить еще одно окно поверх него), но он не будет автоматически скрываться, когда вы отдаете фокус другому окну. Это поведение, которое вы хотите, я думаю.

Примечание. Не вызывайте show в eventqueue, так как это сделает бесполезным событие eventqueue и заставляет jframe игнорировать все события. Функция show должна вызываться в новом потоке, тогда все события будут обрабатываться.