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.
Related
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.
Is there any property or any code that I can implement to make an icon inside a JLabel resizable. Or is there any other item which can store an image, that I could use to have a resizable image inside a JFrame?
use this code :
photo = new ImageIcon(UrlofPhoto);
Image im = photo.getImage();
Image Newim = im.getScaledInstance(yourlabel.getWidth(), yourlabel.getHeight(),Image.SCALE_SMOOTH);
ImageIcon Newphoto=new ImageIcon(Newim);
yourlabel.setIcon(Newphoto);
don't forget to set an initialised size to yourlabel
Generally, I would't suggest trying this with a JLabel as JLabel has a lot of other features you really don't want to messing with (alignment and text).
Generally, a better solution is to use a dedicated "image" panel, which you can provide additional control over to fine tune how you want the scaling to work.
For example
If you're really stuck on using JLabel, I would recommend attaching a ComponentListener to it and resizing the underlying image when ever it changes size. The problem with this is componentResized may be called repeatedly in quick succession, meaning you will need to devise some kind of coalescing algorithm that only reacts to the last event within a given period of time...
Check out Darryl's Stretch Icon which will dynamically scale the icon to fill the label.
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.
I'm trying to make a marquee like effect in my program, the text is determined by the content of a file which will result a dynamic lenght/width for JLabel, and the problems are:
I use drag n drop and GroupLayout since it will auto resize the component, but it doesn't allow me to use setBounds nor the setLocation method.
I tried to change it to null layout, yes I can use the setBounds or the setLocation, and now the problem is that the JLabel cannot auto resize its width to fit the text length.
My marquee text would goes from right to the left screen, and will do the run 2 times.
Any suggestion here? Thanks :)
I want my JTextArea to resize itself (expand vertically) when the last line (that the text area's height can offer) is reached and the user wants to start a new line. You know, like the textbox in MSWord.
I have an idea to use getLineCount() and determine (if necessary) the new height of the JTextArea. Do you have, or know of better approaches for implementing this?
Actually, the JTextArea always has the correct size so all lines of text are visible. What you experience is probably that you wrapped the text area in a JScrollPane. Just omit the scroll pane and make the text area a direct child of the container.
Another solution is to listen to resize events of the text area and size the scroll pane accordingly. This way, you can grow to a certain size and then start to display scroll bars (for example, when someone pastes 500KB of text into the text area).
I had the same problem. From my tests, I do not believe that the JTextArea sets its size dynamically. Instead, its size seems to be limited by its container (a JPanel in my case). However, the JTextArea does change its preferred size based on the text it contains. From the documentation:
java.awt.TextArea has two properties rows and columns that are used to determine the preferred size. JTextArea uses these properties to indicate the preferred size of the viewport when placed inside a JScrollPane to match the functionality provided by java.awt.TextArea. JTextArea has a preferred size of what is needed to display all of the text, so that it functions properly inside of a JScrollPane. If the value for rows or columns is equal to zero, the preferred size along that axis is used for the viewport preferred size along the same axis.
Go to JTextArea "Properties" - checklist "lineWrap".
I had the same problem,I put the JTextArea into a JScrollPane and set the preferred size of JTextArea, and I believe that's the cause of the problem.
So the right solution is to put the JTextArea into a JScrollPane, and don't touch the preferred size of JTextArea, set JScrollPane's instead.