0

I am using Java8 on Windows machine developing with latest community edition of IntelliJ. To make JFrame full screen I find below solution where I faced one different behavior which I want to get verified.

Solution I took from JFrame full screen

As per the solution I need to put three below lines to make JFrame full screen:

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

But in my project I have created a class AppFrame.java that extends JFrame. And in default constructor I set some basic properties like font etc and importantly visibility to 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);
    }
}

And in class that extends AppFrame when I try to put above three lines (with or without setVisible, which is already coming from AppFrame) to maximize it get below error:

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

As a part of solution (which I want to verify) - Experimentally I removed setVisible (true) from AppFrame.java and it worked, but this would be gonna impact all classes extending AppFrame, so I removed frame.setUndecorated(true); as well from my class and put back setVisible in AppFrame. And exception is gone. Also frame.setUndecorated(true); I believe removes title bar of JFrame.

Also, below is excerpt from javadoc of JFrame:

A frame may have its native decorations (i.e. Frame and Titlebar) turned off with setUndecorated. This can only be done while the frame is not displayable.

It would be great if someone can verify this behavior.

Thomas Fritsch
  • 9,639
  • 33
  • 37
  • 49
shaILU
  • 2,050
  • 3
  • 21
  • 40
  • 2
    I'm not sure what you want us to verify, the documentation is pretty clear – MadProgrammer Oct 18 '17 at 07:39
  • 2
    *" I removed setVisible (true) from AppFrame.java"* - I would argue that this is a good thing, as it shouldn't be up to the `AppFrame` to make determinations about when it should be made visible, that's a implementation detail best left to the child classes – MadProgrammer Oct 18 '17 at 07:40
  • 1
    If you want to maximise a window, you can use [`setExtendedState`](https://docs.oracle.com/javase/8/docs/api/java/awt/Frame.html#setExtendedState-int-) – MadProgrammer Oct 18 '17 at 07:41

2 Answers2

0

By design you have to invoke setUndecorated before and only before setVisible. So you have no other choice but to remove from base class invocation of setVisible and invoke it every time in children classes.

Dmitry Kolesnikovich
  • 669
  • 2
  • 15
  • 33
  • Also it is normal practice (?) to call setVisible outside the constructor in the invokeLater. – Joop Eggen Oct 18 '17 at 09:01
  • "no other choice" is an inaccurate statement, as highlighted by my answer. A zero-parameter initializer is not a requirement (to my knowledge) in any programming language, ASM included. – Wayne Jan 02 '18 at 15:16
0

Modify the initializer to use parameters. AppFrame() { should be changed to AppFrame(boolean undecorated, boolean visible) { then in the initializer add setUndecorated(undecorated); and setVisible(visible);

Completed Solution:

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);
    }
}

In regards to:

A frame may have its native decorations (i.e. Frame and Titlebar) turned off with setUndecorated. This can only be done while the frame is not displayable.

This is just stating that you have to do this before calling setVisible(true);. To determine if you can call setUndecorated safely, you can use if (!isDisplayable()) { ... }

Wayne
  • 351
  • 1
  • 13