Home > Net >  Align JLabel using SwingConstants
Align JLabel using SwingConstants

Time:07-05

Why is my JLabel text not aligned to the left or center? Is the FlowLayout the issue? Both of the texts are just appearing at the top, next to each other and I can't fix this.

Main Class

public static void main(String[] args) {
    simpleGui SG = new simpleGui();
    SG.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    SG.setSize(1000,1000);
    SG.setVisible(true);
}

Constructor class

public class simpleGui extends JFrame{
    
    private JLabel label1;
    private JLabel label2;
    
    simpleGui(){
        //title bar
        super("Simple GUI");
        setLayout(new FlowLayout());        
        label1 = new JLabel("I'm a label in the window");
        
        label1.setVerticalTextPosition(SwingConstants.BOTTOM);
        
        add(label1);
        
        
        label2 = new JLabel("Label2");
        label2.setHorizontalTextPosition(SwingConstants.LEFT);
        add(label2);
    }
}

CodePudding user response:

Refer to screen capture 1

I assume that you want label1 to appear at the bottom of the content pane and label2 to appear at the left side. Therefore I think that the default layout manager is appropriate. The default layout manager is BorderLayout.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

public class SimpleGui extends JFrame {
    private JLabel label1;
    private JLabel label2;

    public SimpleGui() {
        super("Simple GUI");
        ((JPanel) getContentPane()).setBorder(BorderFactory.createLineBorder(Color.red));
        label1 = new JLabel("I'm a label in the window", SwingConstants.CENTER);
        label1.setBorder(BorderFactory.createLineBorder(Color.cyan));
        add(label1, BorderLayout.PAGE_END); // changed

        label2 = new JLabel("Label2");
        label2.setBorder(BorderFactory.createLineBorder(Color.blue));
        add(label2, BorderLayout.LINE_START); // changed
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            SimpleGui sg = new SimpleGui();
            sg.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            sg.setSize(1000,1000);
            sg.setVisible(true);
        });
    }
}

This is how it looks when I run the above code.

screen capture 2

Note that BorderLayout gives the bottom component the same width as the content pane as well as its preferred height while the left component is given its preferred width but its height matches the height of the content pane. Refer to the tutorial I linked to at the start of this answer.

Since the width of label1 is greater than the width of the text it contains, I explicitly set the horizontal alignment of label1 to CENTER. By default it is LEFT. The alignment only affects the display when the width of the JLabel is larger than the width of its text.

I recommend that you go through the entire Creating a GUI With Swing trail in Oracle's Java tutorials.

CodePudding user response:

I've updated your code a bit, I changed the classname to include java naming conventions and I've stuck with the default BorderLayout. I think this is what you're after judging by the names of your constants.

import javax.swing.*;
import java.awt.*;
public class SimpleGui extends JFrame{
    
    private JLabel label1;
    private JLabel label2;
    
    SimpleGui(){
        //title bar
        super("Simple GUI");
        //setLayout(new FlowLayout());        
        label1 = new JLabel("I'm a label in the window");
        
        label1.setVerticalTextPosition(SwingConstants.BOTTOM);
        
        add(label1, BorderLayout.SOUTH);
        
        
        label2 = new JLabel("Label2");
        label2.setHorizontalTextPosition(SwingConstants.LEFT);
        add(label2, BorderLayout.WEST);
    }
    
    public static void main(String[] args) {
        SimpleGui SG = new SimpleGui();
        SG.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        SG.setSize(1000,1000);
        SG.setVisible(true);

    }


}

The FlowLayout is going to position things differently and you cannot just say, "you're at the top" and "you're at the left".

CodePudding user response:

What you perceive: Regardless of the calls setVerticalTextPosition() or setHorizontalTextPosition() the text is always at the same location. But your calls actually had some effect that you just did not see.

The reason is that there are two positioning algorithms at the same time:

Positioning the label within the frame You asked FlowLayout to take care. FlowLayout will simply ask the components about their preferred size, then place one besides the other just as you would expect characters or words to show up besides each other in an editor. Not that at this time each label was sized to it's preferred size.

Positioning the text within the label When the label is asked about it's preferred size, it will give the minimum size necessary to render the configured text with the configured font. This way the information can be rendered comfortably without clipping off any information.

Later, when the label is asked to render the text, it will try follow your settings setVerticalTextPosition() or setHorizontalTextPosition(). But since there is no excess space within the label, doing it left-aligned or right-aligned or top-aligned or bottom aligned all ends up at the same coordinate.

Getting out of this Either accept that the labels use their minimum size and you take care that the labels themselves are positioned correctly (GridBagLayout is very powerful in this respect), or resize the labels by setting a minimum and/or preferred size on them, then watch how your text positioning works.

The text positioning can be seen very nicely if you use BorderLayout and add the label in the center position. But this typically will work for one component only.

  • Related