Java: Difference between the setPreferredSize() and setSize() methods in components - java

What is the main difference between setSize() and setPreferredSize(). Sometimes I used setSize(), sometimes setPreferredSize(), sometimes one does what I want, sometimes the other.
What call should I use for JFrames and JPanels?

Usage depends on whether the component's parent has a layout manager or not.
setSize() -- use when a parent layout manager does not exist;
setPreferredSize() (also its related setMinimumSize and setMaximumSize) -- use when a parent layout manager exists.
The setSize() method probably won't do anything if the component's parent is using a layout manager; the places this will typically have an effect would be on top-level components (JFrames and JWindows) and things that are inside of scrolled panes. You also must call setSize() if you've got components inside a parent without a layout manager.
Generally, setPreferredSize() will lay out the components as expected if a layout manager is present; most layout managers work by getting the preferred (as well as minimum and maximum) sizes of their components, then using setSize() and setLocation() to position those components according to the layout's rules.
For example, a BorderLayout tries to make the bounds of its "north" region equal to the preferred size of its north component---they may end up larger or smaller than that, depending on the size of the JFrame, the size of the other components in the layout, and so on.

setSize() or setBounds() can be used when no layout manager is being used.
However, if you are using a layout manager you can provide hints to the layout manager using the setXXXSize() methods like setPreferredSize() and setMinimumSize() etc.
And be sure that the component's container uses a layout manager that respects the requested size. The FlowLayout, GridBagLayout, and SpringLayout managers use the component's preferred size (the latter two depending on the constraints you set), but BorderLayout and GridLayout usually don't.If you specify new size hints for a component that's already visible, you need to invoke the revalidate method on it to make sure that its containment hierarchy is laid out again. Then invoke the repaint method.

setSize will resize the component to the specified size.
setPreferredSize sets the preferred size. The component may not actually be this size depending on the size of the container it's in, or if the user re-sized the component manually.

IIRC ...
setSize sets the size of the component.
setPreferredSize sets the preferred size.
The Layoutmanager will try to arrange that much space for your component.
It depends on whether you're using a layout manager or not ...

In addition to the fact that setSize() should be used in the absence of a layout manager, and setPreferredSize() - when there is no layout manager, there is another difference. 1 takes two numbers in the parameters, and setPreferredSize() takes an object of class java.awt.Dimension:
JFrame frame = new JFrame("Test");
frame.setSize(200,300); //numbers
frame.setPreferredSize(new java.awt.Dimension(200,300)); //an object of java.awt.Dimension

Related

Auto scaling components with Java JFrame [duplicate]

Not sure if what I need is possible.
I have a container (JPanel) that contains some internal elements.
I was wondering if it is possible to force internal elements to fit into the container's size.
I need them to be fully visible i.e., resize to fit inside the Panel's size and not cut some parts of the internal elements.
Scrolling is not an option.
Is this possible by using a Layout or something?
EDIT: Important clarification:
The thing is that I do not have access to the internal elements neither to their properties so I would say that a Layoutmanager capable of resizing child elements to fit to its size is needed. I tested BorderLayout and GridBagLayout but the result is always the same, the internal elements are cut out.
It's for exactly that reason that LayoutManagers exist. All the LayoutManagers work for simple containers directly, excluding GridBagLayout which is to able to handle most complete GUIs directly.
For most complete GUI's you have some choices as follows:
Look for a 3rd party layout such as MigLayout or here
Use GridBagLayout
Very easy way is use nested layout, where there is more than one JPanel and each has child JPanels with the same or different LayoutManager
Or custom layout, should be hard..., but same as using GridBagLayout
You could set the JPanel layout to border layout, then add the single child to the center. If there are multiple children, this approach becomes less useful since components added to the the NORTH, SOUTH, EAST, and WEST will remain statically sized while the centre resizes to fill the remainder.
In short, this isn't an ideal solution. All layouting in Swing is made all the more complex by the fact that different components behave in different ways, so you really need to provide further details of the child components you wish to add to your panel, and any behaviour that has been overridden on those components.
The best way is to try a couple of simple examples to see what mileage you get and whether subtle redesign of your child component nesting could help.
you can use a layout, like GridBagLayout, or BorderLayout depending on the situation. With proper weights it is possible.
this sounds to me like you should just peek an appropriate layout manager and use it. For example, look at BorderLayout - put your component in the CENTER and it will occupy all the area. Its up to each concrete layout manager to decide what will be the size of the components.
Mark
I was using a JInternalFrame inside JDesktopPane. I wanted the internal_frame to auto resize as desktop pane is resized, so I had to implement the AncestorResized event for the internal frame where I placed the following code:
this.setPreferredSize(this.getParent().getPreferredSize());
this.pack();

