I have a JFrame that consists of a potentially arbitrarily-large set of "headers" which can be clicked on to expose panels, one per header (conceptually similar to a vertically-arranged toolbar, with the headers being tabs that expose various tool panels). I want the headers to have a fixed amount of vertical space assigned to them, but to grow horizontally to fill the width of the frame. I want the panels exposed by the headers to consume all excess vertical space in the frame -- but only if they're visible; when invisible they should take zero space.
Unfortunately, no matter how I try to tweak the layout, I can't keep it from assigning extra space to the headers and to invisible panels. In the demo app, simply make the window larger. The desired behavior is that the blue "Hello 0" panel should grow taller while all other components stay "compact"; in practice I see empty space around the two "Compact label" labels and below the two lower "Click me" headers.
Thanks for your time!
public class Demo {
public static void main(String[] args) {
final JFrame frame = new JFrame("Inspector");
frame.setLayout(new MigLayout("debug, fill, flowy, insets 0, gap 0"));
frame.add(new JLabel("Compact label 1"));
frame.add(new JLabel("Compact label 2"));
for (int i = 0; i < 3; ++i) {
JPanel wrapper = new JPanel(
new MigLayout("debug, fill, flowy, insets 0, gap 0",
"", "0[]0[grow]0"));
// Fixed-height header should grow horizontally only
JPanel header = new JPanel(
new MigLayout("flowx, fillx, insets 0, gap 0"));
header.add(new JLabel("Click me!"), "growx, height 40!");
header.setBackground(Color.RED);
// Variably-sized body should fill any extra space.
final JPanel body = new JPanel(new MigLayout("fill"));
body.add(new JLabel("Hello, " + i), "grow");
body.setBackground(Color.BLUE);
body.setVisible(i == 0);
wrapper.add(header, "growx");
wrapper.add(body, "growy, hidemode 2");
header.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
boolean shouldShow = !body.isVisible();
body.setVisible(shouldShow);
frame.pack();
}
});
frame.add(wrapper, "grow");
}
frame.pack();
frame.setVisible(true);
}
}