tags:

views:

673

answers:

6

Hi, I'm writing a small Java GUI program, and I'm having some issues with Java not laying things out properly. I haven't done much Java GUI code lately, so I'm having trouble seeing where the problem lies.

    final JFreeChart chart = createChart(dataset);
    final ChartPanel chartPanel = new ChartPanel(chart, false);
    chartPanel.setPreferredSize(new Dimension(500, 270));
    JPanel buttonPanel = new JPanel();
    buttonPanel.setPreferredSize(new Dimension(500,50));

    JButton toggleButton = new JButton("Toggle");
    final JTextField minRange = new JTextField("10");
    final JTextField maxRange = new JTextField("1000");
    JButton setLimits = new JButton("Set Limits");

    buttonPanel.add(toggleButton, BorderLayout.NORTH);
    buttonPanel.add(minRange, BorderLayout.SOUTH);
    buttonPanel.add(maxRange, BorderLayout.SOUTH);
    buttonPanel.add(setLimits);

JSplitPane jsp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, chartPanel, buttonPanel);
jsp.setDividerLocation(0.8);
setContentPane(jsp);

What's happening here is that all of the layout options are completely being ignored. The GUI components are showing up properly, and the divider specifically is ignoring the preferred size of JFreeChart, and squeezing it to about 5% of space at the top of the frame.

A: 

Try setting the minimum size too.

See: http://stackoverflow.com/questions/538240/java-gui-problems

OscarRyz
Yeah, this turns out to be pretty much a duplicate. Should we make a jsplitpane tag so we don't get this question again?
Michael Myers
Really? Probably we should :)
OscarRyz
A: 

JSplitPane pays attention to the minimum size, not the preferred size. Try simply changing setPreferredSize to setMinumumSize.

Michael Myers
+1  A: 

I believe that using a float proportion on JSplitPane only works once the split pane is "realized", otherwise you're getting a proportion of zero because it doesn't know how big its going to be.

also:

buttonPanel.add(minRange, BorderLayout.SOUTH);
buttonPanel.add(maxRange, BorderLayout.SOUTH);

BorderLayout only allows one component to be in each area, so min range will never appear, as maxRange is now "the" south component. if you want both you'll need to put those 2 components in another panel, then add that panel to the south.

John Gardner
+4  A: 

In addition to problems with the splitpane not respecting your desired sizes, you are using BorderLayout constants but you haven't specified the layout for the panel (the default is FlowLayout).

This:

JPanel buttonPanel = new JPanel();

Should be:

JPanel buttonPanel = new JPanel(new BorderLayout());
Dan Dyer
A: 

Dan Dyer is correct, you didn't set the Layout.

You could also set it by buttonPanel.setLayout(new BorderLayout())

And John Gardner is correct that you set a component to BorderLayout.SOUTH twice.

Also check out MigLayout if you don't already know about it. Its the least "surprising" layout manager I've ever used. It just works. It takes some learning, but very straight forward once you get over the syntax.

And I would avoid SplitPane if you can...its very finicky

Pyrolistical
A: 

Never call setPreferredSize() - it should be a calculation.

For example, your ButtonPanel is being set to a fixed preferred size.

What if you add I18N support and the user is using a language with very long localizations? What if the user resizes the frame?

Check out my article on layout managers for details on how you should really use them. It's from 1999 but still applies:

http://java.sun.com/developer/onlineTraining/GUI/AWTLayoutMgr/

Enjoy!

Scott Stanchfield