Работает ли JFrame.setExtendedState (MAXIMIZED_BOTH) с неокрашенными кадрами? - PullRequest
9 голосов
/ 13 сентября 2011

Следующий код Swing не работает должным образом на моей машине или на машинах моих коллег (все Windows XP и Java 6):

public class Test {
    public static void main(String[] args) {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.setLayout(new FlowLayout());
        frame.add(new JButton(new AbstractAction("Maximize") {
            @Override
            public void actionPerformed(ActionEvent e) {
                frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH);
            }
        }));
        frame.setUndecorated(true);
        frame.setVisible(true);
    }
}

Это максимизирует окно, но не учитывает панель задач Windows (она заполняет экран). Если вы закомментируете "frame.setUndecorated (true);" похоже, работает правильно.

Javadoc подразумевает, что это должно работать. Это ошибка в Java? Это ограничено определенным выпуском или версией Windows? Есть ли обходной путь?

Я видел несколько обходных путей , но они кажутся неполными. Я не могу быть первым, кто закодирует мои собственные декорации кадров в Java.

РЕДАКТИРОВАТЬ: После загрузки OpenJDK и копаться в собственном коде, я обнаружил, что Java вызывает функцию win32 SetWindowPlacement и при некоторых условиях изменяет MINMAXINFO чтобы получить правильный размер окна. Я думаю, что то, что я видел, было поведением окон по умолчанию для окна без заголовка или границы (хотя я нигде не могу найти это документально). Я обнаружил, что вызов JFrame.setMaximizedBounds () предоставляет границы, используемые для изменения структуры win32 MINMAXINFO. Поэтому, изменив выполненное действие и используя размер окна, предложенный camickr в качестве MaximizedBounds, я немного ближе:

GraphicsConfiguration graphicsConfiguration = frame.getGraphicsConfiguration();
frame.setMaximizedBounds(graphicsConfiguration.getBounds());
frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH);

Теперь окно максимизации больше не скрывает строку меню. Но .. теперь у меня есть другая проблема. Я не могу максимизировать со второго монитора. Рамка просто исчезает.

Я добавляю некоторые теги win32 в надежде получить программиста на C ++, который распознает эту проблему.

РЕШЕНИЕ: Я, видимо, пока не могу ответить на свой вопрос, поэтому я просто выложу свое решение здесь. Мне пришлось использовать класс Sun, и я не тестировал его ни на каких платформах, кроме Windows, но до сих пор, похоже, он хорошо работает с несколькими мониторами и несколькими конфигурациями панели задач:

GraphicsConfiguration config = frame.getGraphicsConfiguration();
Rectangle usableBounds = SunGraphicsEnvironment.getUsableBounds(config.getDevice());
frame.setMaximizedBounds(new Rectangle(0, 0, usableBounds.width, usableBounds.height));
frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH);

1 Ответ

4 голосов
/ 13 сентября 2011

Интересно. Когда я пытаюсь это сделать, это происходит в два этапа. Сначала расширяется, чтобы заполнить пространство над панелью задач, затем через долю секунды она покрывает панель задач. Понятия не имею почему.

В любом случае для обхода проблемы вы можете использовать:

GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
Rectangle bounds = env.getMaximumWindowBounds();
System.out.println("Screen Bounds: " + bounds );

чтобы вручную установить границы вашего кадра, когда вы хотите увеличить его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...