Java Swing, почему выравнивание иногда работает?

Существует несколько различных команд для явного выравнивания элементов в Java Swing. Похоже, что эти команды работают только с некоторыми чрезвычайно специфическими ограничениями, и эти ограничения нигде не описаны. В большинстве случаев, когда я хочу выровнять элементы, эти команды вообще ничего не делают. Поэтому мне интересно, почему эти команды не выполняют то, что написано в документации, а также как выровнять элементы в Swing?

Для справки приведем SSCCE с кнопкой OK, которая выравнивается по левому краю, когда мы явно устанавливаем горизонтальное выравнивание по центру.

import javax.swing.*;
import java.awt.*;

public class E {

public static void main(String[] args) {
    JFrame frame = new JFrame();
    JPanel notificationView = new JPanel();
    notificationView.setPreferredSize(new Dimension(300, 145));
    notificationView.setLayout(new GridBagLayout());
    JPanel content = new JPanel();
    content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));

    JLabel notificationText = new JLabel("Here is some text to display to the user and below this is an ok button.");
    content.add(notificationText);
    JButton buttonOkNotification = new JButton("OK");
    //buttonOkNotification.setHorizontalAlignment(JLabel.CENTER); // does not do anything
    //buttonOkNotification.setAlignmentX(Component.CENTER_ALIGNMENT); // does not do anything
    content.add(buttonOkNotification);

    notificationView.add(content);
    frame.add(notificationView);
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
}
}

1 ответ

Решение
JButton buttonOkNotification = new JButton("OK");
//buttonOkNotification.setHorizontalAlignment(JLabel.CENTER); // does not do anything
//buttonOkNotification.setAlignmentX(Component.CENTER_ALIGNMENT); // does not do anything

Обратите внимание, что методы, вызываемые для кнопки, предназначены для выравнивания содержимого кнопки, а не самой кнопки. Эти ограничения обычно становятся уместными или заметными, только если компонент растянут больше, чем его предпочтительный размер. Это растяжение обычно является результатом компоновки и ограничения контейнера, в котором он находится. Хорошим примером является BorderLayout:

  • Чтобы растянуть компонент по горизонтали, но не по вертикали, добавьте его в PAGE_START или же PAGE_END,
  • Чтобы растянуть компонент по вертикали, но не по горизонтали, добавьте его в LINE_START или же LINE_END,
  • Чтобы растянуть компонент по вертикали и горизонтали, добавьте его в CENTER,

Сравните это с FlowLayout, Компоновка потока не растягивает компоненты по вертикали или горизонтали, а всегда сохраняет их предпочтительный размер.


Чтобы выровнять компонент кнопки внутри панели, необходимо использовать ограничения для макета. Это можно сделать на строительстве, например:

new FlowLayout(FlowLayout.RIGHT); // aligns all child components to the right hand side

Но чаще это делается при добавлении компонента в контейнер. Например, при добавлении компонента в GridBagLayout, это может выглядеть так:

gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
panel.add(new JLabel("North West"), gridBagConstraints);
Другие вопросы по тегам