Swing: Difference between setAlignmentX and setHorizontalAlignment in a JLabel - java

What's the difference in Swing, when using GridBagLayout, between setAlignmentX and setHorizontalAlignment, on a JLabel?

setAlignmentX is used to align a component within the container, if the layout manager supports that property.
setHorizontalAlignment aligns the text within the actual label when the size of the label is greater than its preferred size. Again it depends on the layout manager if it respects the preferred size or not.
So create a simple SSCCE and play with the two properties to see what happens. If you don't understand something then you have a SSCCE to post on the forum.

Related

Setting size on JLabel displaces other components in java

I am setting a JLabel for the error messages in my program, so initially the label is empty label.setText(""), but when there is an error it should change to something like label.setText("Error, you have entered invalid data...").
If I use setSize(x,y) on the label, it forces other components to displace when error message takes place. But using setPreferredSize(Dimension(x,y))doesn't impact them.
Q1. Why is that?
Q2. What is the difference between setSize(x,y) and setPreferredSize(Dimension(x,y))
Q3. Does it have to do anything with layout?
Thank you in advance for explanation!
P.S. I am using GridBagLayout for positioning my components on the JPanel.
Don’t use the setSize method.
setSize is called by LayoutManagers, like GridBagLayout, to lay out child components. When you call setSize explicitly, you are fighting with the GridBagLayout. Eventually, GridBagLayout will undo your setSize call, when it calls setSize for its own purposes.
In other words, any call to setSize eventually will be wiped out by the parent layout.
setPreferredSize will not be wiped out. Most LayoutManagers, including GridBagLayout, do their best to respect a component’s preferred size.
However, you should not be calling setPreferredSize. Components already have a preferred size by default, and it is almost certainly better than any numbers you can come up with. For instance, a JLabel’s default preferred size is the size which is just large enough to accommodate its text, icon, and borders.
Computing a preferred size is harder than you might think. How many pixels does text use? How many pixels high is a 12 point font? 12 points is not 12 pixels. 12 points is 12⁄72 inch. How many pixels is that? It depends on the user’s monitor and graphics resolution. All of this is known to the Swing rendering system, and JLabel uses all of that information to determine its default preferred size. You should not try to reinvent all of that work, and you should not try to replace that work with something simpler, as it will be inadequate.
If you just let the JLabel keep its preferred size, GridBagLayout will do its best to accommodate that. If the window itself does not have room to display the JLabel’s new text, you probably should call the window’s pack() method after changing the text.
Update: This appears to be an XY problem—you really want a message that you can show and hide.
You want your layout to be big enough to accommodate your message text as soon as you create it. This is typically done with a CardLayout, which lets you place several components on top of each other, with only one of them visible at any given moment. Since you want to show no text at all, initially, you would add an empty JLabel as the first component in the CardLayout, so it is shown by default:
JLabel label = new JLabel("Error, you have entered invalid data...");
CardLayout messageLayout = new CardLayout();
JPanel messagePane = new JPanel(messageLayout);
messagePane.add(new JLabel(), "blank");
messagePane.add(label, "message");
// Do not add label directly to your user interface.
// Add messagePane instead.
mainWindow.add(messagePane);
// ...
// Show message
messageLayout.show(messagePane, "message");
// ...
// Hide message
messageLayout.show(messagePane, "blank");
"message" and "blank" are never seen by the user. They are just unique identifiers for each component (“card”) in the CardLayout. You can make them anything you want.
The setSize() function sets the size not based on any LayoutManager. Thats why you should always use setPrefferedSize() when working with a LayoutManager. setPrefferedSize() firstly tries to be conform with the LayoutManagers dimensions if then possible Java tries to set the size of the Label according to your setPrefferedSize() input.
So yes, it does have anything to do with layout. If possible, you should only use setPrefferedSize() as you are working with layout managers.

Java Swing JPanel scrollpane not working? [duplicate]

Before I start, I'm aware that its a bad idea to not use a Layout Manager and usually I do use one, however, I also have all my components automatically re-size and relocate based on the size of the window. In addition the program I'm working on is only intended to run on 1 machine throughout its entire lifetime. Please don't downvote me just because of lack of layout manager, I found it to be what I need for this particular program.
To my issue, I found a similar post on stackoverflow but a solution was never achieved.
I'm adding a dynamic amount of JLabels to my JPanel, I've noticed that when not using a layout manager, the scroller doesn't work.
This is a simplified version of my initialization code.
JPanel mypanel = new JPanel();
mypanel.setLayout(null);
mypanel.setSize(800,450);
mypanel.setForeground(Color.WHITE);
mypanel.setBackground(Color.BLACK);
scrollablePanel = new JScrollPane(mypanel);
scrollablePanel.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollablePanel.setPreferredSize(new Dimension(800,300));
scrollablePanel.setSize(800,300);
scrollablePanel.setLocation(250,156);
myContainer.add(scrollablePanel);
where myContainer would be the container (also without a layout manager). The JLabels are added later on to the JPanel with:
enter code heremypanel.add(label1);
after some basic settings are set for the labels such as setForeground and setBackground.
Unfortunately when run, the scrollbar appears as if its not required (see image)
http://i.imgur.com/zp0QKGG.png
The table text seen in the image is made up of multiple JLabels.
If it's not possible to resolve the issue without using a Layout Manager I will switch to BoxLayout, I was just hoping there would be a solution.
The problem is JScrollPanel needs the preferred size of the view component to determine when the view exceeds the scroll pane's viewable area.
The preferred size of a component is normally determined via the layout manager. While you can use setPreferredSize, it is typically discouraged and you will simply run into the same problem as the content exceeds what ever value you decide to set.
A better solution would be to use a LayoutManager or compound layout (using multiple layout managers over multiple containers) to achieve the result you desired...or write your own...

