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
Centering a JLabel in a JPanel
提问by Shackleford
I have a panel derived from JPanel
. I have a custom control derived from JLabel
. I am attempting to center this custom JLabel
on 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 JLabel
is physically moved from one panel to this panel in this app and I believe the location previously set in setLocation
is affecting things. However when I set it to (0,0) the component goes up into the upper left corner.
JLabel
在这个应用程序中,自定义从一个面板物理移动到这个面板,我相信之前设置的位置setLocation
会影响事情。但是,当我将其设置为 (0,0) 时,组件会上升到左上角。
BorderLayout
doesn'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 BoxLayout
and component.setAlignmentX(Component.CENTER_ALIGNMENT)
. This didn't work either.
我从另一个使用的站点剪切和粘贴的示例BoxLayout
和component.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 GridBagLayout
layout and I include a GridBagConstraints
object when I insert the custom JLabel
into my panel. This is inefficient, though. Is there a better way to center the JLabel
in 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 center
tells MigLayout to place the JLabel in the center of its grid cell.
align center
告诉 MigLayout 将 JLabel 放置在其网格单元的中心。
push
tells 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
设置的GridBagLayout的JPanel的,把一个JLabel没有任何的GridBagConstraints到的JPanel,一个JLabel将居中
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 JLabel
is 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 Container
might 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 JLabel
is no longer centered, because the 'glue' is only the remaining real-estate left, aftertwo JLabels
were added to the Container
which will be equallydivided between the two 'slots' (two calls to Container#add(Component) with a glue parameter) in the
Container`.
你会发现你JLabel
的不再居中,因为“胶水”只是剩下的房地产,在JLabels
添加两个之后,Container
这将在两个“插槽”之间平均分配(两次调用Container#add(Component) with a glue parameter) in the
Container`.
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 Component
that 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 Container
and make one layout do everything. There is nothing stopping you (and I strongly encourage you to) use multiple Containers
and group them all together. Control each Container
with 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