JFrame в полноэкранном режиме без оформления

Я использую Java8 на компьютере с Windows, разрабатываемом с последней версией сообщества IntelliJ. Чтобы сделать JFrame полноэкранным, я нахожу ниже решение, в котором я столкнулся с одним другим поведением, которое я хочу проверить.

Решение, которое я взял из полный экран JFrame

В соответствии с решением мне нужно поместить три строки ниже, чтобы сделать JFrame полноэкранным:

frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 
frame.setUndecorated(true);
frame.setVisible(true);

Но в моем проекте я создал класс AppFrame.java, который расширяет JFrame. И в конструкторе по умолчанию я установил некоторые основные свойства, такие как шрифт и т. Д., И, что важно, видимость в true.

import javax.swing.*;
import java.awt.*;

public class AppFrame extends JFrame {

    AppFrame() {
        Font baseFont = new Font("Dialog", Font.PLAIN, 12);
        setFont(baseFont);
        setLocationRelativeTo(null);
        setBackground(Color.WHITE);
        setForeground(Color.black);
        setLayout(new FlowLayout());
        setVisible(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}

И в классе, который расширяет AppFrame, когда я пытаюсь поместить выше три строки (с setVisible или без него, который уже исходит из AppFrame), чтобы максимизировать его, появляется ошибка ниже:

Exception in thread "main" java.awt.IllegalComponentStateException: The frame is displayable. at java.awt.Frame.setUndecorated(Frame.java:923)

Как часть решения (которое я хочу проверить). Экспериментально я удалил setVisible (true) из AppFrame.java, и это сработало, но это повлияет на все классы, расширяющие AppFrame, поэтому я также удалил frame.setUndecorated(true); из своего класса и поставил назад setVisible в AppFrame. И исключение исчезло. Также frame.setUndecorated(true); я считаю, что удаляет строку заголовка JFrame.

Кроме того, ниже приведен отрывок из javadoc JFrame:

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

Было бы здорово, если бы кто-то мог проверить это поведение.


person shaILU    schedule 18.10.2017    source источник
comment
Я не уверен, что вы хотите, чтобы мы проверили, документация довольно ясна   -  person MadProgrammer    schedule 18.10.2017
comment
Я удалил setVisible (true) из AppFrame.java — я бы сказал, что это хорошо, поскольку AppFrame не должен определять, когда его следует сделать видимым, это детали реализации лучше оставить дочерним классам   -  person MadProgrammer    schedule 18.10.2017
comment
Если вы хотите развернуть окно, вы можете использовать setExtendedState   -  person MadProgrammer    schedule 18.10.2017


Ответы (2)


По замыслу вы должны вызывать setUndecorated до и только перед setVisible. Таким образом, у вас нет другого выбора, кроме как удалить из базового класса вызов setVisible и вызывать его каждый раз в дочерних классах.

person Dmitry Kolesnikovich    schedule 18.10.2017
comment
Также нормальной практикой (?) является вызов setVisible вне конструктора в invokeLater. - person Joop Eggen; 18.10.2017
comment
никакой другой выбор не является неточным утверждением, как подчеркивается в моем ответе. Инициализатор с нулевым параметром не является обязательным (насколько мне известно) ни на одном языке программирования, включая ASM. - person Wayne; 02.01.2018

Измените инициализатор, чтобы использовать параметры. AppFrame() { следует изменить на AppFrame(boolean undecorated, boolean visible) {, затем в инициализаторе добавить setUndecorated(undecorated); и setVisible(visible);

Готовое решение:

import javax.swing.*;
import java.awt.*;

public class AppFrame extends JFrame {

    AppFrame(boolean undecorated, boolean visible) {
        Font baseFont = new Font("Dialog", Font.PLAIN, 12);
        setFont(baseFont);
        setLocationRelativeTo(null);
        setBackground(Color.WHITE);
        setForeground(Color.black);
        setLayout(new FlowLayout());
        setExtendedState(JFrame.MAXIMIZED_BOTH);
        setUndecorated(undecorated);
        setVisible(visible);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}

В связи с:

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

Это просто означает, что вы должны сделать это перед вызовом setVisible(true);. Чтобы определить, можете ли вы безопасно вызвать setUndecorated, вы можете использовать if (!isDisplayable()) { ... }

person Wayne    schedule 02.01.2018