java JScrollPane with JPanel with BoxLayout resizes elements

I have a collection of JPanels for different elements: JPanel showPane, seasonsPane, episodesPane, airingsPane
all of which have setLayout set to null and are of fixed size 304x416. I added those JPanels to a JPanel called showViewPanel of size 1280x416 and set up a BoxLayout like so (below is the code in the JFrame):
showViewPanel.setLayout(new BoxLayout(showViewPanel, BoxLayout.X_AXIS));
showViewPanel.setSize(1280, 416);
showViewScroll = new JScrollPane(showViewPanel);
add(showViewScroll);
setSize(304, 416);
setVisible(true);
What I can't figure out is why it does not produce a scrollable view of all the components and instead resizes showViewPanel to match the size of the window. What am I doing wrong?
all of which have setLayout set to null and are of fixed size 304x416.
Don't use a null layout!!! Don't manually set the size of a panel!!! Your panels should be using a layout manager so the preferred size will be calculated automatically.
If you want all your panels to be the same size then maybe use a GridLayout for your main panel (instead of the BoxLayout) and then add your child panels to this panel.
Scrollbars will automatically appear when needed if you let the layout managers do their job.
Override the preferredSize of the subpanels to 304x416 instead. The scrollpane relies on the preferred size of the content (which depends on the preferred size of its contents).
The layout manager will set the size of the subpanels depending on their preferred sizes, so your custom ones get overridden. Generally, you should get rid of null layouts and learn to use the layout managers. Absolute placement leads to trouble all the time, and is not worth the hassle even when it does not.

Set size of JLabel in FlowLayout

I have a JPanel that uses FlowLayout. I add a number of JLabels to the JPanel, use setPreferedSize() to adjust their size and save them in a list, label_list. Everything works fine. Then I want to change their size:
for(JLabel c:label_list){
c.setPreferedSize(new Dimension(10,10));
}
And it doesn't work.
c.setBackground(Color.red)
and similar stuff works. Why can't I use setPreferedSize here?
c.setBounds(1,1,10,10) and c.setSize(10,10)
Works, but after i update the UI (resizeing the panel) every size goes back to normal.
Then I want to change their size:
for(JLabel c:label_list){ c.setPreferedSize(new Dimension(10,10)); }
And it doesn't work.
You need to call revalidate() on the parent of the labels so that it reperforms layout and enforces their preferred size.
c.setBounds(1,1,10,10) and c.setSize(10,10) Works, but after i update
the UI (resizeing the panel) every size goes back to normal.
Setting bounds/size/location manually conflicts with the LayoutManager of the parent container. The job of the LayoutManager is to position and size the child components.
Either set the layout to null and call yourself setSize-setLocation/setBounds, or use a LayoutManager (recommended) and never call setSize-setLocation/setBounds. At most, you can call setPreferred/setMaximum/setMinimum size but try to avoid this as it can causes cross L&F problems.

How do I programatically resize a component in a BorderLayout?

I have a JPanel that is located at the BorderLayout.SOUTH position of a parent JPanel. I would like to programatically change the height of this child JPanel.
I am calling childPanel.setPreferredSize(new Dimension(getWidth(), newHeight));, but it has no effect. (I have tried setting the Maximum and Minimum sizes as well.)
What (probably very simple thing) am I missing?
After changing the preferred size, you need to call revalidate() on that childPanel.
You may want to read this Oracle Tutorial on LayoutManagers

JViewports with null Layouts?

I got a JViewport correctly scrolling using the default layout manager (using viewport.setViewPosition), but when I call setLayout(null) this no longer works.
Any ideas?
I can give code if needs be, but it's pretty messy at the moment.
Thanks!
Edit: Thanks for the info so far. I've been using a null layout so I can absolutely position components I draw later, is there a way I can do with whilst using a layout manager?
Scroll panes only work when the preferred size of the component added to the scroll pane is greater than the size of the scroll pane.
When you use a null layout, the preferred size is 0, so the scroll pane doesn't work. That is why you should use a layout manager. It will determine the preferred size for you.
Don't call setLayout(null) for any reason.
Every Component should have a LayoutManager, that decide about children's size and position. So use a suitable LayoutManager or implement your own.
If you call setLayout(null) then you need to
Call the Component class's setbounds method for each children.
also Call repaint method.

Categories

Resources