Search code examples
javaswingjpanelfullscreensizing

JRootPane in full screen mode sizing issue


I am trying to create a JFrame with a JRootPane that takes up the whole screen, however for some reason the content of the JRootPane does not fill up the the screen like it should.

I believe the issue is that the JRootPane does not fill its parent, but it could be possible that somehow the JRootPane's child panel doesn't fill up the root pane.

This is what it currently shows:

Running Application

Here is the relevant code:

public class Runner {
    public static void main(String[] args){
        GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] devices = graphicsEnvironment.getScreenDevices();
        new MainFrame(devices[0]);
}
}

This is the JFrame with a rootPane that should fill it completely:

public class MainFrame extends JFrame{
private GraphicsDevice graphicsDevice;
private DisplayMode origDisplay;
private final JRootPane rootPane;

public MainFrame(GraphicsDevice graphicsDevice){
    super();
    this.setGraphicsDevice(graphicsDevice);
    this.setOrigDisplay(graphicsDevice.getDisplayMode()); 

    rootPane = new JRootPane(); 
    rootPane.setContentPane(TitleScreenPanel.getInstance(this));
    this.add(rootPane, BorderLayout.CENTER);

    if (graphicsDevice.isFullScreenSupported()){
      setUndecorated(true);
      setResizable(false);
      graphicsDevice.setFullScreenWindow(this);
      revalidate();
    }else{
      System.out.println("Full-screen mode not supported");
    }  

    try {
        Theme.loadTheme(new File("res/IS.theme"));
        UIManager.setLookAndFeel(new TinyLookAndFeel());
    } catch (UnsupportedLookAndFeelException e) {
        e.printStackTrace();
    }


    SwingUtilities.updateComponentTreeUI(this);
    Toolkit.getDefaultToolkit().setDynamicLayout(true);
    System.setProperty("sun.awt.noerasebackground", "true");
    JFrame.setDefaultLookAndFeelDecorated(true);
    JDialog.setDefaultLookAndFeelDecorated(true);
    rootPane.revalidate();


}

public DisplayMode getOrigDisplay() {
    return origDisplay;
}

public void setOrigDisplay(DisplayMode origDisplay) {
    this.origDisplay = origDisplay;
}

public GraphicsDevice getGraphicsDevice() {
    return graphicsDevice;
}

public void setGraphicsDevice(GraphicsDevice graphicsDevice) {
    this.graphicsDevice = graphicsDevice;
}

}

The panel being added to the JRootPane:

public class TitleScreenPanel extends JPanel{
private static TitleScreenPanel titleScreenPanel;
private JButton exitButton;
private JButton startButton;

private TitleScreenPanel(final MainFrame context){
    startButton = new JButton("START");
    startButton.setFont(startButton.getFont().deriveFont(48f));
    startButton.setBorder(BorderFactory.createEmptyBorder());
    startButton.setContentAreaFilled(false);
    exitButton = new JButton("Exit Full-Screen Mode");
    exitButton.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            context.getGraphicsDevice().setDisplayMode(context.getOrigDisplay());
            System.exit(0);
        }
    });
    this.add(startButton, BorderLayout.CENTER);
    this.add(exitButton, BorderLayout.SOUTH);
}

public static TitleScreenPanel getInstance(MainFrame context){
    if(titleScreenPanel == null){
        titleScreenPanel = new TitleScreenPanel(context);
    }
    return titleScreenPanel;
}
}

Solution

  • Let's start with...You don't need to create a JRootPane, a JFrame already has one, in fact, about the only thing you really need to do is either add or set the TitleScreenPane to the JRootPane's contentPane, for example...

    //rootPane = new JRootPane();
    setContentPane(TitleScreenPanel.getInstance(this));
    //add(rootPane, BorderLayout.CENTER);
    

    Next, JPanel uses a FlowLayout by default, so what you are seeing is actually exactly what you should be seeing.

    In order to get what you want, you need to change the layout manager for TitleScreenPanel to BorderLayout...

    As a runnable example...

    FullScreen

    import java.awt.BorderLayout;
    import java.awt.DisplayMode;
    import java.awt.GraphicsDevice;
    import java.awt.GraphicsEnvironment;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class MainFrame extends JFrame {
    
        public static void main(String[] args) {
            GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice[] devices = graphicsEnvironment.getScreenDevices();
            new MainFrame(devices[0]);
        }
    
        private GraphicsDevice graphicsDevice;
        private DisplayMode origDisplay;
    //    private final JRootPane rootPane;
    
        public MainFrame(GraphicsDevice graphicsDevice) {
            super();
            this.setGraphicsDevice(graphicsDevice);
            this.setOrigDisplay(graphicsDevice.getDisplayMode());
    
    //        rootPane = new JRootPane();
            setContentPane(TitleScreenPanel.getInstance(this));
    //        add(rootPane, BorderLayout.CENTER);
    
            if (graphicsDevice.isFullScreenSupported()) {
                setUndecorated(true);
                setResizable(false);
                graphicsDevice.setFullScreenWindow(this);
                revalidate();
            } else {
                System.out.println("Full-screen mode not supported");
            }
    
    //        try {
    //            Theme.loadTheme(new File("res/IS.theme"));
    //            UIManager.setLookAndFeel(new TinyLookAndFeel());
    //        } catch (UnsupportedLookAndFeelException e) {
    //            e.printStackTrace();
    //        }
    //        SwingUtilities.updateComponentTreeUI(this);
    //        Toolkit.getDefaultToolkit().setDynamicLayout(true);
            System.setProperty("sun.awt.noerasebackground", "true");
    //        JFrame.setDefaultLookAndFeelDecorated(true);
    //        JDialog.setDefaultLookAndFeelDecorated(true);
    //        rootPane.revalidate();
    
        }
    
        public DisplayMode getOrigDisplay() {
            return origDisplay;
        }
    
        public void setOrigDisplay(DisplayMode origDisplay) {
            this.origDisplay = origDisplay;
        }
    
        public GraphicsDevice getGraphicsDevice() {
            return graphicsDevice;
        }
    
        public void setGraphicsDevice(GraphicsDevice graphicsDevice) {
            this.graphicsDevice = graphicsDevice;
        }
    
        public static class TitleScreenPanel extends JPanel {
    
            private static TitleScreenPanel titleScreenPanel;
            private JButton exitButton;
            private JButton startButton;
    
            private TitleScreenPanel(final MainFrame context) {
                setLayout(new BorderLayout());
                startButton = new JButton("START");
                startButton.setFont(startButton.getFont().deriveFont(48f));
                startButton.setBorder(BorderFactory.createEmptyBorder());
                startButton.setContentAreaFilled(false);
                exitButton = new JButton("Exit Full-Screen Mode");
                exitButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        context.getGraphicsDevice().setDisplayMode(context.getOrigDisplay());
                        System.exit(0);
                    }
                });
                this.add(startButton, BorderLayout.CENTER);
                this.add(exitButton, BorderLayout.SOUTH);
            }
    
            public static TitleScreenPanel getInstance(MainFrame context) {
                if (titleScreenPanel == null) {
                    titleScreenPanel = new TitleScreenPanel(context);
                }
                return titleScreenPanel;
            }
        }
    }