将JLabel置于JPanels中心

我正在制作一个记分计划,但我遇到了一个问题。 我试图做的是在顶部有一个包含两个JPanel的JPanel,而JPanel又包含两个团队名称。 我很困惑为什么程序顶部的两个JLabel没有集中在它们所包含的JPanel中。

在此处输入图像描述

import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ScoreFrame extends JFrame { private static final Dimension SCREEN_SIZE = Toolkit.getDefaultToolkit().getScreenSize(); private static final int WIDTH = SCREEN_SIZE.width; private static final int HEIGHT = SCREEN_SIZE.height; private final JTextField[] nameField = new JTextField[] { new JTextField(), new JTextField() }; private final JLabel[] nameLabel = new JLabel[] { new JLabel("Team 1"), new JLabel("Team 2") }; private final GridBagLayout gridBag = new GridBagLayout(); private final GridBagConstraints constraints = new GridBagConstraints(); private final JPanel topPanel = new JPanel(); public ScoreFrame() { super(); setResizable(false); setSize(SCREEN_SIZE); setLayout(gridBag); setUndecorated(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); addKeyListener(new EscapeListener()); addComponents(); } private void addComponents() { addToTopPanel(); constraints.insets = new Insets(0, 0, (int) (HEIGHT * (double) 4 / 5), 0); gridBag.setConstraints(topPanel, constraints); add(topPanel); } private void addToTopPanel() { final JPanel[] teamPanel = new JPanel[] { new JPanel(), new JPanel() }; topPanel.setLayout(gridBag); topPanel.setSize(new Dimension(WIDTH, HEIGHT / 5)); Dimension teamPanelSize = new Dimension(WIDTH / 2, HEIGHT / 5); teamPanel[0].setSize(teamPanelSize); teamPanel[1].setSize(teamPanelSize); Font nameFont = new Font("Times New Roman", Font.PLAIN, 50); nameLabel[0].setFont(nameFont); nameLabel[1].setFont(nameFont); teamPanel[0].add(nameLabel[0]); teamPanel[1].add(nameLabel[1]); gridBag.setConstraints(teamPanel[0], constraints); constraints.gridx = 1; gridBag.setConstraints(teamPanel[1], constraints); topPanel.add(teamPanel[0]); topPanel.add(teamPanel[1]); } public void paint(Graphics g) { super.paint(g); int strokeSize = ((WIDTH + HEIGHT) / 2) / 300; if (strokeSize < 1) { strokeSize = 1; } final int fontSize = (int) (strokeSize * 12.5); Graphics2D g2d = (Graphics2D) g; g2d.setStroke(new BasicStroke(strokeSize)); g.drawLine(WIDTH / 2, 0, WIDTH / 2, HEIGHT / 5); g.drawLine(WIDTH / 2, (int) (HEIGHT * (double) 105 / 400), WIDTH / 2, HEIGHT); g.drawLine(0, HEIGHT / 5, WIDTH, HEIGHT / 5); g.drawRect((int) (WIDTH * (double) 45 / 100), HEIGHT / 5, WIDTH / 10, (int) (HEIGHT * (double) 3 / 20)); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g.setFont(new Font("Times New Roman", Font.PLAIN, fontSize)); g.drawString("Errors", (int) (WIDTH * (double) 101 / 220), HEIGHT / 4); } private JFrame getFrame() { return this; } public static void main(final String args[]) { new ScoreFrame().setVisible(true); } public class EscapeListener implements KeyListener { public void keyPressed(final KeyEvent event) { if (event.getKeyCode() == 27) { final int choice = JOptionPane.showConfirmDialog(getFrame(), "Do you want to exit the program?"); if (choice == 0) { System.exit(0); } } } public void keyReleased(final KeyEvent event) { } public void keyTyped(final KeyEvent event) { } } } 

调用pack()是使用布局的关键步骤。 此示例使用JLabel.CENTERGridLayout在调整框架大小时使标签居中。 为简单起见,中心面板只是一个占位符。 这个稍微复杂的示例使用了与java.text.MessageFormat类似的方法。

附录: 但我如何将 pack() 应用于我的代码?

只需调用pack() ,如引用的示例所示。 我没有看到一种简单的方法来挽救你当前设定尺寸的方法。 相反,在JPanel覆盖主内容的getPreferredSize() 。 无论屏幕大小如何, paintComponent()实现都应该适应当前的大小。

图片

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.GridLayout; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; /** @see https://stackoverflow.com/a/14422016/230513 */ public class Scores { private final JLabel[] nameLabel = new JLabel[]{ new JLabel("Team 1", JLabel.CENTER), new JLabel("Team 2", JLabel.CENTER)}; private void display() { JFrame f = new JFrame("Scores"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel teamPanel = new JPanel(new GridLayout(1, 0)); teamPanel.add(nameLabel[0]); teamPanel.add(nameLabel[1]); f.add(teamPanel, BorderLayout.NORTH); f.add(new JPanel() { @Override public Dimension getPreferredSize() { return new Dimension(320, 240); } }, BorderLayout.CENTER); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new Scores().display(); } }); } }