I have a frame with a border layout that includes a panel with a border layout at its center that has a label in its center that presents images.
Another thread is accessing that label to portray images that can be seen as a video - this works.
However, the frame itself is sized this way every time:
https://prnt.sc/116grry
I have to resize it manually to show the image every time I run the program.
SetPreferredSize doesn't change or do anything to achieve what I want.
The code:
https://gist.github.com/IshayKom/d06f40980fe42f96e28acdf1422b9e4f
Is there any way to initiate the frame at a specific size before it gets the images?
You might be looking for .setMinimumSize instead. setPreferredSize does not provide constraints and can thus be changed by other components such as the container that is used to show the image.
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.
let's say I want to do a program like photoshop or lightroom in java where I work with one image on the left side and I have a menu on the right side with all the options. How could I set the size of the panel where the menu is contained to scale correctly with multiple resolutions?
I was thinking on getting the current system resolution of the system (getScreenResolution()) and then multiply it by some factor like 0.3-0.2 and set that as width but I'm not sure if that works properly with higher resolutions or you would loose too much working space in the menu (I just have a small laptop to try).
I wasn't able to find any question like this, or something easier to work with the dpi in android.
I work with one image on the left side and I have a menu on the right side with all the options.
Just use a proper layout manager and let the layout manager do its job.
For example you can use a BorderLayout.
Create a panel for your menus and add that panel to the BorderLayout.LINE_END and the panel will be displayed at its preferred size.
Then create a second panel for the image and add that panel to the BorderLayout.CENTER. Now this panel will automatically be resized to fill the space as the frame is resized.
I have a resizable JFrame and (since I do not know much about Layouts yet) set its JPanel Layout to null.
Is there a way I can tell my program to resize each of its components' size relative to the window's size?
e.g. I have a 200x100 default sized JFrame, on which a button is 20x10. If I resize the window to 400x200, I want the button to be (still on the same position relative to the window's edges) resized to 40x20.
If that works is there a way to do the same thing with fonts? E.g. size 11 on 200x100 but something like size 14 on 400x200.
Regardless of what convention you use to scale your components and font, it is not a good idea to set a layout to null. Widgets behaving strangely when using "setlayout(null)" will give insight to why this is error prone. Automatically size JPanel inside JFrame might help with scaling when you change the size of the JFrame manually.
Add a ComponentListener to your frame and create a table with the defaultSizes of the Components for a specific windowsize. The componentResized(ComponentEvent e) will be called each time the window is resized. Inside it, you can resize the components. Or you implement your own LayoutManager.
I have a JTextPane with HTML text.
I used GroupLayout (using WindowBuilder).
I've set the minimum size of my JFrame to 800x600 so the user cannot make it smaller than that.
The app has a big scrolling JPanel the size of the entire window. The top part of the panel is taken up by a JTextPane wrapped in JScrollPane. I have disabled the scroll bars and sized the JScrollPane to make the entire text visible.
In group layout the JScrollPane is set to stay constant vertically, but size horizontally.
My issue is that when the user makes the window larger the JScrollPane also expands, but now there is a big white space left at the bottom of the text pane. Is there a way that I can make JTextPane shrink to fit its contents.
Also if you suggest a different layout, I would be willing to try it.
I used this TextPanePerfectSize example from #camickr to solve a similar problem. The example uses validate() and pack() to adjust to the preferred size. You might be able to adapt it to your situation.
Take a look at SpringLayout. It gives you far more control over the positioning of components. Look at the SpringLayout tutorial if you get stuck.
The trick in your case is to bind the bottom (south) of your JScrollPane to the top (north) of the screen.
I'm using a JPanel containing a JLabel with an icon. I'm using a ComponentAdapter on the JLabel to request a correctly sized thumbnail from the controller (using MVC pattern) when the JLabel is resized. This works fine when the JLabel is resized to be bigger than before, so then it's filled with an ImageIcon the size of the JLabel. However, when resizing the window to be smaller, it simply doesn't resize the JLabel at all (because of the icon's size, I'm assuming).
Is there possibly some layout manager or setting to make the JLabel disregard its content (the ImageIcon) and resize itself anyways? I mean, it can truncate text, so it ought to be able to just show part of the image when resized smaller.
Try experimenting with setPreferredSize() and setMinimumSize() to ensure the JLabel is allowing itself to shrink to the required size. You also need to double-check what kind of LayoutManager you are using and what constraints, if any, you use when adding your component to the panel. Try a different layout manager if you can. If none of that works, you will need to provide some example code.