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