Adding JScrollPane to a JPanel without a Layout Manager

Before I start, I'm aware that its a bad idea to not use a Layout Manager and usually I do use one, however, I also have all my components automatically re-size and relocate based on the size of the window. In addition the program I'm working on is only intended to run on 1 machine throughout its entire lifetime. Please don't downvote me just because of lack of layout manager, I found it to be what I need for this particular program.
To my issue, I found a similar post on stackoverflow but a solution was never achieved.
I'm adding a dynamic amount of JLabels to my JPanel, I've noticed that when not using a layout manager, the scroller doesn't work.
This is a simplified version of my initialization code.
JPanel mypanel = new JPanel();
mypanel.setLayout(null);
mypanel.setSize(800,450);
mypanel.setForeground(Color.WHITE);
mypanel.setBackground(Color.BLACK);
scrollablePanel = new JScrollPane(mypanel);
scrollablePanel.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollablePanel.setPreferredSize(new Dimension(800,300));
scrollablePanel.setSize(800,300);
scrollablePanel.setLocation(250,156);
myContainer.add(scrollablePanel);
where myContainer would be the container (also without a layout manager). The JLabels are added later on to the JPanel with:
enter code heremypanel.add(label1);
after some basic settings are set for the labels such as setForeground and setBackground.
Unfortunately when run, the scrollbar appears as if its not required (see image)
http://i.imgur.com/zp0QKGG.png
The table text seen in the image is made up of multiple JLabels.
If it's not possible to resolve the issue without using a Layout Manager I will switch to BoxLayout, I was just hoping there would be a solution.
The problem is JScrollPanel needs the preferred size of the view component to determine when the view exceeds the scroll pane's viewable area.
The preferred size of a component is normally determined via the layout manager. While you can use setPreferredSize, it is typically discouraged and you will simply run into the same problem as the content exceeds what ever value you decide to set.
A better solution would be to use a LayoutManager or compound layout (using multiple layout managers over multiple containers) to achieve the result you desired...or write your own...

Java Swing JLabel Text longer than bounds

I have a problem with Java Swing JLabel.
The text i want to display on the JLabel exceeds the bounds of the JLabel. I want to display it via a Marqueeeffect. I already implemented the effect but when there is a string that exceeds the bounds of the JLabel it gets cut off and the rest gets replaced with "...".
My question is, if there is any opportunity to set the textlength for a JLabel individually, not depending on the bounds, that it doesnt get cut off?
Hope somebody got an answer for me.
I dont use any LayoutManagers and i dont want the JLabel to get resized, it should only can contain text longer than the bounds of it.
I want to display it via a Marqueeeffect.
Check out the Marquee Panel.
In this LayoutTest, you can see how the label's UI delegate uses layoutCompoundLabel() to elide the text when label's size falls below the preferred size.
In this MarqueeTest, MarqueePanel has a default FlowLayout, which adopts the display label's preferred size.
The Swing JLabel was not designed to do marquee scrolling.
Here's the source code for JLabel. You can modify the text handling routines to do a marquee scroll rather than compressing the text with an ellipsis.
Oh, you'd better use a layout manager. Your marquee JLabel won't layout correctly without a layout manager.

Can a layout manager spawn several JPanels?

I have to build a rather large form with many controls. The controls are divided in basic controls/settings and extended controls/settings. The user can decide if he wants to see only the basic or both basic and extended controls.
I've dropped all extended controls onto their own JPanel so that I can easily switch between the two views by showing or hiding this panel.
Currently I'm using GroupLayout and what happens is that the controls on different panels are not aligned:
Label aaa: Text field
Label a: Text field
Label aaaaaa: Text field
----------------------------
Label b: Text field
Label bbb: Text field
Label bb: Text field
Unfortunatly I found now way to "synchronize" the layouts of the two panels (except using AbsoluteLayout and fixed control coordinates)
Is there any way to achive this?
Is my whole design flawed?
EDIT: If it is possible I would like to keep the GroupLayout manager.
As far as I know, no Swing LayoutManager (from JRE or open source) can span several panels.
I am currently working on such a feature (which I called "layouts synchronization") for my DesignGridLayout project, but it is not something easy to implements (I have started about 2 weeks ago and I still don't see exactly if and when I will get to something interesting, but I still have high hope for it;-))
One option you could check would be to add all components to the same panel (with just one GroupLayout then) and hide/show them based on user's selection. Hopefully, GroupLayout will adapt the size to the situation (after calling pack()).
If GroupLayout behaves well, then it would just be a matter of calling pack() each time after user changes his selection to show/hide extended fields.
Else you would have to manually set the size of your panel every time the user changes his selection.
Probably the easiest (good) way to do it is to add all the components to the main panel. Set the subpanels to non-opaque, and add the also to the main panel. The main panel the needs optimised drawing to be switched off.
Another technique is to add a spacer component. To the bottom panel add a component in the same column as the labels which dynamically takes the width component of its various size methods from the top labels. Do the same in reverse to the top panel.
I think there is no way to do it with the standard layout managers. You'll probably have to write your own layout manager, but it shouldn't be too hard if you subclass GroupLayout.
You could use GridLayout instead of GroupLayout which will give you uniform spacing between the columns
If you want to keep them in separate panels with separate layouts:
Iterate over all of the labels that you add, and find the maximum preferred width of each.
Iterate a second time, and set the preferred size to that each label's preferred height, but the maximum width.
This is the explanation of th GridLayout. This will set every component to the size, you expect it. With the GridData object you can specify how the components are ordere.
Examples
(source: sun.com)

Categories