Search code examples
javaswingalignmentjlabel

Modifying JLabel text changes its alignement


I am trying to have a dialog showing a progress bar with a label. I have set my label to be center aligned with JLabel.Center and the use of a box.

Initially, the label is shown as centered, which is what I am looking for. However, when changing the label's text (by using the code "creatingQueriesLabel.setText(text)", the label is now displayed as left aligned.

Any help will be greatly appreciated! Here is my code.

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

Solution

  • Problems:

    • You're setting sizes and positions using absolute positioning -- don't as that's not how Swing works and this will lead to GUI's that are very hard to maintain and enhance, as you're finding out.
    • Use the SwingConstants.CENTER int when constructing the JLabel so that its text is centered
    • Add it to a container that uses BorderLayout, probably in the BorderLayout.PAGE_START position.
    • Unrelated problem -- don't do this: if ("currentQueryText" == evt.getPropertyName()) {. This tests for reference equality which is not what you want to test for. Use the equals method instead.
    • This GUI looks like it should be a dialog window, a temporary window that is displaying information not shown in the main parent window (the JFrame window), and so it should be displayed in a JDialog, not a JFrame.

    For example:

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