Link to home
Start Free TrialLog in
Avatar of krakatoa
krakatoaFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Placement of JLabel in a Window.

I'm using a Java Window and adding() a JLabel to it - the only component.

A Window's default Layout is BorderLayout, and I have placed the JLabel at BorderLayout.CENTER.

However, the JLabel text seems to be left-aligned, right on the left edge of the Window. I want it in the centre, so what would I need to do?

Thanks k.
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

container.add(new JLabel("I'M A CENTRIST!", SwingConstants.CENTER));

Open in new window

Avatar of krakatoa

ASKER

Yes, I’m actually using that, but it’s not effective apparently.
In that case there's probably something else interfering with the movement of the label. Would need to see code
Ok thanks. I will post it soon.
.
.
.

JLabel warning = new JLabel("Insufficient proximity factor");
                        warning.setForeground(Color.WHITE);
                        warning.setHorizontalTextPosition(SwingConstants.CENTER);
                        
                        msgwindow = new Window(frame);               
                    
                        msgwindow.setSize(new Dimension(200,80));
                        msgwindow.setLocation(frame.getX()+(frame.getWidth()/2),((frame.getHeight())/2)-50);
                        msgwindow.setBackground(new Color(200,55,15));
                        msgwindow.setOpacity(1.0f);
                    
                        msgwindow.add(warning,SwingConstants.CENTER);
                        msgwindow.setVisible(true);
.
.
.

Open in new window

Your code works for me:

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;


public class FB extends JFrame implements ActionListener {
    private JButton b;

    public void actionPerformed(java.awt.event.ActionEvent e) {
        // Do it
        JFrame frame = FB.this;
        JLabel warning = new JLabel("Insufficient proximity factor");
        warning.setForeground(Color.WHITE);
        warning.setHorizontalTextPosition(SwingConstants.CENTER);

        Window msgwindow = new Window(frame);

        msgwindow.setSize(new Dimension(200, 80));
        msgwindow.setLocation(frame.getX() + (frame.getWidth() / 2), ((frame.getHeight()) / 2) - 50);
        msgwindow.setBackground(new Color(200, 55, 15));
        msgwindow.setOpacity(1.0f);

        msgwindow.add(warning, BorderLayout.CENTER);
        msgwindow.setVisible(true);
    }

