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

родителският контейнер има странна ширина и оформлението работи правилно.

Още едно странно наблюдение. Опитах се да добавя множество компоненти към кутията. Проблемът изглежда възниква само когато последният добавен компонент има нечетна ширина.

Както и да е, нямам представа какво прави оформлението на кутията, но определено ми изглежда като грешка.

Решението е да използвате различен мениджър на оформлението. Можете да използвате GridBagLayout за показване на компоненти на различни редове. Ще трябва да зададете ограничението за всеки компонент, за да отидете на нов ред.

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

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