tckmn
tckmn

Reputation: 59343

Alignment issues with BoxLayout

I am making an application for which I am using a BoxLayout. As you can see in the following picture, when the title string is short, it's perfect. But as the string gets longer, the JLabel gets more and more misaligned. image Here's some code that is related to the problem:

JPanel centerPanel = new JPanel();
centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.PAGE_AXIS));
frame.add(centerPanel, BorderLayout.CENTER);
//...
JLabel l = new JLabel(/*...*/);
l.setHorizontalAlignment(SwingConstants.CENTER); //I tried removing and adding
                                                 //this but nothing changed
centerPanel.add(l);

Is there something obvious I am missing? Google isn't being helpful with this problem.

In case it's important, the country-label-progress-bar things are just JPanels with FlowLayouts.

SSCCE:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class SSCCE {

    public static void main(String[] args) {
        final JFrame f = new JFrame("SSCCE");
        JPanel p = new JPanel();
        p.setLayout(new BoxLayout(p, BoxLayout.PAGE_AXIS));
        final JLabel[] titles = new JLabel[5];
        JPanel[] smallPanels = new JPanel[titles.length];
        for (int i = 0; i < smallPanels.length; i ++) {
            titles[i] = new JLabel(Math.random() < 0.5 ? "foo" : "bar");
            p.add(titles[i]);
            smallPanels[i] = new JPanel();
            smallPanels[i].add(new JLabel("foobar"));
            smallPanels[i].add(new JProgressBar());
            p.add(smallPanels[i]);
        }
        f.add(p, BorderLayout.CENTER);
        final JTextField tf = new JTextField("foobar");
        tf.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                titles[2].setText(tf.getText());
                f.repaint();
            }
        });
        f.add(tf, BorderLayout.NORTH);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(600, 600);
        f.setVisible(true);
    }

}

To operate the SSCCE, type something in the text field and press enter.

Upvotes: 1

Views: 655

Answers (2)

Guillaume Polet
Guillaume Polet

Reputation: 47637

Here is an updated version of your SSCCE with a GridBagLayout. Not sure of how you want components to resize when labels or frame size changes but it should not be too hard to manage this.

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;

public class SSCCE {

    public static void main(String[] args) {
        final JFrame f = new JFrame("SSCCE");
        JPanel p = new JPanel();
        p.setLayout(new GridBagLayout());
        Insets insets = new Insets(3, 3, 3, 3);
        GridBagConstraints gbc1 = new GridBagConstraints();
        gbc1.gridwidth = GridBagConstraints.REMAINDER;
        gbc1.anchor = GridBagConstraints.CENTER;
        gbc1.insets = insets;
        GridBagConstraints gbc2 = new GridBagConstraints();
        gbc2.anchor = GridBagConstraints.EAST;
        gbc2.insets = insets;
        GridBagConstraints gbc3 = new GridBagConstraints();
        gbc3.weightx = 1.0;
        gbc3.fill = GridBagConstraints.HORIZONTAL;
        gbc3.gridwidth = GridBagConstraints.REMAINDER;
        gbc3.insets = insets;
        final JLabel[] titles = new JLabel[5];
        Random random = new Random();
        for (int i = 0; i < titles.length; i++) {
            titles[i] = new JLabel(Math.random() < 0.5 ? "foo" : "bar");
            p.add(titles[i], gbc1);
            p.add(new JLabel("foobar"), gbc2);
            JProgressBar progress = new JProgressBar();
            progress.setStringPainted(true);
            progress.setString(String.valueOf(random.nextInt(100)));
            p.add(progress, gbc3);
        }
        f.add(p, BorderLayout.CENTER);
        final JTextField tf = new JTextField("foobar");
        tf.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                titles[2].setText(tf.getText());
                f.repaint();
            }
        });
        f.add(tf, BorderLayout.NORTH);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
    }
}

Upvotes: 3

mKorbel
mKorbel

Reputation: 109823

  • BoxLayout accepting Min, Max and PreferredSize, childs could be resizable from Min to MaxSize

  • FlowLayout accepting only PreferredSize, rest (Min, MaxSize) is ignored by this LayoutManager, childs aren't resizable

  • these XxxSize are calculated from PreferredSize came from childs placed into container (JPanel in this case)

  • (your question) for better help sooner post an SSCCE, short, runnable, compilable, just about your issue

Upvotes: 2

Related Questions