Проблемы выравнивания с BoxLayout

Я делаю приложение, для которого я использую BoxLayout. Как вы можете видеть на следующем рисунке, когда строка заголовка короткая, это идеально. Но чем длиннее строка, тем больше и больше смещается JLabel. imageВот некоторый код, связанный с проблемой:

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);

Есть ли что-то очевидное, что я упускаю? Google не помогает с этой проблемой.

В случае, если это важно, метка страны-прогресс-бар - это просто JPanels с 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);
    }

}

Чтобы управлять SSCCE, введите что-нибудь в текстовое поле и нажмите клавишу ввода.


person tckmn    schedule 17.11.2012    source источник
comment
Я предполагаю, что есть некоторые проблемы с выравниванием. Ознакомьтесь с этим, надеюсь, это поможет вам docs.oracle.com/javase/tutorial/uiswing/layout/   -  person Xara    schedule 17.11.2012
comment
@ Зара, я пробовал. Ничего не произошло   -  person tckmn    schedule 17.11.2012
comment
Хорошо, на самом деле по этой ссылке они обсуждали ту же проблему, что и вы.   -  person Xara    schedule 17.11.2012
comment
@ Зара, да, но я попробовал, и ничего не произошло, как вы можете видеть в моем последнем комментарии.   -  person tckmn    schedule 17.11.2012
comment
Рассмотрите возможность создания и публикации sscce, которую мы сможем проверить, запустить, протестировать и изменить, а затем помочь решить. Кроме того, рассмотрите возможность использования GridBagLayout вместо BoxLayout.   -  person Hovercraft Full Of Eels    schedule 17.11.2012
comment
@HovercraftFullOfEels хорошо, подождите   -  person tckmn    schedule 17.11.2012
comment
@HovercraftFullOfEels хорошо сделано   -  person tckmn    schedule 17.11.2012
comment
1+ за SSCCE и к двум ответам ниже!   -  person Hovercraft Full Of Eels    schedule 17.11.2012


Ответы (2)


  • BoxLayout принимает Min, Max и PreferredSize, дочерние элементы могут изменять размер от с Min по MaxSize

  • FlowLayou не принимает только PreferredSize, остальные (Min, MaxSize) игнорируется этим LayoutManager, размер дочерних элементов не изменяется

  • эти XxxSize вычисляются из PreferredSize полученных из дочерних элементов, помещенных в контейнер (в данном случае JPanel)

  • (ваш вопрос) для получения дополнительной помощи, скорее опубликуйте SSCCE, короткую, работоспособную, компилируемую, только о вашей проблеме

person mKorbel    schedule 17.11.2012
comment
так что... я должен обернуть JLabels в JPanel с FlowLayout? - person tckmn; 17.11.2012
comment
О да! Это исправило это! Спасибо. - person tckmn; 17.11.2012

Вот обновленная версия вашего SSCCE с GridBagLayout. Не уверен, как вы хотите, чтобы компоненты изменяли размер при изменении меток или размера кадра, но это не должно быть слишком сложно.

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);
    }
}
person Guillaume Polet    schedule 17.11.2012
comment
Спасибо, это тоже поможет :) - person tckmn; 17.11.2012
comment
@PicklishDoorknob, это причина, по которой нужно публиковать SSCCE, тогда 1. любое предложение будет касаться нескольких моментов (+1 Гийом Полет), 2. избежание любого беспорядка из-за неизвестного кода, 3. альтернативой GBC являются SpringLayout, пользовательский MigLayout или TableLayout - person mKorbel; 17.11.2012