Центрирование 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