修改 JLabel 文本会改变其对齐方式

Modifying JLabel text changes its alignement

我正在尝试让一个对话框显示带有标签的进度条。我已将我的标签设置为与 JLabel.Center 居中对齐并使用框。

最初,标签显示为居中,这正是我要找的。但是,当更改标签的文本时(通过使用代码 "creatingQueriesLabel.setText(text)",标签现在显示为左对齐。

任何帮助将不胜感激!这是我的代码。

    JFrame frame = new JFrame("Creating queries ...");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Box box = Box.createVerticalBox();

    JPanel panel = new JPanel();
    panel.setLayout(null);

    creatingQueriesLabel = new JLabel("Initializing ... ");
    creatingQueriesLabel.setSize(480, 160);
    creatingQueriesLabel.setLocation(10, 10);
    creatingQueriesLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);

    box.setLocation(0, 10);
    box.setSize(480, 160);
    box.add(creatingQueriesLabel);

    progressBar = new JProgressBar();
    progressBar.setSize(480, 50);
    progressBar.setValue(0);
    progressBar.setStringPainted(true);
    progressBar.setLocation(creatingQueriesLabel.getX(),
            creatingQueriesLabel.getY() + creatingQueriesLabel.getHeight());

    panel.add(progressBar);

    frame.add(box);
    frame.add(panel);

    // Display the window.
    frame.pack();
    frame.setSize(520, 280);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

/**
 * Invoked when task's progress property changes.
 */
public void propertyChange(PropertyChangeEvent evt)
{
    if ("progress" == evt.getPropertyName())
    {
        int progress = (Integer) evt.getNewValue();
        progressBar.setValue(progress);
    }
    if ("currentQueryText" == evt.getPropertyName())
    {
        String text = (String) evt.getNewValue();
        creatingQueriesLabel.setText(text);
    }
}

问题:

  • 您正在使用绝对定位来设置大小和位置——不要这样做,因为这不是 Swing 的工作方式,这将导致 GUI 很难维护和增强,正如您所发现的。
  • 在构建 JLabel 时使用 SwingConstants.CENTER 整数,使其文本居中
  • 将其添加到使用 BorderLayout 的容器中,可能在 BorderLayout.PAGE_START 位置。
  • 不相关的问题 -- 不要这样做:if ("currentQueryText" == evt.getPropertyName()) {。这将测试引用相等性,这不是您想要测试的。请改用 equals 方法。
  • 这个 GUI 看起来应该是一个对话框 window,一个临时的 window 显示主父 window 中未显示的信息(JFrame window ),所以它应该显示在 JDialog 中,而不是 JFrame 中。

例如:

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

@SuppressWarnings("serial")
public class CreatingSpeciesPanel extends JPanel {
    public static final String INITIALIZING = "Initializing...";
    public static final String DONE = "DONE!";
    private static final int PREF_W = 480;
    private static final int PREF_H = 150;
    private static final int GAP = 20;
    private static final float TITLE_SIZE = 24f;

    private JLabel title = new JLabel(INITIALIZING, SwingConstants.CENTER);
    private JProgressBar progressBar = new JProgressBar();

    public CreatingSpeciesPanel() {
        title.setFont(title.getFont().deriveFont(Font.BOLD, TITLE_SIZE));
        progressBar.setValue(0);
        progressBar.setStringPainted(true);

        JPanel centerPanel = new JPanel(new BorderLayout());
        centerPanel.add(progressBar, BorderLayout.PAGE_END);

        setLayout(new BorderLayout());
        setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
        add(title, BorderLayout.PAGE_START);
        add(centerPanel, BorderLayout.CENTER);

    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    public void setValue(int value) {
        progressBar.setValue(value);
    }

    public void setTitleLabelText(String text) {
        title.setText(text);
    }

    private static void createAndShowGui() {
        final CreatingSpeciesPanel creatingSpeciesPanel = new CreatingSpeciesPanel();
        final JFrame mainFrame = new JFrame("Main Frame");

        JButton createSpeciesBtn = new JButton(new AbstractAction("Create Species") {

            @Override
            public void actionPerformed(ActionEvent e) {
                creatingSpeciesPanel.setTitleLabelText(CreatingSpeciesPanel.INITIALIZING);
                final JDialog dialog = new JDialog(mainFrame, "Creating Species", ModalityType.APPLICATION_MODAL);
                dialog.add(creatingSpeciesPanel);
                dialog.pack();
                dialog.setLocationRelativeTo(mainFrame);

                new Timer(200, new ActionListener() {
                    private int doneCount = 0;
                    private int value = 0;
                    private static final int MAX_DONE_COUNT = 10;

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (value < 100) {

                            value += (int) Math.random() * 5 + 5;
                            value = Math.min(100, value);

                            creatingSpeciesPanel.setValue(value);
                            if (value == 100) {
                                creatingSpeciesPanel.setTitleLabelText(CreatingSpeciesPanel.DONE);
                            }
                        } else {
                            // let's display the dialog for 2 more seconds
                            doneCount++;
                            if (doneCount >= MAX_DONE_COUNT) {
                                ((Timer) e.getSource()).stop();
                                dialog.setVisible(false);
                            }
                        }
                    }
                }).start();

                dialog.setVisible(true);
            }
        });

        JPanel panel = new JPanel();
        panel.add(createSpeciesBtn);
        panel.setPreferredSize(new Dimension(500, 400));

        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.getContentPane().add(panel);
        mainFrame.pack();
        mainFrame.setLocationRelativeTo(null);
        mainFrame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}