1

I have a GUI in java that I am building for a Learn Java application. My JFrame has a JPanel in it that has a GridBagLayout. The GUI looks something like: (the [Brackets] are buttons)

--------------------------------------------
|          |                    |          |
|          |                    |          |
| Instr-   |    Coding Area     |  Console |
| uctions  |                    |          |
|          |                    |          |
|          |                    |          |
|----|-----|--------------------|          |
|[..]|[...]| [Run]              |          |
|----|-----|-----------|--------|          |
|[Lsn List]|[Previous] | [Next] |          |
|----------|-----------|--------|----------|

I can get my code to run correctly by hardcoding the preferredSize for the Components, but that doesn't change sizes based on the user's screen size. I can properly set the size of the JFrame to the user's screen size; but when I use percentages of the JFrame's size to set the size of the components, I cannot use any Insets without overflowing the components off the frame.

What should I do instead? (I have a feeling that using percentages is not the best practice, and there is probably something I am missing about GridBagLayout).

Here is my Main.java. (I tried to remove anything extraneous, but I could only get it down to ~100 lines without breaking the example).

import javax.swing.*;
import java.awt.*;
public class Main extends JFrame {
    public static Main gui;
    public static int height, width;
    public static String version;
    public static JPanel panel;
    private GridBagConstraints c;
    private static final long serialVersionUID = 1L;
    public Main() {
        initVars();
        initUI();
    }
    private void initVars() {
        Toolkit toolkit = getToolkit();
        Dimension size = toolkit.getScreenSize();
        Insets scnMax = toolkit.getScreenInsets(getGraphicsConfiguration()); // screen insets
        int heightOver = scnMax.bottom + scnMax.top; // <-- these variables make sure not to include taskbar in the window size
        int widthOver = scnMax.left + scnMax.right; // <---
        width = (int)size.getWidth() - widthOver;
        height = (int)size.getHeight() - heightOver;
        panel = new JPanel();
    }
    private void initUI() {
        getContentPane().add(panel);
        pack();
        setSize(width,height);
        panel.setLayout(new GridBagLayout());
    /* code area */
        JEditorPane codeArea = new JEditorPane();
        JScrollPane codeScroll = new JScrollPane(codeArea);
        codeScroll.setPreferredSize(pDim(0.4f,0.7f));
        c = getLocation(2,0,3,1);
        panel.add(codeScroll,c);
    /* learn/instructions area */
        JTextArea instructions = new JTextArea("Instructions");
        instructions.setEditable(false);
        instructions.setPreferredSize(pDim(0.3f,0.7f));
        c = getLocation(0,0,2,1);
        panel.add(instructions, c);
    /* console */
        JTextArea console = new JTextArea("Console");
        console.setEditable(false);
        console.setPreferredSize(pDim(0.3f,0.95f));
        c = getLocation(5,0,1,3);
        panel.add(console, c);
    /* buttons */
        Dimension navigationSize = new Dimension(110,50);
        int both = GridBagConstraints.BOTH;

        JButton btnLearn = new JButton("Learn");
        c = getLocation(0,1,1,1);
        c.fill = both;
        panel.add(btnLearn, c);

        JButton btnInstructions = new JButton("Instructions");
        c = getLocation(1,1,1,1);
        c.fill = both;
        panel.add(btnInstructions, c);

        JButton btnRun = new JButton("Run");
        btnRun.setPreferredSize(navigationSize);
        c = getLocation(2,1,1,1);
        c.fill = both;
        panel.add(btnRun, c);

        JButton btnPrevious = new JButton("Previous");
        btnPrevious.setPreferredSize(navigationSize);
        c = getLocation(2,2,2,1);
        c.fill = both;
        panel.add(btnPrevious, c);

        JButton btnNext = new JButton("Next");
        btnNext.setPreferredSize(navigationSize);
        c = getLocation(4,2,1,1);
        c.fill = both;
        panel.add(btnNext, c);

        JButton btnLessonList = new JButton("Lesson List");
        c = getLocation(0,2,2,1);
        c.fill = both;
        panel.add(btnLessonList,c);
    }
    private GridBagConstraints getLocation(int x, int y, int width, int height) {
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = x; c.gridy = y; c.gridwidth = width; c.gridheight = height;
        return c;
    }
    private int pX(float percent) {return (int)(percent*width);}
    private int pY(float percent) {return (int)(percent*height);}
    private Dimension pDim(float x, float y) {
        return new Dimension(pX(x),pY(y));
    }
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                Main.gui = new Main();
                gui.setVisible(true);
            }
        });
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
AMACB
  • 1,290
  • 2
  • 18
  • 26
  • 2
    `public static Main gui;` The use of `static` in a GUI more often causes problems than solves them. See [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/q/7229226/418556) (Yes.) – Andrew Thompson Mar 26 '16 at 03:48
  • The problem with removing the `setPreferredSize` is that it shrinks everything down ridiculously small. What can I do instead? – AMACB Mar 26 '16 at 03:58
  • 2
    [What layout accepts percentages instead of values in swing?](http://stackoverflow.com/questions/20114174/what-layout-accepts-percentages-instead-of-values-in-swing) demonstrates using percentages instead of calculating the `pX` and `pY` that you did (that requires `setPreferredSize`). – Obicere Mar 26 '16 at 03:59
  • @Obicere Thanks for the boost in the right direction! – AMACB Mar 26 '16 at 04:16
  • If you post that as an answer, I'll accept it. – AMACB Mar 26 '16 at 04:33
  • @Obicere: You've got mail! – Catalina Island Mar 26 '16 at 15:53

0 Answers0