中心内JPanels的JLabel(Centering JLabels inside JPanels

2019-07-18 11:20发布

我正在做一个得分保管程序,但我遇到了一个问题。 我一直试图做的是有在包含两个JPanels,这反过来,包含两个队名前一个JPanel。 我很困惑,为什么在程序的顶部的两个JLabel不是他们包含在JPanels内居中。

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) {
    }
    }
}

Answer 1:

调用pack()是在使用的布局的关键步骤。 此示例使用JLabel.CENTERGridLayout到作为帧被调整大小相等居中标签。 为简单起见,中心面板仅仅是一个占位符。 这种较为复杂例如使用沿着类似的方法java.text.MessageFormat

附录: 可是我怎么会应用 pack() 到我的代码?

简单地调用pack()如图所举的例子。 我没有看到一个简单的方法来挽救当前的外在设定大小的方法。 取而代之的是,覆盖getPreferredSize()JPanel为你的主要内容。 无论屏幕大小,你的执行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();
            }
        });
    }
}


文章来源: Centering JLabels inside JPanels