BoxLayout не может выровнять один элемент с нечетной шириной по центру

Я пытаюсь выровнять ряд элементов по вертикальной оси в центре панели, и BoxLayout кажется именно тем, что мне нужно. Однако кажется странным, когда все добавляемые элементы имеют нечетную ширину.

Вот SSCCE, демонстрирующий это странное поведение:

import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.JFrame;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.BoxLayout;
import java.awt.Graphics;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.Component;

public class BoxBug {
  public static void main(String[] args){
    UIManager.put("swing.boldMetal", Boolean.FALSE);
    SwingUtilities.invokeLater(new Runnable(){
      public void run(){
        gui();
      }
    });
  }

  public static void gui(){
    JFrame f = new JFrame("Title");
    Box b = new Box(BoxLayout.Y_AXIS);

    JComponent c = new JComponent(){
      public void paint(Graphics g){
        g.setColor(new Color(255, 0, 0));
        g.fillRect(0, 0, getWidth(), getHeight());
      }

      // just change the first argument here
      // (even numbers work fine, odd ones fail)
      private Dimension p = new Dimension(3, 20);
      public Dimension getPreferredSize(){return p;}
      public Dimension getMinimumSize(){return p;}
      public Dimension getMaximumSize(){return p;}
    };
    c.setAlignmentX(Component.CENTER_ALIGNMENT);

    b.add(c);
    f.add(b);
    f.pack();
    f.setVisible(true);
  }
}

Вот как это выглядит:

введите здесь описание изображения

Когда я изменяю ширину JComponent с 3 на 4, он отлично работает:

введите здесь описание изображения

Затем снова происходит сбой, когда я изменяю ширину на 5:

введите здесь описание изображения

Я искал эту проблему в Google и StackOverflow, но не нашел никакой документации по этому вопросу, поэтому мне кажется, что это ошибка.

Если это ошибка, может ли кто-нибудь найти хак, чтобы обойти ее?


person xinxinw1    schedule 03.05.2014    source источник


Ответы (1)


Однако кажется странным, когда все добавляемые элементы имеют нечетную ширину.

Это становится более странным, чем это. Размер родительского контейнера также влияет на макет.

Я заменил f.pack() на:

f.setSize(150, 100);

и это не работает. В основном это сценарий, который вы описали, поскольку этот метод или f.pack() приведут к тому, что родительский контейнер будет иметь четную ширину, а макет не работает.

Однако, если вы используете:

f.setSize(151, 100);

родительский контейнер имеет нечетную ширину, и макет работает правильно.

Еще одно странное наблюдение. Я попытался добавить несколько компонентов в Box. Проблема возникает только тогда, когда последний добавленный компонент имеет нечетную ширину.

В любом случае, я понятия не имею, что делает макет коробки, но мне это кажется ошибкой.

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

Или вы можете попробовать использовать относительный макет, который поддерживает вертикальный макет. с выравниванием по центру, и вам не нужны никакие ограничения. Единственное изменение в вашем коде будет:

//Box b = new Box(BoxLayout.Y_AXIS);
JPanel b = new JPanel( new RelativeLayout(RelativeLayout.Y_AXIS) );
person camickr    schedule 03.05.2014