1

I wrote this code sample to illustrate a problem I'm having with my program.

I expect to be able to slide the JSplitPane's slider bar to the left, beyond the edge of the buttons, compressing that JPanel, and have the FlowLayout wrap the buttons to a second row.

Instead, the JSplitPane does not allow me to move the slider past the rightmost button on the screen, and if I resize the entire JFrame to force the compression, the buttons (I presume) are just running off the righthand side of the JPanel, underneath the slider bar (I guess, because I obviously cannot see them).

What am I doing wrong?

import java.awt.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
public class Driver implements Runnable {
    public static void main(String[] args) {
        (new Driver()).run();
    }
    public void run() {
        try {
            go();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }
    private void go() throws Exception {
        JFrame jframe = new JFrame("FlowLayoutTest");
        JPanel left = new JPanel();
        left.setBackground(Color.RED);
        left.setLayout(new BorderLayout());
        JPanel right = new JPanel();
        right.setBackground(Color.BLUE);
        right.setLayout(new BorderLayout());
        JSplitPane topmost =
            new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, right);
        jframe.setContentPane(topmost);
        JPanel bottomleft = new JPanel();
        bottomleft.setBackground(Color.GREEN);
        bottomleft.setLayout(new FlowLayout());
        left.add(bottomleft, BorderLayout.PAGE_END);
        for (int i = 0; i < 10; i++) {
            bottomleft.add(new JButton("" + i));
        }
        jframe.pack();
        jframe.setVisible(true);
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
Maarx
  • 633
  • 1
  • 7
  • 18

2 Answers2

7

Is there another layout manager besides FlowLayout that will do what I'm looking for?

Wrap Layout should work.

camickr
  • 321,443
  • 19
  • 166
  • 288
1

If you add this

bottomleft.setMinimumSize(new Dimension(0, 0));

before the pack() then it'll reflow. BUT, it won't re-pack the border layout, so instead of two lines you'll get one with the rest cut off. So after a resize you'll have to repack the border layout. If you omit the border layout then it'll reflow like you want.

That said, you should avoid FlowLayout like the plague. Most of the layouts that come with Swing are poor, but FlowLayout is one of the worst offenders.

Adam
  • 16,808
  • 7
  • 52
  • 98
  • The problem is, my program has actual stuff within the other sections of the BorderLayout, but removing them doesn't affect the behavior of 'bottomleft', so my mockup omits them. – Maarx Apr 18 '11 at 23:16
  • Is there another layout manager besides FlowLayout that will do what I'm looking for? (start with one row, wrap to a second, and expand the component upward) – Maarx Apr 18 '11 at 23:19
  • "So after a resize you'll have to repack the border layout." Where would I insert some code to run "after a resize"? – Maarx Apr 18 '11 at 23:35
  • @Adam, There is nothing wrong with FlowLayout. It was designed for a specific function and is extremely simple to use for its designed functionality. – camickr Apr 19 '11 at 01:16
  • @Maarx, you can use a resize listener on left. Or better yet, try the mentioned Wrap Layout. If you like hand coding GUIs I think you'll benefit a lot from looking for some non-standard layout managers anyway. @camickr, I'd argue that its designed functionality is rarely useful. What the OP is doing should "just work", but requires WrapLayout to fix it. But more importantly, this sort of layout tends to produce very ugly GUIs that don't behave well and don't conform to any sort of GUI design guidelines, even Sun's. – Adam Apr 19 '11 at 01:45
  • 1
    @Adam, The FlowLayout is simply designed to flow components on a line. It is well suited for any dialog where you have your "Ok" and "Cancel" buttons that are right aligned in the SOUTH panel of a BorderLayout. Every layout has a purpose if you use it properly. It was never designed to be a multi use layout with dozens of constraints that you need to comfigure in order to get it to work properly. GUI's should be built with the proper combination of layout managers. Its not meant to be one size fits all. – camickr Apr 19 '11 at 04:04
  • @camickr very true, it's important to use the right tool for the job. But for instances where components should flow on one line then BoxLayout is better because FlowLayout might wrap. Now if you do want it to wrap then FlowLayout can misbehave due to not updating the preferred size to be two lines. I think if FlowLayout was written properly then the OP wouldn't be asking this question. – Adam Apr 19 '11 at 04:13
  • If component should flow on one line then FlowLayout is the easiest to use. You just add the component to the panel and spacing is automatically added between components. If the panel is added to the NORTH or SOUTH then, yes, the components will wrap but you don't see them. This is similiar behaviour to the BoxLayout where components are truncated if there is not enough spaces to display all components. So either way not all components will be visible. It boils down to the requirement and designing the GUI properly. – camickr Apr 19 '11 at 05:35