Centering JLabels inside JPanels

眉间皱痕 提交于 2019-12-04 04:23:38

问题


I'm making a score-keeping program, but I'm running into a problem. What I've tried to do is have a JPanel at the top that contains two JPanels, which, in turn, contains two team names. I'm confused as to why the two JLabels at the top of the program aren't centered inside of the JPanels they're contained in.

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:


Invoking pack() is a critical step in using layouts. This example uses JLabel.CENTER and GridLayout to center the labels equally as the frame is resized. For simplicity, the center panel is simply a placeholder. This somewhat more complex example uses a similar approach along with java.text.MessageFormat.

Addendum: But how would I apply pack() to my code?

Simply invoke pack() as shown in the examples cited. I don't see an easy way to salvage your current approach of setting sizes extrinsically. Instead, override getPreferredSize() in a JPanel for your main content. No matter the screen size, your implementation of paintComponent() should adapt to the current size, for example.

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


来源:https://stackoverflow.com/questions/14421855/centering-jlabels-inside-jpanels

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!