Search code examples
javaswinguser-interfacelayout-managergridbaglayout

How to set a dynamic width for the cells in a GridBagLayout (or any other Layout that can do the job)


I want to build a GUI from a ini-file, so that non programmers can change the layout easier if needed.

I can add JPanel containers and certain Swing components with keywords and arguments given in a text file like this:

//new panel
JPanel "noborder"

alignleft
JLabel
text "Bias (V)"

JToggleButton
text "+/-"

JSpinner "bias"

alignleft
JLabel
text "V"

newline

alignleft
JLabel
text "Current Setpoint"

gridx "2"
JSpinner "setpoint"

alignleft
JLabel
text "nA"

newline

alignleft
JLabel
text "Feedback"

gridx "2"
JSpinner "feedback"

alignleft
JLabel
text "nm/s"

newline

alignleft
JLabel
text "Compensation"

gridx "2"
JSpinner "compensation"

I believe the syntax used is pretty straightforward, newline sets gridx = 0, gridy++, JLabel/JSpinner/JPanel adds new components to the frame with the given GridBagConstraints and increments gridx, ...

The panels are added to a JFrame, aligned in Y direction using a GridBagLayout frameGbc, with the following settings:

frameGbc = new GridBagConstraints();
frameGbc.gridx = 0;
frameGbc.gridy = 0;
frameGbc.anchor = GridBagConstraints.CENTER;
frameGbc.fill = GridBagConstraints.HORIZONTAL;
frameGbc.gridwidth = GridBagConstraints.REMAINDER;

After adding a panel, gridy gets incremented by 1.

When I add a component, it gets added to the last Panel added to the Frame. I can set gridx, gridy, gridwidth, gridheight and anchor via my ini-file.

The file I use currently gives my the following layout:

https://i.sstatic.net/dWNKS.png

The lower part you can see (Starting with a JLabel with the text "Bias (V)") was set up by the part of the ini file I provided above.

The components take the space they need and the panel centers them obviously.

What I want to do, is use the full width given by the broadest panel (the one that needs the most space, here: the one with the 6 buttons) for every panel, so that e.g. for the last panel the program sizes the width of one cell automatically at a quarter of the max width, as the maximum gridx where a component is placed is gridx = 3 -->

cellwidth = maxwidth/4 

Or, more generally:

cellwidth = maxwidth / (highest occupied gridx +1)

I played around with several constraints and looked for similar problems for several hours by now, as I can't find anyone else with a comparable problem I guess the solution must be either really easy or quite tricky.

I defininitely want to avoid having to use weightx, weighty, ipadx, ipady, ... because the syntax of the .ini-file should stay as simple as possible.


Solution

  • so that e.g. for the last panel the program sizes the width of one cell automatically at a quarter of the max width

    You can't do that. That is effectively like saying a cell should have a gridwidth of 1.5 which won't work.

    One solution might be to create a nested panel. The nested panel could have a grid width of 6 to take up the space of all 6 cells. Then each of the 4 components added to this panel would take up 1/4 of the total space available to the panel.