将JLabel置于JPanel中心

时间:2012-03-22 19:39:58

标签: java swing layout layout-manager

我有一个来自JPanel的小组。我有一个源自JLabel的自定义控件。我正在尝试将此自定义JLabel置于我的面板中。

我知道这样做的唯一方法就是使用空布局(setLayout(null)),然后计算自定义JLabel的setLocation()点,使其位于正确的位置。

在此应用中,自定义JLabel已从一个面板物理移动到此面板,我相信先前在setLocation中设置的位置正在影响事物。但是,当我将其设置为(0,0)时,组件会进入左上角。

BorderLayout不起作用,因为当只提供1个组件并放入BorderLayout.CENTER时,中央部分会扩展以填充所有空间。

我使用BoxLayoutcomponent.setAlignmentX(Component.CENTER_ALIGNMENT)从另一个网站剪切并粘贴的示例。这也不起作用。

另一个答案提到了覆盖小组的getInset()功能(我认为这就是所谓的),但事实证明这是一个死胡同。

到目前为止,我正在使用一个GridBagLayout布局的面板,当我将自定义GridBagConstraints插入我的面板时,我会添加一个JLabel对象。但这是低效的。有没有更好的方法将JLabel置于我的JPanel

中心

7 个答案:

答案 0 :(得分:32)

GridBagLayout设置JPanel,将JLabel GridBagConstraints添加到JPanelJLabel将居中

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

答案 1 :(得分:16)

JLabel称为label,然后使用:

label.setHorizontalAlignment(JLabel.CENTER);

答案 2 :(得分:8)

BoxLayout是要走的路。如果设置X_AXIS BoxLayout,请尝试在组件之前和之后添加水平胶水:

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

答案 3 :(得分:8)

忘记Java标准库中的所有LayoutManagers并使用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扩展网格单元以填充可用空间。

答案 4 :(得分:1)

我不喜欢这里的答案。

在我的职业生涯中,我从未见过对GridBagLayout的有效使用。不是说没有一个,而是说我还没有看到[有效的]一个,并且那里可能存在相关性。此外,在Container的中间添加一个JLabel可能会使它成为中心,以进行演示,但是如果您尝试继续在某些示例上继续使用它,则以后将会更加困难。其他布局。

我确实喜欢关于BoxLayout的建议,因为这实际上是一种很好的方法。就是说,这个答案只是难题的一部分,因此为什么我要解决一个已有7年历史的问题。

我的“答案”

您的问题确实没有简短的答案。根据您的要求,您的问题有确切的答案,但是StackOverflow是关于社区之间的相互学习,我怀疑您是在尝试总体上(或您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 Container`。

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

答案 5 :(得分:0)

使用它。

labelName.setHorizontalAlignment(SwingConstants.CENTER);

labelName.setHorizontalAlignment(JPanel.CENTER);

他们两个都必须工作。

答案 6 :(得分:0)

这样做而不是库和布局:

JLabel jlabel = new JLabel("Label Text", SwingConstants.CENTER);

确保导入 javax.swing.SwingConstants INTERFACE ,但不要执行它。它只包含常量,不包含方法。

将 JLabel 放在 JPanel 中,否则它将位于 JFrame 或 JWindow(您的顶级容器)的中心。