BoxLayout игнорирует выравнивание подпанели
У меня есть JPanel с менеджером BoxLayout, который содержит подпанели. Я хочу, чтобы компоненты внутри этих субпанелей имели выравнивание по левому краю, но они всегда отображаются по центру. Похоже, BoxLayout правильно выравнивает компоненты, которые вставляются напрямую, но не может этого сделать, когда они находятся внутри подпанели.
Я изменил пример, найденный в http://www.java2s.com/Tutorial/Java/0240__Swing/YAxisAlignment.htm чтобы каждая кнопка помещалась внутри подпанели, а затем подпанель помещалась внутри главной панели с менеджером BoxLayout:
public class YAxisAlignX {
private static Container makeIt(String title, float alignment) {
String labels[] = { "--", "----", "--------", "------------" };
JPanel container = new JPanel();
container.setBorder(BorderFactory.createTitledBorder(title));
BoxLayout layout = new BoxLayout(container, BoxLayout.Y_AXIS);
container.setLayout(layout);
// modified loop. the original version does not create JPanel pan.
// adds the buttons directly the the JPanel container with the
// BoxLayout
for (int i = 0, n = labels.length; i < n; i++) {
JPanel pan = new JPanel();
JButton button = new JButton(labels[i]);
pan.add(button);
button.setAlignmentX(alignment);
pan.setAlignmentX(alignment);
container.add(pan);
}
return container;
}
public static void main(String args[]) {
JFrame frame = new JFrame("Alignment Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container panel1 = makeIt("Left", Component.LEFT_ALIGNMENT);
Container panel2 = makeIt("Center", Component.CENTER_ALIGNMENT);
Container panel3 = makeIt("Right", Component.RIGHT_ALIGNMENT);
Container contentPane = frame.getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(panel1);
contentPane.add(panel2);
contentPane.add(panel3);
frame.pack();
frame.setVisible(true);
}
}
Если вы выполните эту версию, вы увидите, что все кнопки расположены по центру, несмотря на набор выравнивания. Почему это происходит? Есть ли решение? В моем случае каждая подпанель содержит несколько компонентов, и я не хочу добавлять их непосредственно на главную панель.
Большое спасибо.
1 ответ
Но они выровнены!
Прежде всего, setAlignmentX
изменяет свойство на уровне JComponent, макет, в котором размещены эти компоненты, может использовать или не использовать эту информацию. Например, BoxLayout
использует это, но FlowLayout
а также BorderLayout
нет.
В вашем случае вы размещаете несколько панелей с вертикальной BoxLayout и выстраиваете их различными способами, и это работает! Просто так получилось, что панели растягиваются, чтобы уместиться на всю колонну, поэтому фактическое выравнивание не меняет их внешний вид. Вы можете увидеть это, установив Границу вокруг панелей:
pan.setBorder(BorderFactory.createLineBorder(Color.red));
Увидеть:
Тот факт, что панели содержат кнопку или что-то еще, в основном не имеет значения (это влияет только на размер, который панель хочет принять, а не определенно), BoxLayout выравнивает панели, а не то, что находится внутри панелей, это работа каждого макет панели. Вот почему кнопки не влияют на их выравнивание BoxLayout
,
Теперь, как эти кнопки решают его выравнивание? Ну, это до макета, в котором они находятся. Кнопки внутри pan
панель, которая использует LayoutManager по умолчанию FlowLayout
, Теперь, как я уже сказал, FlowLayout не заботится о свойстве alignmentX/Y, поэтому строка:
button.setAlignmentX(alignment);
Ничего не делает. Для выравнивания в FlowLayout вам нужно изменить его alignment
поле через FlowLayout.setAligment(int)
(документы), вы также можете сделать это в конструкторе, поэтому если мы изменим pan
декларация для:
JPanel pan = new JPanel(new FlowLayout(FlowLayout.LEFT));
У вас также будут кнопки, выровненные по левому краю внутри их панелей:
Конечно, все столбцы выровнены по левому краю, так как параметр float alignment
из makeIt
не влияет на выравнивание FlowLayout только на BoxLayout (и это не имеет значения). Вы можете изменить этот аргумент на int и вызвать функцию с другим FlowLayout
константы.
В общем, в оригинальной версии линия button.setAlignmentX(alignment);
имеет смысл, потому что кнопки были добавлены непосредственно к container
Панель и BoxLayout выровняли их правильно:
Однако, как только вы помещаете кнопки в другие панели, BoxLayout начинает выравнивать панели (которые из-за того, как панели работают внутри BoxLayout, они растягиваются, чтобы заполнить всю ширину), а не кнопки, и выравнивание кнопок зависит от расположения панелей., Вот как это должно работать, чтобы мы могли создавать согласованные вложенные макеты.
Надеюсь, это понятно.