Java 在 JPanel 中居中 JLabel

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9829319/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 08:16:28  来源:igfitidea点击:

Centering a JLabel in a JPanel

javaswinglayoutlayout-manager

提问by Shackleford

I have a panel derived from JPanel. I have a custom control derived from JLabel. I am attempting to center this custom JLabelon my panel.

我有一个来自JPanel. 我有一个从JLabel. 我试图JLabel在我的面板上将此自定义居中。

The only way I know to do this that will work is to use the a null layout (setLayout(null)) and then calculate the custom JLabel's setLocation()point so that it's in the right spot.

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

The custom JLabelis physically moved from one panel to this panel in this app and I believe the location previously set in setLocationis affecting things. However when I set it to (0,0) the component goes up into the upper left corner.

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

BorderLayoutdoesn't work because when only 1 component is provided and placed into BorderLayout.CENTER, the central section expands to fill all of the space.

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

An example I cut and pasted from another site used BoxLayoutand component.setAlignmentX(Component.CENTER_ALIGNMENT). This didn't work either.

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

Another answer mentioned overriding the panel's getInset()function (I think that's what it was called), but that proved to be a dead end.

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

So far I'm working with a panel with a GridBagLayoutlayout and I include a GridBagConstraintsobject when I insert the custom JLabelinto my panel. This is inefficient, though. Is there a better way to center the JLabelin my JPanel?

到目前为止,我正在使用一个带有GridBagLayout布局的面板,GridBagConstraints当我将自定义JLabel插入到我的面板中时,我包含了一个对象。但是,这是低效的。有没有更好的方法来集中JLabel在我的JPanel

回答by Jakub Zaverka

BoxLayout is the way to go. If you set up a X_AXIS BoxLayout, try adding horizontal glues before and after the component:

BoxLayout 是要走的路。如果您设置了 X_AXIS BoxLayout,请尝试在组件前后添加水平粘连:

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

回答by ulmangt

Forget all the LayoutManagers in the Java Standard Library and use MigLayout. In my experience it's much easier to work with an usually does exactly what you expect it to do.

忘记 Java 标准库中的所有 LayoutManager 并使用MigLayout。根据我的经验,使用通常完全按照您期望的方式工作要容易得多。

Here's how to accomplish what you're after using 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 );
    }
}

Most of that is just boilerplate. The key is the layout constraint: "push, align center":

其中大部分只是样板。关键是布局约束"push, align center"

align centertells MigLayout to place the JLabel in the center of its grid cell.

align center告诉 MigLayout 将 JLabel 放置在其网格单元的中心。

pushtells MigLayout to expand the grid cell to fill available space.

push告诉 MigLayout 扩展网格单元以填充可用空间。

回答by mKorbel

Set GridBagLayoutfor JPanel, put JLabelwithout any GridBagConstraintsto the JPanel, JLabelwill be centered

设置的GridBagLayoutJPanel的,把一个JLabel没有任何的GridBagConstraints的JPanel一个JLabel将居中

enter image description here

在此处输入图片说明

example

例子

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

回答by hiuller

Supose your JLabelis called label, then use:

假设你JLabel被称为label,然后使用:

label.setHorizontalAlignment(JLabel.CENTER);

回答by searchengine27

I don't like the answers here.

我不喜欢这里的答案。

I've never seen a valid use of a GridBagLayout ever in my career. Not saying there isn't one, just saying I haven't seen [a valid] one, and there might be correlation there. Moreover, adding a single JLabel to the middle of a Containermight make it center for demonstrational purposes, but you're going to have a lot harder of a time later on if you try to continue to work with that over some other layouts.

在我的职业生涯中,我从未见过 GridBagLayout 的有效使用。不是说没有,只是说我没有看到[有效的]一个,并且那里可能存在相关性。此外,将单个 JLabel 添加到 a 的中间Container可能会使其成为演示目的的中心,但是如果您尝试在其他一些布局上继续使用它,那么稍后您将有很多困难。

I do like the suggestion about the BoxLayout, because that is actually a great way to do it. That said, that answer is only part of the puzzle, hence why I'm dredging up a 7 year old question.

我确实喜欢关于 BoxLayout 的建议,因为这实际上是一个很好的方法。也就是说,这个答案只是谜题的一部分,因此我为什么要挖掘一个 7 岁的问题。

My 'Answer'

我的答案'

Really there is no short answer to your question. There is an exact answer to your question based on what you asked, but StackOverflow is about a community learning from each other, and I suspect you're trying to learn how to use layouts in general (or you were 7 years ago) and telling you to type a combination of keys to do exactly your demo case is not going to teach you the answer.

你的问题真的没有简短的答案。根据您提出的问题,您的问题有一个确切的答案,但 StackOverflow 是关于一个社区相互学习,我怀疑您正在尝试学习如何使用布局(或者您是 7 年前)并告诉您键入组合键来完成您的演示案例不会教您答案。

I'm going to try not to explain any layouts that you can't web-search the answer for on your own (with a link to the Oracle tutorial at the end, because I think it explains the different layouts fairly well).

我将尽量不解释您无法自行通过网络搜索答案的任何布局(最后附有 Oracle 教程的链接,因为我认为它很好地解释了不同的布局)。

