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.
Related
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.
I've used methods in JFrame:
setSize(600, 600);
setResizable(true);
Next I've created a JButton, and set it's bounds to 0,0,600,600.
I've found that the button is a bit (~40) bigger than the window. It made me some problems when I tried to put a few components exactly where I wanted to. I am using null layout. How to fix it and make my frame exactly 600x600?
The obvious answer is to get rid of the null layout and use a LayoutManager instead. If you want a component to take all available space, use a BorderLayout and put the component in the BorderLayout.CENTER.
To answer your specific question: the size of the JFrame is 600 by 600, but that is not the size of its content pane. The JFrame also contains window decorations which take up some of the size.
You could try to remove those decorations, or simply make your JFrame bigger. Or start wondering about your requirement to have a JFrame with a content pane of exactly 600 by 600 while it is still resizable by the user.
While you resize JFrame manually via mouse, elements on JPanel can go on next line if there is no enough space, same time new element-lines can be removed if JFrame is big enough
Example:
at this moment there are two lines to fit all JButtons
If I change JFrame width via mouse, JButtons will drop on next lines:
the problem is you can't see all JButtons, JFrame needs to be resized in height.
How to make JFrame auto resize in height to fit all elements according to set width?
This is not a very good design. Show me another professional application that works like this? People don't like to see the size of frames jump. The user is usually resizing the frame to fit the app on their desktop and will get frustrated if they fix the width and the height changes. Let the user control the size.
If you want all the buttons to display, then maybe a better solution is to just make the frame non resizable by using:
frame.setResizable( false );
frame.pack();
frame.setVisible();
Anyway, if you really want to do this then you would probably add a ComponentListener to the content pane of the frame. Then in the componentResized() method you would invoke pack().
However, this will cause multiple events to be generated every couple of pixels so you may also want to use:
Toolkit.getDefaultToolkit().setDynamicLayout( false );
So that the pack() is only done once when the mouse is released.
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
frame.setSize(400,200);
How to make my JFrame auto-resizable? Size depends on existing components in the frame, but the user can add more components dynamically.
You could use the JFrame.pack() method, that according documentation:
Causes this Window to be sized to fit the preferred size and layouts
of its subcomponents.
See the Nested Layout Example for both dynamically added components (labels added using a button - in a scroll pane), as well as a resizable GUI.
When is the size of the JComponent is calculated? After being shown in the screen or before that?
if I send .getSize() message before .setVisible(true), would it give me the right answer?
Thanks
I sometimes check the sizes of my components when debugging to find out why I can't see them for instance. In most cases, the sizes will be realized when the GUI has been rendered. This can occur when pack() or setVisible(true) has called on the top-level window. My usual sequence of method calls is to call pack() first as this tells the layout managers to lay out the components that they are responsible for, and sets the sizes of the components and the GUI, then call setLocationRelativeTo(null) to center my GUI, then call setVisible(true) to display it.
The layout manager is responsible for determining the size of a component, so you don't know its actual size until the component has been added to the frame and the frame has been pack()ed ore made visible.
If you use a layout manager that respects the preferred size of a component then you can use:
component.getPreferredSize();
Why do you think you need to know the size? Generally you don't worry about sizes and let the layout manager do its job.
In addition to the usual pack() > setVisible(true) > getPreferredSize() sequence, you can validate() the relevant Container to preview the geometry, as shown here.
If I understand properly, the reason why you want to know the size of a component is to reset the size of a JWindow once a user click on the "More options" button, isn't it?
I would suggest to do the following: when the user clicks on that button, update your UI adding the extra component, and the execute pack() on the JWindow. It should resize to the proper size.