将JLabel置于JPanels中心

时间:2013-01-20 05:09:11

标签: java swing layout layout-manager gridbaglayout

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

enter image description here

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

1 个答案:

答案 0 :(得分:7)

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

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

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

image

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