Центрирование JLabel в JPanel

У меня есть панель, полученная из JPanel. У меня есть пользовательский элемент управления, полученный из JLabel. Я пытаюсь сосредоточить этот пользовательский JLabel на моей панели.

Единственный способ, которым я знаю, что это будет работать, - использовать пустой макет (setLayout(null)), а затем вычислить пользовательскую точку JLabel setLocation(), чтобы она была в нужном месте.

Пользовательский JLabel физически перемещается с одной панели на эту панель в этом приложении, и я считаю, что местоположение, ранее установленное в setLocation, влияет на вещи. Однако, когда я устанавливаю его на (0,0), компонент поднимается в верхний левый угол.

BorderLayout не работает, потому что, когда только 1 компонент предоставлен и помещен в BorderLayout.CENTER, центральный раздел расширяется, чтобы заполнить все пространство.

Пример, который я вырезал и вставил с другого сайта, использовал BoxLayout и component.setAlignmentX(Component.CENTER_ALIGNMENT). Это тоже не сработало.

Другой ответ, упомянутый выше, над панелью getInset() (я думаю, что он был вызван), но это оказалось тупиком.

До сих пор я работаю с панелью с макетом GridBagLayout, и я включаю объект GridBagConstraints, когда я вставляю пользовательский JLabel в свою панель. Однако это неэффективно. Есть ли лучший способ центрировать JLabel в моем JPanel?

Ответ 1

Установите GridBagLayout для JPanel, поставьте JLabel без GridBagConstraints в JPanel, JLabel будет сосредоточено

enter image description here

Пример

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

public class CenteredJLabel {

    private JFrame frame = new JFrame("Test");
    private JPanel panel = new JPanel();
    private JLabel label = new JLabel("CenteredJLabel");

    public CenteredJLabel() {
        panel.setLayout(new GridBagLayout());
        panel.add(label);
        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(panel);
        frame.setSize(400, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                CenteredJLabel centeredJLabel = new CenteredJLabel();
            }
        });
    }
}

Ответ 2

Предположим, что ваш JLabel называется label, а затем используйте:

label.setHorizontalAlignment(JLabel.CENTER);

Ответ 3

BoxLayout - это путь. Если вы установите X_AXIS BoxLayout, попробуйте добавить горизонтальные клеи до и после компонента:

panel.add(Box.createHorizontalGlue());
panel.add(label);
panel.add(Box.createHorizontalGlue());

Ответ 4

Забудьте все LayoutManager в стандартной библиотеке Java и используйте MigLayout. По моему опыту, гораздо проще работать с обычно делает именно то, что вы ожидаете от него.

Здесь как выполнить то, что вы используете MigLayout.

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import net.miginfocom.swing.MigLayout;

public class Test
{
    public static void main( String[] args )
    {
        JFrame frame = new JFrame( );
        JPanel panel = new JPanel( );

        // use MigLayout
        panel.setLayout( new MigLayout( ) );

        // add the panel to the frame
        frame.add( panel );

        // create the label
        JLabel label = new JLabel( "Text" );

        // give the label MigLayout constraints
        panel.add( label, "push, align center" );

        // show the frame
        frame.setSize( 400, 400 );
        frame.setVisible( true );
    }
}

Большая часть всего лишь шаблона. Ключ - это ограничение макета: "push, align center":

align center сообщает MigLayout о размещении JLabel в центре его ячейки сетки.

push сообщает MigLayout о расширении ячейки сетки, чтобы заполнить доступное пространство.

Ответ 5

Мне не нравятся ответы здесь.

Я никогда не видел действительного использования GridBagLayout в своей карьере. Не сказать, что его нет, просто сказать, что я не видел [действительного], и там может быть корреляция. Более того, добавление одного JLabel в середину Container может сделать его центром демонстрационных целей, но позже у вас будет намного сложнее, если вы попытаетесь продолжить работу с этим над некоторыми другими макетами..

Мне нравится предложение о BoxLayout, потому что это действительно отличный способ сделать это. Тем не менее, этот ответ является лишь частью головоломки, поэтому я и занимаюсь 7-летним вопросом.

Мой "ответ"

