Ответ Fortega работал, однако, некоторая часть не нужна (или больше не нужна в Java 8):
-
Rectangle
не нужно сохранять. - Код не учитывает конфигурацию двойного экрана.В частности,
GraphicsConfiguration
изменится, если окно изменения окна. - Насколько я тестировал, единственное требуемое переопределение -
setExtendedState
.
При учете конфигурации с двумя экранами, по крайней мере в Windows , приведенный ниже код не работает должным образом:
Rectangle maxBounds = new Rectangle(screenInsets.left + screenSize.x,
screenInsets.top + screenSize.y,
screenSize.x + screenSize.width - screenInsets.right - screenInsets.left,
screenSize.y + screenSize.height - screenInsets.bottom - screenInsets.top);
На следующих настройках двойного экрана:
- Левый экран 1920x1080(не основной), позиция: -1920, 0
- Правый экран 1920x1080 (основной), позиция: 0, 0
maxBounds
будет содержать отрицательный x (-1920)но setMaximizedBounds
каким-то образом ожидает координату в пространстве экрана (где (x,y)
начинается с (0,0)
), а не на виртуальном экране:
- Будет установлено значение
setMaximizedBounds(x=-1920,y=0,width=1920,height=1050)
- Windows увидит окно на левом экране (потому что у меня есть одна панель задач на экран, показывающая только окно на этом экране), однако окно не будет отображаться на экране, потому что оно находится за пределами.
- Если разрешение экрана, или хуже, его масштабный коэффициент (с ноутбуком, Windows10 применяет масштабный коэффициент, например: 25%, делая экран «не очень» (1920x1080), тогда приведенный выше код не адаптируется.Например, если в моей конфигурации 3 экрана, причем самый правый из них является основным, окно будет плохо отображаться на левом и среднем экранах.Не думаю, что я исправил это в приведенном ниже коде.
Следующий код работает в Windows с двойным экраном:
@Override
public synchronized void setExtendedState(final int state) {
if ((state & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH) {
final GraphicsConfiguration cfg = getGraphicsConfiguration();
final Insets screenInsets = getToolkit().getScreenInsets(cfg);
final Rectangle screenBounds = cfg.getBounds();
final int x = screenInsets.left + screenBounds.x * 0;
final int y = screenInsets.top + screenBounds.y * 0;
final int w = screenBounds.width - screenInsets.right - screenInsets.left;
final int h = screenBounds.height - screenInsets.bottom - screenInsets.top;
final Rectangle maximizedBounds = new Rectangle(x, y, w, h);
System.out.println("cfg (" + cfg + ") screen.{bounds: " + screenBounds + ", insets: " + screenInsets + ", maxBounds: " + maximizedBounds);
super.setMaximizedBounds(maximizedBounds);
}
super.setExtendedState(state);
}
На простом JFrame
:
- При максимизации на левом экране («screen = 0») будет напечатано
cfg (D3DGraphicsConfig[dev=D3DGraphicsDevice[screen=0],pixfmt=0]) screen.{bounds: java.awt.Rectangle[x=-1920,y=0,width=1920,height=1080], insets: java.awt.Insets[top=0,left=0,bottom=30,right=0], maxBounds: java.awt.Rectangle[x=0,y=0,width=1920,height=1050]
- При максимизации на правом экране («screen = 1») будет напечатано
cfg (D3DGraphicsConfig[dev=D3DGraphicsDevice[screen=1],pixfmt=0]) screen.{bounds: java.awt.Rectangle[x=0,y=0,width=1920,height=1080], insets: java.awt.Insets[top=0,left=0,bottom=30,right=0], maxBounds: java.awt.Rectangle[x=0,y=0,width=1920,height=1050]