BoxLayout

盒子布局

BoxLayout is one way to do it, and there is already a code snippet to demo it above so I won't provide one. I'll expand on it to say that, just as mentioned, that only answers your question exactly, but doesn't really teach you anything. Glue, as the BoxLayout refers to it, basically gives you an equal amount of remainingreal-estate between all the 'glue' currently in the Container. So, if you were to do something like

BoxLayout 是一种方法,上面已经有一个代码片段来演示它,所以我不会提供一个。我将进一步说明,正如前面提到的,它只能准确地回答您的问题,但并没有真正教会您任何东西。胶水,为BoxLayout的是指它,基本上给你等量的剩余的所有的“胶水”之间的房地产目前Container。所以,如果你要做类似的事情

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

You would find that your JLabelis no longer centered, because the 'glue' is only the remaining real-estate left, aftertwo JLabelswere added to the Containerwhich will be equallydivided between the two 'slots' (two calls to Container#add(Component) with a glue parameter) in theContainer`.

你会发现你JLabel的不再居中,因为“胶水”只是剩下的房地产,JLabels添加两个之后Container这将在两个“插槽”之间平均分配(两次调用Container#add(Component) with a glue parameter) in theContainer`.

BorderLayout

边框布局

BorderLayout is another way to go about this. BorderLayout is broken down into 5 regions. BorderLayout#CENTER, as you might guess, is the center region. The important note about this layout and how it centers things is how it obeys sizes of the Componentthat is in the center. That I won't detail though; the Oracle tutorial at the end covers it well enough if you're interested, I think.

BorderLayout 是解决此问题的另一种方法。BorderLayout 分为 5 个区域。BorderLayout#CENTER,正如您可能猜到的那样,是中心区域。关于此布局及其中心位置的重要说明是它如何遵守Component中心位置的大小。不过我不会详细说明;我认为,如果您有兴趣,最后的 Oracle 教程已经很好地涵盖了它。

Worth Noting

值得注意

I suppose you could use a GridLayout, but it's a more simple way to do it over a GridBagLayout, which I already said even that I think is not a good approach. So I won't detail this one either.

我想你可以使用 a GridLayout,但它是一种更简单的方法来完成 a GridBagLayout,我已经说过,即使我认为这不是一个好方法。所以我也不会详细介绍这个。

The Point of it All

这一切的重点

Now all that said, I think all LayoutManagers are worth a look. Just like anything else with relation to programming - use the tool that fits the job. Don't just assume because you used X layout before, that you should always use X layout and no other layout is viable. Figure out what you want your display to look like, and how you think it should behave with respect to resizing components, and then pick what you think would work best.

说了这么多,我认为所有的 LayoutManager 都值得一看。就像与编程有关的任何其他事情一样 - 使用适合工作的工具。不要因为您之前使用过 X 布局就假设您应该始终使用 X 布局,而没有其他布局是可行的。弄清楚你希望你的显示器看起来像什么,以及你认为它在调整组件大小方面应该如何表现,然后选择你认为最有效的方式。

Another dual meaning of picking the right tool, is that you don't have to just fit all of your components into one single Containerand make one layout do everything. There is nothing stopping you (and I strongly encourage you to) use multiple Containersand group them all together. Control each Containerwith a layout that is appropriate for that section of the display, and a different layout for a different Container.

选择正确工具的另一个双重含义是,您不必将所有组件整合到一个中,Container然后让一个布局完成所有工作。没有什么可以阻止您(我强烈建议您)使用多个Containers并将它们组合在一起。Container使用适合该显示部分的布局来控制每个布局,并针对不同的Container.

Important!!

重要的!!

The reason why this is very important is because each layout has rules and things that they obey, and other things that they respect, and then others that are effectively ignored (i.e. preferred, maximum, and minimum sizes, for instance). If you use different layouts [correctly], you will find your display accepts dynamically being resized while still obeying the shape that you wanted it to hold. This is a very important key difference between doing it the right way, and just settling with GridBagLayout.

这非常重要的原因是因为每个布局都有他们遵守的规则和事物,以及他们尊重的其他事物,还有其他被有效忽略的事物(例如,首选、最大和最小尺寸)。如果你[正确地]使用不同的布局,你会发现你的显示器可以接受动态调整大小,同时仍然遵守你希望它保持的形状。这是以正确的方式做这件事和只用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);

Figure out what is appropriate to your scenario, and go with that. There is no one-size-fits-all unless you want something overly cumbersome and made redundant by other layouts (i.e. GridBagLayout).

弄清楚什么适合您的场景,然后继续。除非您想要一些过于繁琐且被其他布局(即 GridBagLayout)变得多余的东西,否则没有一刀切。

Oracle's Tutorial

Oracle 的教程

If you've made it this far, then I think you're looking for as much information as you can get. In which case, I strongly encourage you to read Oracle's tutorial on layout managers because it lays out general details of them all very well: https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html

如果您已经做到了这一点,那么我认为您正在寻找尽可能多的信息。在这种情况下,我强烈建议您阅读 Oracle 的布局管理器教程,因为它很好地列出了它们的一般细节:https: //docs.oracle.com/javase/tutorial/uiswing/layout/visual.html