I'm trying to set up a puzzle editor/solver with an interactable canvas on the left, selectable tools on the top right, and a big "Solve" button plus some replay buttons in the bottom right. I'm using a couple of GridBagLayouts (one for the main layout and one for the buttons) and in both places it looks like neither the sizes nor the margins are getting calculated correctly.
Here's a picture of what it's displaying:
What I'd like is a 10-pixel margin around the contents, and 10-pixel margins within each of the right-hand sections, but it's giving me a 15-pixel margin on top and god-knows-what on the bottom and sides. The sub-JPanels are also not being sized correctly, as you can see the content is too large for the window. I'm using a simple box layout for the radio buttons and nothing seems to be wrong with the sizing or margins there. I'm using the expected pixel values as the grid weights because in my mind, that should size them correctly. Any ideas why the margins and sizes are completely broken?
Relevant code attached. EditorToolsGroup is a sub-component that creates the radio buttons. and SolveButtons is a sub-component that creates the solve/replay buttons. I can include the code for SolveButtons if requested, but there's really not anything different going on there.
public class Editor implements ActionListener {
private static final String WINDOW_TITLE = "Golem Puzzle Editor";
private static final int WINDOW_WIDTH = 1500;
private static final int WINDOW_HEIGHT = 800;
private static final int WINDOW_MARGIN = 10;
private static final int CONTROLS_WIDTH = 180;
private static final int SOLVE_BUTTONS_HEIGHT = 100;
private static final int RADIO_BUTTONS_HEIGHT = WINDOW_HEIGHT - SOLVE_BUTTONS_HEIGHT - 2*WINDOW_MARGIN;
private static final int CANVAS_WIDTH = WINDOW_WIDTH - CONTROLS_WIDTH - 2*WINDOW_MARGIN;
private static final int CANVAS_HEIGHT = WINDOW_HEIGHT - 2*WINDOW_MARGIN;
private JFrame window;
private EditorCanvas canvas;
public Editor() {
this.window = new JFrame(WINDOW_TITLE);
this.window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.window.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
JPanel mainPanel = new JPanel();
Border margin = new EmptyBorder( WINDOW_MARGIN, WINDOW_MARGIN, WINDOW_MARGIN, WINDOW_MARGIN);
mainPanel.setBorder(margin);
this.window.add(mainPanel);
JPanel subPanel = new JPanel();
subPanel.setLayout(new GridBagLayout());
mainPanel.add(subPanel);
this.setupCanvas(subPanel);
this.createRadioButtons(subPanel);
this.createSolveButtons(subPanel);
this.window.setVisible(true);
}
private void setupCanvas(JPanel parent) {
this.canvas = new EditorCanvas();
this.canvas.setBackground(Color.RED);
this.canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
GridBagConstraints canvasConstraints = new GridBagConstraints();
canvasConstraints.fill = GridBagConstraints.BOTH;
canvasConstraints.gridwidth = 1;
canvasConstraints.gridheight = 2;
canvasConstraints.gridx = 0;
canvasConstraints.gridy = 0;
canvasConstraints.weightx = CANVAS_WIDTH;
canvasConstraints.weighty = CANVAS_HEIGHT;
parent.add(this.canvas, canvasConstraints);
}
private void createRadioButtons(JPanel parent) {
EditorToolsGroup editorToolsGroup = new EditorToolsGroup(this);
JPanel editorToolsGroupPanel = editorToolsGroup.getPanel();
editorToolsGroupPanel.setBackground(Color.GREEN);
editorToolsGroupPanel.setPreferredSize(new Dimension(CONTROLS_WIDTH, RADIO_BUTTONS_HEIGHT));
GridBagConstraints toolsGroupConstraints = new GridBagConstraints();
toolsGroupConstraints.fill = GridBagConstraints.BOTH;
toolsGroupConstraints.gridwidth = 1;
toolsGroupConstraints.gridheight = 1;
toolsGroupConstraints.gridx = 1;
toolsGroupConstraints.gridy = 0;
toolsGroupConstraints.weightx = CONTROLS_WIDTH;
toolsGroupConstraints.weighty = RADIO_BUTTONS_HEIGHT;
parent.add(editorToolsGroupPanel, toolsGroupConstraints);
}
private void createSolveButtons(JPanel parent) {
SolveButtons solveButtons = new SolveButtons(this);
JPanel solveButtonsPanel = solveButtons.getPanel();
solveButtonsPanel.setBackground(Color.BLUE);
solveButtonsPanel.setPreferredSize(new Dimension(CONTROLS_WIDTH, SOLVE_BUTTONS_HEIGHT));
GridBagConstraints buttonConstraints = new GridBagConstraints();
buttonConstraints.fill = GridBagConstraints.BOTH;
buttonConstraints.gridwidth = 1;
buttonConstraints.gridheight = 1;
buttonConstraints.gridx = 1;
buttonConstraints.gridy = 1;
buttonConstraints.weightx = CONTROLS_WIDTH;
buttonConstraints.weighty = SOLVE_BUTTONS_HEIGHT;
parent.add(solveButtonsPanel, buttonConstraints);
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
// TODO
}
}