krakatoa
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.
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.
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
ASKER
Ok thanks. I will post it soon.
ASKER
.
.
.
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);
.
.
.
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();
}
}
}
ASKER
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, . . .?
ASKER
The only way I can approach getting near to what I require, is to do something extremely poor and hacky like :
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 ?
msgwindow.add(new JLabel(" "), BorderLayout.WEST);
msgwindow.add(warning, BorderLayout.CENTER);
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
ASKER
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,Swin
instead of using your : msgwindow.add(warning,Bord
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.
ASKER
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);
}
(width changed to make centering more obvious)
ASKER
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 windowNo - 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
ASKER
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.
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
ASKER
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
But there are other ways if BorderLayout offends you - using other layout managers or writing your own
ASKER
if BorderLayout offends youGrinning, no.
I'll code something, and post it back here for hows and whys.
ASKER
Indeed it is.
And this is why there could apparently be something much odder going on. Because :
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).
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
.
.
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.CEN TER);
JLabel warning = new JLabel("Insufficient proximity factor",SwingConstants.CEN
ASKER
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?
ASKER
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.
ASKER
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.setHorizontalAlign ment(Swing Constants. CENTER);
instead of
warning.setHorizontalTextP osition(Sw ingConstan ts.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)
warning.setHorizontalAlign
instead of
warning.setHorizontalTextP
public void setHorizontalAlignment(int
Sets the alignment of the label's contents along the X axis.
public void setHorizontalTextPosition(
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>
ASKER
@ 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.
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.
ASKER
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>",SwingCon stants.CEN TER);
JLabel warning = new JLabel("<html>Text length is too short.</html>",SwingConsta nts.CENTER );
Executing the top line of code produces this :
Whilst (and with no other changes to any surrounding code or parameters at all) the second line executes as :
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>",SwingCon
JLabel warning = new JLabel("<html>Text length is too short.</html>",SwingConsta
Executing the top line of code produces this :
Whilst (and with no other changes to any surrounding code or parameters at all) the second line executes as :
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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.
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
ASKER
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.
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.
ASKER
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)
ASKER
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
ASKER
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.setHorizontalAlig
... 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>
ASKER
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
ASKER
(You'll (obviously) need to toggle between running the two lines with the different length texts - "Short Text", and "Long Text" lines).
N.B. :
The inclusion of this line :
makes no difference at all on the positioning.
//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 "
N.B. :
The inclusion of this line :
warning.setHorizontalTextPosition(SwingConstants.CENTER);
makes no difference at all on the positioning.
ASKER
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.
ASKER
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.
; )
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.
; )
Open in new window