Java и полноэкранный режим на нескольких мониторах

Фрагмент моего Java-приложения:

 JFrame f = new JFrame();
 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
 GraphicsDevice gd = ge.getDefaultScreenDevice();
 gd.setFullScreenWindow(f);

Итак, что он делает, так это делает его полноэкранным. Теперь странно, что программа полноэкранная, но только на одном мониторе! Например. У меня есть система Windows Vista с двумя экранами, объединенными в один рабочий стол. Что сделать, чтобы он автоматически запускался в полноэкранном режиме на всех мониторах?


Хорошо, я попробовал это:

import java.awt.image.ColorModel;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;

class grdevs
{
    public static void main(String [] args)
    {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] gs = ge.getScreenDevices();
        for(GraphicsDevice curGs : gs)
        {
            GraphicsConfiguration[] gc = curGs.getConfigurations();
            for(GraphicsConfiguration curGc : gc)
            {
                Rectangle bounds = curGc.getBounds();
                ColorModel cm = curGc.getColorModel();

                System.out.println("" + bounds.getX() + "," + bounds.getY() + " " + bounds.getWidth() + "x" + bounds.getHeight() + " " + cm);
            }
        } 
    }
}

но это дает:

0.0,0.0 1024.0x768.0 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0
0.0,0.0 1024.0x768.0 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0
0.0,0.0 1024.0x768.0 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0
0.0,0.0 1024.0x768.0 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0
0.0,0.0 1024.0x768.0 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0
0.0,0.0 1024.0x768.0 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0
1024.0,0.0 1024.0x768.0 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0
1024.0,0.0 1024.0x768.0 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0
1024.0,0.0 1024.0x768.0 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0
1024.0,0.0 1024.0x768.0 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0
1024.0,0.0 1024.0x768.0 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0
1024.0,0.0 1024.0x768.0 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0

Например, я ожидаю, что устройство поддерживает разрешение 2048x768, поскольку они объединены в одно (я нажал «расширить рабочий стол»).


person Folkert van Heusden    schedule 20.12.2009    source источник


Ответы (4)


Вы можете попробовать:

int width = 0;
int height = 0;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();
for (GraphicsDevice curGs : gs)
{
  DisplayMode mode = curGs.getDisplayMode();
  width += mode.getWidth();
  height = mode.getHeight();
}

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

Редактировать: Затем установите размер вашего кадра: f.setSize(width, height);

person Ash    schedule 21.12.2009
comment
Я согласен. Нормальное поведение - максимизация/полноэкранный режим на одном мониторе. Если у вас есть расширенный рабочий стол, монитор может покрывать только частичные прямоугольники внутри большого прямоугольника рабочего стола. Даже они не могли покрыть всю площадь рабочего стола (например, два монитора по диагонали), поэтому приходится находить большой прямоугольник рабочего стола и задавать размер вручную. - person helios; 05.01.2010

Более общее решение для кода Эша состоит в объединении границ всех графических конфигураций.

Rectangle2D result = new Rectangle2D.Double();
GraphicsEnvironment localGE = GraphicsEnvironment.getLocalGraphicsEnvironment();
for (GraphicsDevice gd : localGE.getScreenDevices()) {
  for (GraphicsConfiguration graphicsConfiguration : gd.getConfigurations()) {
    result.union(result, graphicsConfiguration.getBounds(), result);
  }
}
f.setSize(result.getWidth(), result.getHeight());

Это будет работать как для вертикально выровненных мониторов, так и для горизонтальных.

person tiestvilee    schedule 14.11.2012

Это не то, для чего предназначен setFullScreenWindow. Это действительно для приложений, которым нужен более прямой доступ к фреймбуферу (более высокая производительность) - например, 3D-игра в DirectX. Этот вид подразумевает ОДИН монитор.

См. этот другой ответ, который я сделал: JDialog не отображается в полноэкранном режиме

person M1EK    schedule 22.12.2009

Это нормальное поведение, когда вы разворачиваете окно в Windows, когда у вас два монитора. Чтобы два получили полное разрешение, вам нужно посмотреть GraphicsConfiguration для проверки каждого GraphicsDevice.

person unholysampler    schedule 20.12.2009