На самом деле нет короткого ответа на ваш вопрос. Существует точный ответ на ваш вопрос, основанный на том, что вы спросили, но Qaru о сообществе, которое учится друг у друга, и я подозреваю, что вы пытаетесь научиться использовать макеты в целом (или вы были 7 лет назад) и рассказывать ввод комбинации клавиш для точного демонстрационного примера не даст вам ответа.

Я постараюсь не объяснять какие-либо макеты, для которых вы не можете самостоятельно найти ответ в Интернете (со ссылкой на учебник Oracle в конце, потому что я думаю, что он довольно хорошо объясняет различные макеты).

BoxLayout

BoxLayout - один из способов сделать это, и уже есть фрагмент кода, чтобы продемонстрировать его выше, поэтому я не буду его предоставлять. Я расширю это, чтобы сказать, что, как уже упоминалось, это только точно отвечает на ваш вопрос, но на самом деле ничему вас не научит. Клей, как указывает BoxLayout, в основном дает вам равное количество оставшейся недвижимости между всеми "клеями", которые в настоящее время находятся в Container. Так что, если вы должны были сделать что-то вроде

panel.add(Box.createHorizontalGlue());
panel.add(label);
panel.add(Box.createHorizontalGlue());
panel.add(otherLabel);

Вы обнаружите, что ваш JLabel больше не центрирован, потому что "клей" - это только оставшаяся недвижимость, после того, как два JLabels были добавлены к Container, что быть одинаково разделенным между двумя "слотами" (два вызова к Container#add(Component) with a glue parameter) in the контейнеру ".

BorderLayout

BorderLayout - еще один способ сделать это. BorderLayout разбит на 5 регионов. BorderLayout#CENTER, как вы можете догадаться, является центральной областью. Важное замечание об этой компоновке и о том, как она центрирует вещи, заключается в том, как она подчиняется размерам Component, который находится в центре. это я не буду подробно, хотя; Я думаю, что в конце урока Oracle это достаточно хорошо освещено.

Стоит отметить

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

Смысл всего этого

Теперь все сказанное, я думаю, что все LayoutManager-ы стоит посмотреть. Как и все, что связано с программированием - используйте инструмент, который подходит для работы. Не просто предполагайте, потому что вы использовали макет X раньше, что вы всегда должны использовать макет X, и никакой другой макет не является жизнеспособным. Выясните, как вы хотите, чтобы ваш дисплей выглядел, и как, по вашему мнению, он должен себя вести в отношении изменения размера компонентов, а затем выберите, что, по вашему мнению, будет работать лучше.

Другим двойственным смыслом выбора правильного инструмента является то, что вам не нужно просто вписывать все свои компоненты в один Container и заставить один макет делать все. Ничто не мешает вам (и я настоятельно рекомендую вам) использовать несколько Containers и сгруппировать их все вместе. Управляйте каждым Container макетом, подходящим для этого раздела дисплея, и другим макетом для другого Container.

Важно !!

Причина, по которой это очень важно, заключается в том, что у каждого макета есть правила и вещи, которым они подчиняются, и другие вещи, которые они уважают, а затем другие, которые эффективно игнорируются (например, предпочтительные, максимальные и минимальные размеры). Если вы используете разные макеты [правильно], вы обнаружите, что ваш дисплей принимает динамическое изменение размера при сохранении формы, которую вы хотели сохранить. Это очень важное ключевое различие между правильной работой и простым расчетом с GridBagLayout.

JPanel outer = new JPanel(new BorderLayout());
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.PAGE_AXIS));
JPanel southPanel = new JPanel(new CardLayout());

outer.add(centerPanel, BorderLayout.CENTER);
outer.add(southPanel, BorderLayout.SOUTH);

Выясните, что соответствует вашему сценарию, и продолжайте. Не существует универсального подхода, если только вы не хотите что-то слишком громоздкое и избыточное с помощью других макетов (например, GridBagLayout).

Учебное пособие по Oracle

Если вы сделали это так далеко, то я думаю, что вы ищете столько информации, сколько вы можете получить. В этом случае я настоятельно рекомендую вам прочитать руководство Oracle по менеджерам компоновки, потому что оно очень хорошо излагает их общие детали: https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html