-1

I have a controlPanel (BoxLayout):

controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS));

Now I build two FlowLayout and add them to the contolPanel panel:

JPanel fromDatePanel = new JPanel(new FlowLayout());
JPanel untilDatePanel = new JPanel(new FlowLayout());

fromDatePanel.add(new JLabel("From - "));
fromDatePanel.add(new JButton("..."));
untilDatePanel.add(new JLabel("Until - "));
untilDatePanel.add(new JButton("..."));

controlPanel.add(fromDatePanel);
controlPanel.add(untilDatePanel);

I'm getting this:

enter image description here

Why it creates a gap between the layouts? If I insert a JButton for example, it works fine (It inserts them with no gap).

How can I remove the gap between the two FlowLayout? (So it'll be like the blue gap)

Maroun
  • 94,125
  • 30
  • 188
  • 241
  • 1
    If you want to keep the `BoxLayout` and get rid of the gap, override `getMaximumSize()` of the `JPanel` and return `getPreferredSize`. See my answer below. – Guillaume Polet Jun 06 '13 at 12:18

3 Answers3

2

See Using Invisible Components as Filler about Box.createVerticalGlue().

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • This will not work. I want to do the opposite - to make the two `FlowLayout`s be right under each other (with no gap). – Maroun Jun 06 '13 at 10:33
  • 2
    Then use `GridBagLayout` or `GroupLayout`; the latter is seen [here](http://stackoverflow.com/a/8504753/230513). – trashgod Jun 06 '13 at 10:35
  • Thanks, I will. But it's interesting, I still want to find a solution for the above problem. It's annoying me :D – Maroun Jun 06 '13 at 10:44
  • 2
    Post all the code. Any time you have a small, easily contained example like this, go to the trouble of creating an entire little program that illustrates your question and post all of it. Half the time or more, you will answer your own question; the other half, you will give others a MUCH better chance to answer it. – arcy Jun 06 '13 at 10:58
2

You can achieve a vertical layout (vertically centered) using GridBagLayout (and use the GridBagConstraint with a gridwidth=REMAINDER):

import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestGridBagLayout {

    protected void initUI() {
        JFrame frame = new JFrame();
        JPanel controlPanel = (JPanel) frame.getContentPane();
        controlPanel.setLayout(new GridBagLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;

        JPanel fromDatePanel = new JPanel(new FlowLayout());
        JPanel untilDatePanel = new JPanel(new FlowLayout());

        fromDatePanel.add(new JLabel("From - "));
        fromDatePanel.add(new JButton("..."));
        untilDatePanel.add(new JLabel("Until - "));
        untilDatePanel.add(new JButton("..."));

        controlPanel.add(fromDatePanel, gbc);
        controlPanel.add(untilDatePanel, gbc);
        frame.setSize(600, 600);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                TestGridBagLayout testMultiplePanels = new TestGridBagLayout();
                testMultiplePanels.initUI();

            }
        });
    }

}

Regarding the difference between JButton and JPanel when added to a BoxLayout, this is due to the differences of implementation of the getMaximumSize() which is taken into account by the BoxLayout. JButton returns the preferred size while JPanel will return null which is interpreted by the BoxLayout as infinite dimensions.

If you want to keep your BoxLayout, you could override JPanel.getMaximumSize() and return getPreferredSize():

import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestGridBagLayout {

    protected void initUI() {
        JFrame frame = new JFrame();
        JPanel controlPanel = (JPanel) frame.getContentPane();
        controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel fromDatePanel = new JPanel(new FlowLayout()) {
            @Override
            public Dimension getMaximumSize() {
                return getPreferredSize();
            }
        };
        JPanel untilDatePanel = new JPanel(new FlowLayout()) {
            @Override
            public Dimension getMaximumSize() {
                return super.getMaximumSize();
            }
        };

        fromDatePanel.add(new JLabel("From - "));
        fromDatePanel.add(new JButton("..."));
        untilDatePanel.add(new JLabel("Until - "));
        untilDatePanel.add(new JButton("..."));

        controlPanel.add(fromDatePanel);
        controlPanel.add(untilDatePanel);
        frame.setSize(600, 600);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                TestGridBagLayout testMultiplePanels = new TestGridBagLayout();
                testMultiplePanels.initUI();

            }
        });
    }

}
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
1

enter image description here

I used BorderLayout and it worked.

        JPanel controlPanel = new JPanel();
        //  controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS));
        controlPanel.setLayout(new BorderLayout());

        JPanel fromDatePanel = new JPanel(new FlowLayout());
        JPanel untilDatePanel = new JPanel(new FlowLayout());

        fromDatePanel.add(new JLabel("From - "));
        fromDatePanel.add(new JButton("..."));
        untilDatePanel.add(new JLabel("Until - "));
        untilDatePanel.add(new JButton("..."));

        controlPanel.add(fromDatePanel, BorderLayout.NORTH);
        controlPanel.add(untilDatePanel, BorderLayout.CENTER);

Edit-1:

You can add nested panels inside each panel.

Nested Panels

        JPanel controlPanel = new JPanel();
        controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS));
        // controlPanel.setLayout(new BorderLayout());

        JPanel fromDatePanel = new JPanel(new FlowLayout());
        JPanel untilDatePanel = new JPanel(new FlowLayout());
        JPanel thirdPnl = new JPanel(new FlowLayout());
        JPanel fourthPnl = new JPanel(new FlowLayout());

        JPanel thrdForthPnl = new JPanel(new BorderLayout()); 

        fourthPnl.add(new JLabel("Fourth"));
        fourthPnl.add(new JButton("4.1"));

        thirdPnl.add(new JLabel("Third"));
        thirdPnl.add(new JButton("3.1"));

        thrdForthPnl.add(thirdPnl, BorderLayout.NORTH);
        thrdForthPnl.add(fourthPnl, BorderLayout.CENTER);

        fromDatePanel.add(new JLabel("From - "));
        fromDatePanel.add(new JButton("..."));
        untilDatePanel.add(new JLabel("Until - "));
        untilDatePanel.add(new JButton("..."));

        controlPanel.add(fromDatePanel, BorderLayout.NORTH);
        controlPanel.add(untilDatePanel, BorderLayout.CENTER);
        controlPanel.add(thrdForthPnl, BorderLayout.SOUTH);
Amarnath
  • 8,736
  • 10
  • 54
  • 81
  • Thanks. But this will work only for two panels. I'm using `BoxLayout` because I want to add more than two buttons. – Maroun Jun 06 '13 at 11:27
  • 1
    @MarounMaroun You can add as many panels ad you want inside each panel. And add the mother of all panels to the contentPane. By designing panel wise you can even reuse these panel later on. – Amarnath Jun 06 '13 at 12:48