Search code examples
javajframewindowsize

How do I set my Java window (JFrame, actually) to the correct resolution?


I'm mucking about in Java by modifying Jamal's pong game and now I've noticed that the entire window is literally 800x600, but that's not what I want! I want the frame to be 800x600 and around that to be the window 8's fancy borders. It makes little sense to me to ask Java for a 800x600 JFrame and then get a 794x571 frame to work with!


The main code to set the window:

public Main() {
    // cvars contains variables from JPong.ini (It's an extended class from the ini4j library)
    cvars = CVarList.getInstance();

    // get(sectionName, optionName, classtype, defaultValue)
    setSize(cvars.get("Window", "width", int.class, 800),
            cvars.get("Window", "height", int.class, 600));
    setTitle(cvars.get("Window", "title", String.class, "JPong"));
    setResizable(cvars.get("Window", "resizable", boolean.class, false));
    setVisible(true);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    table = new Table(this);
    add(table);
}

The reason I found out was because I changed the racket/paddle speed and the racket/paddles got stuck at either end of the window, so after modifying the code the paddles didn't stick anymore, but now they moved a little bit out of the visible frame (because I used 0 and the window's height in the logic to stop the racket/paddle)

Now I wonder how many Java windows are actually sized wrong...


Solution

  • Create a JPanel which contains the Table, within it, override it's getPreferredSize method and return the desired size you want

    public class TableWrapperPanel extends JPanel {
        private Table table;
        public TableWrapperPanel(Table table) {
            setLayout(new BorderLayout());
            this.table = table;
            add(table);
        }
    
        public Dimension getPreferredSize() {
            cvars = CVarList.getInstance();
            return new Dimension(cvars.get("Window", "width", int.class, 800),
                cvars.get("Window", "height", int.class, 600));
        }
    }
    

    Now, in your main method, create an instance of the TableWrapperPanel and add it to your "window", calling pack after you have done so, this will pack the window around your content.

    public Main() {
        // cvars contains variables from JPong.ini (It's an extended class from the ini4j library)
        cvars = CVarList.getInstance();
    
        // get(sectionName, optionName, classtype, defaultValue)
        setSize(cvars.get("Window", "width", int.class, 800),
                cvars.get("Window", "height", int.class, 600));
        setTitle(cvars.get("Window", "title", String.class, "JPong"));
        setResizable(cvars.get("Window", "resizable", boolean.class, false));
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        TableWrapperPanel wrapper = new TableWrapper(table);
        add(wrapper );
        pack();
        setVisible(true);
    }
    

    Alternatively, you could just create a custom version of Table which overrides the getPreferredSize method itself

    public class SizableTable extends Table { 
        //... Constructors ...
    
        public Dimension getPreferredSize() {
            cvars = CVarList.getInstance();
            return new Dimension(cvars.get("Window", "width", int.class, 800),
                cvars.get("Window", "height", int.class, 600));
        }
    }
    

    And instead of creating an instance of Table in the main method, create an instance of SizableTable, adding it to the window and then calling pack