Java Swing - 使用 BorderLayout 将 JLabel 居中
Java Swing - Center a JLabel using BorderLayout
我有一个作业,说明指定我需要两个标签在屏幕上居中(水平和垂直)。
我知道这个问题已经被问过很多次,但每当我搜索这个问题时,给出的解决方案通常是使用不同的布局管理器,比如 BoxLayout。但是,说明还指定我必须使用 BorderLayout。
最初我没有将标签添加到面板,而是直接将它们添加到框架,但这没有用,所以建议我将它们都放在 JPanel 上,这也没有用。
我的代码目前看起来像这样:
JButton butSubmit = new JButton("Submit");
JButton butReset = new JButton("Reset");
JLabel nameAndReg = new JLabel("My details", SwingConstants.CENTER);
JLabel errorMsg = new JLabel("The error message", SwingConstants.CENTER);
nameAndReg.setForeground(Color.blue);
JTextField redVal = new JTextField(3);
JTextField greenVal = new JTextField(3);
JTextField blueVal = new JTextField(3);
JPanel butPanelSouth = new JPanel();
JPanel butPanelNorth = new JPanel();
JPanel labsPanel = new JPanel();
butPanelSouth.add(redVal);
butPanelSouth.add(greenVal);
butPanelSouth.add(blueVal);
butPanelSouth.add(butSubmit);
butPanelNorth.add(butReset);
labsPanel.add(nameAndReg, BorderLayout.CENTER);
labsPanel.add(errorMsg, BorderLayout.CENTER);
add(labsPanel, BorderLayout.CENTER);
add(butPanelNorth, BorderLayout.NORTH);
add(butPanelSouth, BorderLayout.SOUTH);
这就是它产生的结果:
如何让 'My details' 和 'The error message' 垂直和水平地位于 window 的中间,一个在另一个下面,并且仍然使用 BorderLayout?
编辑:抱歉,我意识到我不是很清楚。我得到的建议是 'perhaps nest your layout managers i.e. put a JPanel in the centre of a BorderLayout on a JFrame.'
正如我在上面的评论中所说,当你说 "the instructions also specify that I must use BorderLayout
".
时,你应该澄清你的意思
如果您的意思是您的内容面板必须有 BorderLayout
,而其他面板可以有不同的布局(就像在您的代码中一样,因为您在子面板中使用了 FlowLayout
), 很容易解决你的问题。
您只需要在 JPanel
中添加标签,它使用的布局将标签居中对齐,就像 GridBagLayout
那样。
您的第一个标签将包含 gridx = 0
和 gridy = 0
,第二个标签将包含 gridx = 0
和 gridy = 1
。
你的第二个将正好在第一个下面,你可以使用 insets
创建一些空的 space (在下面的代码中我使用 5 个像素作为 Insets.top
)。
由于您的 labsPanel
将位于 BorderLayout.CENTER
,面板将采用您框架中的所有空白 space,并且 GridBagConstrains.anchor
默认值(GridBagConstrains.CENTER
) 确保你的标签在你的 labsPanel
内居中。结果,标签将在框架的中间垂直和水平对齐,如下面的屏幕截图所示:
代码示例:
import java.awt.*;
import javax.swing.*;
public class Test
{
public static void main (String [] a) {
SwingUtilities.invokeLater (new Runnable () {
@Override public void run () {
createAndShowGUI ();
}
});
}
private static void createAndShowGUI () {
JFrame frame = new JFrame ("Test");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.setContentPane (new MainPanel ());
frame.pack ();
frame.setLocationRelativeTo (null);
frame.setVisible (true);
}
}
class MainPanel extends JPanel
{
public MainPanel () {
super (new BorderLayout ());
JLabel nameAndReg = new JLabel ("My details", SwingConstants.CENTER);
JLabel errorMsg = new JLabel ("The error message", SwingConstants.CENTER);
nameAndReg.setForeground(Color.blue);
JPanel labsPanel = new JPanel (new GridBagLayout ());
labsPanel.add (nameAndReg);
GridBagConstraints c = new GridBagConstraints ();
c.gridy = 1;
c.insets = new Insets (5, 0, 0, 0);
labsPanel.add (errorMsg, c);
JButton butSubmit = new JButton("Submit");
JButton butReset = new JButton("Reset");
JTextField redVal = new JTextField(3);
JTextField greenVal = new JTextField(3);
JTextField blueVal = new JTextField(3);
JPanel butPanelSouth = new JPanel ();
JPanel butPanelNorth = new JPanel ();
butPanelSouth.add (redVal);
butPanelSouth.add (greenVal);
butPanelSouth.add (blueVal);
butPanelSouth.add (butSubmit);
butPanelNorth.add (butReset);
add (labsPanel, BorderLayout.CENTER);
add (butPanelNorth, BorderLayout.NORTH);
add (butPanelSouth, BorderLayout.SOUTH);
}
}
如果 所有 你的面板必须有一个 BorderLayout
,很难实现你想要的,但正如我所说,这将是一个疯狂的要求。
发布的代码只是有一个错误。下面一行:
labsPanel.add(nameAndReg, BorderLayout.CENTER);
与面板的构造不一致 - no-arg 构造函数默认为 Flow Layout(因此添加的 2 个标签彼此相邻):
JPanel labsPanel = new JPanel();
要使用边框布局约束,面板必须使用 BorderLayout
:
JPanel labsPanel = new JPanel(new BorderLayout());
但请注意,您只能将单个组件添加到 BorderLayout
的 CENTRE
位置。如果您希望这 2 个标签在垂直中心“流动”在一起,您可能需要再嵌套一个 JPanel
。
我有一个作业,说明指定我需要两个标签在屏幕上居中(水平和垂直)。
我知道这个问题已经被问过很多次,但每当我搜索这个问题时,给出的解决方案通常是使用不同的布局管理器,比如 BoxLayout。但是,说明还指定我必须使用 BorderLayout。
最初我没有将标签添加到面板,而是直接将它们添加到框架,但这没有用,所以建议我将它们都放在 JPanel 上,这也没有用。
我的代码目前看起来像这样:
JButton butSubmit = new JButton("Submit");
JButton butReset = new JButton("Reset");
JLabel nameAndReg = new JLabel("My details", SwingConstants.CENTER);
JLabel errorMsg = new JLabel("The error message", SwingConstants.CENTER);
nameAndReg.setForeground(Color.blue);
JTextField redVal = new JTextField(3);
JTextField greenVal = new JTextField(3);
JTextField blueVal = new JTextField(3);
JPanel butPanelSouth = new JPanel();
JPanel butPanelNorth = new JPanel();
JPanel labsPanel = new JPanel();
butPanelSouth.add(redVal);
butPanelSouth.add(greenVal);
butPanelSouth.add(blueVal);
butPanelSouth.add(butSubmit);
butPanelNorth.add(butReset);
labsPanel.add(nameAndReg, BorderLayout.CENTER);
labsPanel.add(errorMsg, BorderLayout.CENTER);
add(labsPanel, BorderLayout.CENTER);
add(butPanelNorth, BorderLayout.NORTH);
add(butPanelSouth, BorderLayout.SOUTH);
这就是它产生的结果:
如何让 'My details' 和 'The error message' 垂直和水平地位于 window 的中间,一个在另一个下面,并且仍然使用 BorderLayout?
编辑:抱歉,我意识到我不是很清楚。我得到的建议是 'perhaps nest your layout managers i.e. put a JPanel in the centre of a BorderLayout on a JFrame.'
正如我在上面的评论中所说,当你说 "the instructions also specify that I must use BorderLayout
".
如果您的意思是您的内容面板必须有 BorderLayout
,而其他面板可以有不同的布局(就像在您的代码中一样,因为您在子面板中使用了 FlowLayout
), 很容易解决你的问题。
您只需要在 JPanel
中添加标签,它使用的布局将标签居中对齐,就像 GridBagLayout
那样。
您的第一个标签将包含 gridx = 0
和 gridy = 0
,第二个标签将包含 gridx = 0
和 gridy = 1
。
你的第二个将正好在第一个下面,你可以使用 insets
创建一些空的 space (在下面的代码中我使用 5 个像素作为 Insets.top
)。
由于您的 labsPanel
将位于 BorderLayout.CENTER
,面板将采用您框架中的所有空白 space,并且 GridBagConstrains.anchor
默认值(GridBagConstrains.CENTER
) 确保你的标签在你的 labsPanel
内居中。结果,标签将在框架的中间垂直和水平对齐,如下面的屏幕截图所示:
代码示例:
import java.awt.*;
import javax.swing.*;
public class Test
{
public static void main (String [] a) {
SwingUtilities.invokeLater (new Runnable () {
@Override public void run () {
createAndShowGUI ();
}
});
}
private static void createAndShowGUI () {
JFrame frame = new JFrame ("Test");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.setContentPane (new MainPanel ());
frame.pack ();
frame.setLocationRelativeTo (null);
frame.setVisible (true);
}
}
class MainPanel extends JPanel
{
public MainPanel () {
super (new BorderLayout ());
JLabel nameAndReg = new JLabel ("My details", SwingConstants.CENTER);
JLabel errorMsg = new JLabel ("The error message", SwingConstants.CENTER);
nameAndReg.setForeground(Color.blue);
JPanel labsPanel = new JPanel (new GridBagLayout ());
labsPanel.add (nameAndReg);
GridBagConstraints c = new GridBagConstraints ();
c.gridy = 1;
c.insets = new Insets (5, 0, 0, 0);
labsPanel.add (errorMsg, c);
JButton butSubmit = new JButton("Submit");
JButton butReset = new JButton("Reset");
JTextField redVal = new JTextField(3);
JTextField greenVal = new JTextField(3);
JTextField blueVal = new JTextField(3);
JPanel butPanelSouth = new JPanel ();
JPanel butPanelNorth = new JPanel ();
butPanelSouth.add (redVal);
butPanelSouth.add (greenVal);
butPanelSouth.add (blueVal);
butPanelSouth.add (butSubmit);
butPanelNorth.add (butReset);
add (labsPanel, BorderLayout.CENTER);
add (butPanelNorth, BorderLayout.NORTH);
add (butPanelSouth, BorderLayout.SOUTH);
}
}
如果 所有 你的面板必须有一个 BorderLayout
,很难实现你想要的,但正如我所说,这将是一个疯狂的要求。
发布的代码只是有一个错误。下面一行:
labsPanel.add(nameAndReg, BorderLayout.CENTER);
与面板的构造不一致 - no-arg 构造函数默认为 Flow Layout(因此添加的 2 个标签彼此相邻):
JPanel labsPanel = new JPanel();
要使用边框布局约束,面板必须使用 BorderLayout
:
JPanel labsPanel = new JPanel(new BorderLayout());
但请注意,您只能将单个组件添加到 BorderLayout
的 CENTRE
位置。如果您希望这 2 个标签在垂直中心“流动”在一起,您可能需要再嵌套一个 JPanel
。