Я заметил, что если режим экрана изменяется за пределами Java, то java.awt.GraphicsEnvironment.getMaximumWindowBounds()
все еще возвращает размер до изменения размера экрана.
Но java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode()
работает и показывает новое разрешение.
Я отслеживал getMaximumBounds()
для вызова GraphicsDevice.getDefaultConfiguration()
который, как я подозреваю, использует устаревшую конфигурацию.
Мой вопрос: есть ли способ сказать Java, что изменилась конфигурация экрана или это просто ошибка?
Благодарю.
Вот простое приложение, которое показывает ошибку:
import java.awt.*;
public class test {
public static void print() {
try {
Rectangle r = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
System.out.println("max window bounds=" + r);
DisplayMode mode = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode();
System.out.println("mode=" + mode.getWidth() + "x" + mode.getHeight());
GraphicsConfiguration gc = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
System.out.println("insets=" + insets);
} catch (Exception e) {}
}
public static void main(String args[]) {
try {
print();
System.out.println("Change video mode and press Enter to continue...");
System.in.read();
print();
} catch (Exception e) {}
}
}
Вот обходной путь, который работает для меня:
public static Rectangle getMaximumBounds() {
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration());
DisplayMode mode = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode();
Rectangle bounds = new Rectangle();
bounds.x = insets.left;
bounds.y = insets.top;
bounds.width = mode.getWidth() - (insets.left + insets.right);
bounds.height = mode.getHeight() - (insets.top + insets.bottom);
return bounds;
}
Но я заметил, что другие функции awt не корректируются из-за изменения режима экрана. JPopupMenu.show() отключает меню. Pffff.... о хорошо...
Основываясь на ответе Питера Кьюринга, я добавил поддержку нескольких мониторов на основе того, где находится компонент. Надеюсь, это будет полезно для других, поскольку поддержка нескольких мониторов в java ужасна.
public static Rectangle getMaximumBounds(Component comp) {
GraphicsConfiguration gc = comp.getGraphicsConfiguration();
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
DisplayMode mode = gc.getDevice().getDisplayMode();
int xPos = 0;
int yPos = 0;
for(GraphicsDevice device : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
Rectangle deviceBounds = device.getDefaultConfiguration().getBounds();
if(deviceBounds.contains(gc.getBounds())) {
xPos = gc.getBounds().x;
yPos = gc.getBounds().y;
}
}
Rectangle bounds = new Rectangle();
bounds.x = insets.left + xPos;
bounds.y = insets.top + yPos;
bounds.width = mode.getWidth() - (insets.left + insets.right);
bounds.height = mode.getHeight() - (insets.top + insets.bottom);
return bounds;
}