    private void setGui() {
        try {
            setLocation(0, 100);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            Container cp = getContentPane();
            JPanel bPanel = new JPanel();
            b = new JButton("Click");
            b.addActionListener(this);
            bPanel.add(b);
            cp.add(bPanel, BorderLayout.SOUTH);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    FB f = new FB();
                    f.setGui();
                    f.setSize(200, 200);
                    f.setVisible(true);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Open in new window

Ah, well maybe I'm barking up a tree that's not there, but the JLabel's text is still left-aligned when running in your code. It's in exactly the same place as in my case. Am I possibly misinterpreting the meaning of Borderayout.CENTER or SwingConstants. CENTER? Visually, I don't see how I can be, . . .?
The only way I can approach getting near to what I require, is to do something extremely poor and hacky like :

msgwindow.add(new JLabel("        "), BorderLayout.WEST);
        msgwindow.add(warning, BorderLayout.CENTER);

Open in new window


Is there really no way to make use of WEST or some alignment method instead of such a hack ? Or would I need to move to another Layout manager ?
Ah, well maybe I'm barking up a tree that's not there, but the JLabel's text is still left-aligned when running in your code.
Oops. Insufficient observation - it's not centred.

OTOH, your code does not use what i posted. You'll find the problem disappears when it does
your code does not use what i posted. You'll find the problem disappears when it does

If you are talking about this :

msgwindow.add(warning,SwingConstants.CENTER);

instead of using your : msgwindow.add(warning,BorderLayout.CENTER);

the problem does not disappear . . . they produce exactly the same result - left aligned. I tried both approaches before posting the question. As my opening post states, Window uses BorderLayout by default, so I tried that first - with both a default non-call therefore, as well as the explicit call.

What my code does not use nor need is the use of BorderLayout.SOUTH, which you have included in yours for some reason.

In short, the question has not moved on despite all above attempts.
I'm going to try the BorderLayout explicit call with the 2-arg constructor.
If you are talking about this :
Nope. About the very first code i posted
    public void actionPerformed(java.awt.event.ActionEvent e) {
        // Do it
        JFrame frame = FB.this;
        JLabel warning = new JLabel("Insufficient proximity factor", SwingConstants.CENTER);
        warning.setForeground(Color.WHITE);

        Window msgwindow = new Window(frame);
        msgwindow.setLayout(new BorderLayout());
        

        msgwindow.setSize(new Dimension(300, 80));
        msgwindow.setLocation(frame.getX() + (frame.getWidth() / 2), ((frame.getHeight()) / 2) - 50);
        msgwindow.setBackground(new Color(200, 55, 15));
        msgwindow.setOpacity(1.0f);

        msgwindow.add(warning, BorderLayout.CENTER);
        msgwindow.setVisible(true);
    }

Open in new window

(width changed to make centering more obvious)
The placement therefore perilously depends on a more-or-less forced / artificial widening of the window, implying that the layout manager is unable to implement scaled presentation of the available areas when it’s below a certain threshhold.
The placement therefore perilously depends on a more-or-less forced / artificial widening of the window
No - not really. I just widened it to show you it's obviously centered. If you use your width of 200, it's still perfectly centered, but your margin is quite small so centering is not so obvious. That's a consequence not of the layout manager getting things wrong but of the extra measurement work required when making your own popups
There are manifold philosophical not to mention practical reasons why that behaviour is uncomfortable to me. For instance, why have any layout at all if the absence of the use of one of the layout's areas impacts the use of another? Compass points effectively have a quadrant each to themselves for example - West doesn't shrink to satisfy North South or East. So why pretend to have a CENTER if it actually means purloining WEST if not used? Excel has the idea much better, inasmuch as cells in columns will have their readable content visually displayed across cells to the right, and then only visually truncated (if the existing column with is not sufficient) should a cell in a column to the right be occupied. Only when the column containing the text is widened will the full text be visible, but crucially  that doesn't mean the adjacent columns shrink to let that happen. In the case of Excel, a single space can be entered into the cell to the right of the one with overspill width text,  if you wish to visually truncate that spilling text. But the cell (column) to the left of the text cell does not have to give way under either condition.
What we have with BorderLayout is an implementational / technical confection of idiosyncratic nature, which fulfils only a nominally practical role, since a real-world use case (as in my code example) makes no attempt to allocate any space to WEST that is proportional to its billing. Why should WEST be disadvantaged by CENTER simply because CENTER has payload? CENTER's content ought to be truncated, or the Window have resizeable functionality built in. The fact that it doesn't and that a 'manual' resize() has to be applied is a poor excuse for a default layout. So whilst I'm sure you are correct technically (i.e. that's the implementation they decided on), in the real world it's a misleading and thus coding-timewasting angle to have chosen.

Anyway, the answer is that there is no direct way of doing this in a straight BorderLayout. There will have to be another container inside it with the widget in that.
I don't know, but the way BorderLayout works seems to me to be eminently simple and predictable, and thus labour-saving. Of course, you're free to implement your own layout manager that does exactly what you want
Of course, you're free to implement your own layout manager that does exactly what you want

Sort of obiter dictum in the layout management field.
Well, there's no actual problem here: you want to centre a label in the context of the container having BorderLayout. It's a one line (ctor) solution
But there are other ways if BorderLayout offends you - using other layout managers or writing your own
if BorderLayout offends you
Grinning, no.

I'll code something, and post it back here for hows and whys.
Meantime, this is what happens with your code and my first comment's code combined: perfectly centred

User generated image
Indeed it is.
And this is why there could apparently be something much odder going on. Because :

.
.
.
JLabel warning = new JLabel("<html>Text length is.</html>"); // 0th
.
.
.
//msgwindow.add(new JLabel("<html>Text length is.</html>", SwingConstants.CENTER));  // 1st
msgwindow.add(warning,SwingConstants.CENTER);   //2nd
.
.

Open in new window

If the 1st option is used, the alignment matches your assertions, meaning centered. If the 2nd option above is used, then there is no centre alignment - it's all pushed or starts, left.

So there must be something going on that does not meet the eye.

(I know the <html> formatting wasn't there before, but this has no impact on the issue in question).
I don't really understand. The issue is solved by the means i mentioned above. So how can there still be a problem?
Try this

JLabel warning = new JLabel("Insufficient proximity factor",SwingConstants.CENTER);
Try this

What makes you think that will be helpful, and what makes you think it is any different to anything else that's already been suggested used or mentioned above?
I don't really understand. The issue is solved by the means i mentioned above. So how can there still be a problem?

There's no getting away from the fact that the two lines of code I quoted in my last quote inclusive post, vary in the way they lay out the label. Maybe there is an issue with the OS - Win v Unix ?

The comment from Jalpa Kotak, which I was skeptical about, as everyone may have gathered, actually works.
BUT  Jalpa Kotak's solution does not work when the text is longer, and that's the real issue. The text gets wrapped by the JLabel and both lines are left-aligned. Or rather the window 'left-aligns' the JLabel, seemingly putting it in WEST.
use
warning.setHorizontalAlignment(SwingConstants.CENTER);
instead of
warning.setHorizontalTextPosition(SwingConstants.CENTER);

public void setHorizontalAlignment(int alignment)
Sets the alignment of the label's contents along the X axis.

public void setHorizontalTextPosition(int textPosition)
Sets the horizontal position of the label's text, relative to its image.(And there is no image)
BUT  Jalpa Kotak's solution ...

That would be .. err .. exactly what i posted as the very first comment?
If you're using html as well, that could have side effects

You could try (deprecated but should work)
<center>The text</center>

Open in new window

@ CEHJ and JK -

none of the suggestions has any effect on the positioning.

I think I'm going to close / delete this question and start a new one tomorrow. I'll have the exact lines of code that I want examined, and the length of the text required for display in the JLabel will have to be used exclusively in the discussion to get the scenario to make real world sense. Can't post now, batteries too low.
It is possibly better to see if this issue can be resolved still in this question, despite its degenerate position.

So can I focus on what happens concerning these two lines of code  (obviously one has to be commented out by turns) :

JLabel warning = new JLabel("<html>Text length is too short for the number of keywords.</html>",SwingConstants.CENTER);
JLabel warning = new JLabel("<html>Text length is too short.</html>",SwingConstants.CENTER);

Executing the top line of code produces this :
User generated image
Whilst (and with no other changes to any surrounding code or parameters at all) the second line executes as :

User generated image
ASKER CERTIFIED SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Right, well first of some apology - but it was a case of total snowblindness, after hours of coding here.

So CEHJ, your assertions work and are correct.

Thanks.
I'm not absolved of blame. I notice with astonishment that my first complete runnable doesn't incorporate my own suggestions
Lol.

Well, I think YOU know from some of my past posts in previouses, how bag-on-the-headed I can be sometimes. ; )

Great tenacity there CEHJ, thanks again.
I don't want to "resuffer" what we've just been through, but iianm and iiancrazy, my post of the previous two lines still doesn't make much sense . . . . anyway maybe that's for another time . . . my head's fizzing. ; 0)
Actually, it seems to be / is, the HTML <center></center> tags that make the difference. Without these, I'm back to square 0 - al least with the longer text of the two. Hmm.
Actually, it seems to be / is, the HTML <center></center> tags that make the difference.
Indeed it is. So you need to keep that if you want every line centred
So you need to keep that if you want every line centred

Right.

The yet more peculiar behaviour is that neither the SwingConstants.CENTER for the JLabel's text placement, nor BorderLayout.CENTER for the window's placement in it of the JLabel, are required. Simply using the HTML <center> tags in the JLabel is sufficient. Most intriguing. Not to say odd.

Actually, it's even nastier than that : leaving out a "warning.setHorizontalAlignment(SwingConstants.CENTER);" from the longer text has no bad effect on the alignment, but not having that statement for a shorter text throws the alignment.again. Perplexing at the very least.
... but not having that statement for a shorter text throws the alignment.again.
I find that hard to believe - if you're still using <center>
Well, I couldn’t believe it either, but it is happening. I can’t see any fundamental blunders of perception omp this time, and I think it warrants further investigation.
OK. Again, please post code that could be pasted into lines 11-25 of my first long runnable code
(You'll (obviously) need to toggle between running the two lines with the different length texts - "Short Text", and "Long Text" lines).


//New "Lines 11 - 25 "
        
        JFrame frame = FBB.this; // I already have a class called FB and don't want to have to look at that now, so sorry I renamed your class.
        JLabel warning = new JLabel("<html><center>Insufficient Proximity Factor.</center></html>"); // Short Text
        //JLabel warning = new JLabel("<html><center>Text length is too short for the number of keywords.</center></html>"); // Long Text
        warning.setForeground(Color.WHITE);
        warning.setHorizontalTextPosition(SwingConstants.CENTER);
        Window msgwindow = new Window(frame);

        msgwindow.setSize(new Dimension(200, 80));
        msgwindow.setLocation(frame.getX() + (frame.getWidth() / 2), ((frame.getHeight()) / 2) - 50);
        msgwindow.setBackground(new Color(200, 55, 15));
        msgwindow.setOpacity(1.0f);
        
        msgwindow.add(warning);
        msgwindow.setVisible(true);
        
        //End New "Lines 11 - 25 "

Open in new window




N.B. :

The inclusion of this line :
warning.setHorizontalTextPosition(SwingConstants.CENTER);

Open in new window


makes no difference at all on the positioning.
Either perfectly centred:

User generated imageUser generated image
Not on my system. I keep testing it, and the shorter text never aligns as in your example. And assuming you've used the code I posted as is, then that's inexplicable to me.
Hold on . . . I've got another oops.

Let's leave this, as per your solution. There is another call to the window later, and I fear that MIGHT be affecting things. But I've run out of road on this one for now, as I've got the correct behaviour in place now for both window incarnations.

; )