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();
Related
I have two JPanel instances in a JLayeredPane, on different z-orders. I want both of my child JPanels to always fill the space of the LayeredPane.
The idea is for me to toggle the display of a 2nd panel over top of the first to display a modal-like dialog. Yes, I could just use a JDialog, but I thought it would be fun to try and create some transparancy overtop of the covered JPanel for a nice effect.
I find that using a layout manager on the JLayeredPane, like BorderLayout, and trying to set both children to CENTER conflicts since both panels can't be in the Center.
Is there a trick that I'm not seeing?
The idea is for me to toggle the display of a 2nd panel over top of the first
The easiest way to do this is to use a Glass Pane.
Check out the Disabled Glass Pane for an example of this approach.
There are two ways to create some "Glass Panel like" overlay for JPanels with JLayeredPane:
Add a ComponentListener to the JLayeredPane and update the sizes of all child components whenever the size of the JLayeredPane changes
Create a simple FillLayout, which expands the size of its child Components to the size of the Layout Container (In our case the JLayeredPane). You need to keep a list of children Components. During layoutContainer you copy the dimensions of the Container to these child Components. I wrote this and its really simple, but unfortunately I can't post it, since it's corporate. But if anyone is interested just ask in the comments. The implementation basically consists of one-liners.
For both solutions you need to make sure, that the panels on top are transparent, by setting setOpaque to false. This ensures that underlying panels render their content.
I am trying to make something like the above, a frame that consists of many JButton components (gray rectangles). These buttons are of the exact shape but their positioning looks like the picture. I am new to AWT, Swing and such and don't know what layout should I use, I know a bit of GridLayout and BorderLayout which are obviously not suitable in this case.
Any ideas?
I think its better to use GridBagLayout. GridBagLayout is a sophisticated, flexible layout manager. It aligns components by placing them within a grid of cells, allowing components to span more than one cell. The rows in the grid can have different heights, and grid columns can have different widths. For further details, see How to Use GridBagLayout. For more details - https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html#gridbag
I strongly recommend you to use Grid Bag Layout, with this layout you can make good looking GUI or strange GUI in most cases. In your problem Check insets in Grid Bag layout, this layout is kind of tricky but if you will learn it, you will see that it is simple.
In my JPanel, I have 6 buttons laid out in a row (using FlowLayout as of now). The default size of the panel is enough to accommodate these buttons in one row. But, when the frame is resized it gets stuck at the size that is the sum of the minimum sizes of each button.
I need a layout manager that simply puts the buttons in a new row on re-sizing of the panel.
I'm pretty new to Java Swing so I apologize in advance if this is a trivial question.
MigLayout is by far the best layout manager I've ever used. Things that used to require nested containers and lots of hard to understand code can be done in a single container with simple to understand (and maintain) string constraints.
The flow layout is capable of your desired behavior (moving components into new row if they cannot fit). Check out the swing tutorial (run FlowLayoutDemo). You'll have to show us your source code to find out, whether there is some other constrain which prevents it.
FlowLayout does actually paint components on a new row, but the problem is that the preferred size of the panel doesn't change so in many cases you can't see the components (unless you happen to add the panel to the CENTER of a BorderLayout).
One solution is to use the Wrap Layout, which extends FlowLayout to recalculate the preferred size of the panel so that you see the buttons on a new row.
So, I'm trying to design my first GUI app, and i'm stuck on putting elements exactly where I want them. I'm not trying to let anyone do my job for me, but some starters would be great.
For example:
The basic answer is, you don't. Pixel perfect positioning is an illusion in modern user interfaces. Why? Because no two platforms are equal (unless they are exact copies). Each computer will have different requirements when it comes to how information is rendered on the screen, most notably, fonts.
Font metrics will change between platforms, meaning that the way a font is rendered on your screen won't be the same as it is rendered on someone elses. This causes no end of issues not only of an individual component, but how the surrounding components should react.
The best choice is to use layout managers, which provide "guides" on how components should be laid out and how they effect surrounding components.
Based on your example above, I would suggest you would actually need (at least) three layout managers.
At the base, you would use a BorderLayout, this would separate the form from the buttons.
You would need a fields panel and a buttons panel.
The fields panel would contain the actual fields and probably use a GridBagLayout. The buttons panel would contain the buttons and probably use a FlowLayout
The form panel would be added to the CENTER position of the base panel and the buttons to the SOUTH position.
Take a look at Laying Out Components Within a Container for more details
What you want to look at is various layouts in Java (Given that you are asking a basic question I am assuming you are using Swing).
See this link for more info: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
It will show you the various layouts available in Java and how to use them. You will need to use different Components along with different layouts to render your GUI exactly the way you want it.
I'm trying to have my Swing components not scale either vertically and scale horizontally, or the other way around (In other words, I only want them to have one axis of freedom. They can either scale horizontally in some cases, or vertically in others).
Is there any elegant way of doing this, without adding a multitude of JPanels?
LE: I'd rather not make any significant modifications to the already made layout that I've received.
I'm hoping for a magical, simple fix to this issue, like JTextField.don'tScaleVerticallyIdiot();
You need to use an appropriate layout manager.
The two most powerful are MigLayout and FormLayout. I personally prefer MigLayout because it's easier to use directly, whereas FormLayout works well only with a window designer like WindowBuilder.
Both have similar feature characteristics.
Using MigLayout, you can specify if a component is allowed to grow on a specific axis, and if so, what kind of weight it should be provided (as opposed to extra space going to other components).
I think you can achieve that with setting BorderLayout as a LayoutManager of the container, so:
Adding swing component on BorderLayout.EAST will make it scalable vertically only.
Adding swing component on BorderLayout.WEST will make it scalable vertically only.
Adding swing component on BorderLayout.NORTH will make it scalable horizontally only.
Adding swing component on BorderLayout.SOUTH will make it scalable horizontally only.
Adding swing component on BorderLayout.CENTER will make it scalable both horizontally and vertically.
You didn't mention which LayoutManager that you are currently using.
Personally, I would use GridBagLayout for what you are trying to achieve.
I want it to be a single row as height and scale horizontally as much as I drag the frame, but without adding multiple JPanels.
I think BoxLayout with a PAGE_AXIS can do that.