I am wanting to grow only the last component in a panel to fill the remaining vertical space.
I currently have:
panel.setLayout(new MigLayout("inset 0, filly", "[grow, fill, right][grow, fill, left]"));
Which adds padding after each component in order to fill the remaining vertical space. Is there a way to tell MigLayout not to add the padding and grow the last row?
The last row is docked incase that changes anything:
panel.add(new JScrollPane(getTable()), "newline, dock south");
Oh, one more thing I forgot to mention (and this is probably important) The amount of rows isn't know at compile time.
Looks like the dock indeed makes a difference, replacing it with pushy growing cell constraint (and no filly in the layout constraint) works fine. Might be an option if you can live without the dock:
panel.add(new JScrollPane(new JTable(8, 5)), "span, pushy, growy");
I have solved this by adding the component constraint of: height :100%: and removing the filly layout constraint.
My understanding is that this tells the component that it has no minimum size and the preferred size is 100% of it's container. This means that it will take up as much room as possible.
So when you do use the size constraint :pref: I believe it's saying "Up to the specified size`
And when you do min:: I think that resolves to "at least the specified size"?
Related
In my Swing application I have a panel that uses a GridBagLayout. There, I have 3 columns and in one of these columns there is a JTextField. What I want is to set the width of this JTextField (using setPreferredSize() method) so that it occupies all the available space of its column.
As I understand the widths of the columns are calculated based on the weights that I've assigned to them using GridBagConstraints. I tried to subtract from the width of the panel the sum of widths of other components at the same line, but that doesn't seem to work, apparently because of different margins and insets.
So, how do I make my JTextField occupy all the available space?
Take a look at ...
GridBagConstraints.weightx
GridBagConstraints.fill
These will allow you to control how a component fills a given cell and the amount of "weight" a cell is given over the others
FlowLayout performs "pressure" from the right, so as all components are trying to take their minimal widths. Contrary, BoxLayout tries to spread all components to fill entire height of the space.
Can I add some filler as last component or something to make all components have minimal heights in BoxLayout?
You could use Box.createGlue(), which returns a component that takes up as much space as the BoxLayout will give it. Adding it to the bottom of a vertical BoxLayout will scrunch the other components to the top.
You could also use nested layouts.
There is a persistent empty space around the ImageIcons. I created new empty borders on all the objects like so:
array[i].setBorder(BorderFactory.createEmptyBorder());
set the hgap and vgap to zero on two diffrent layouts:
frame.getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
//frame.getContentPane().setLayout(new GridLayout(screenSize.height/15,screenSize.width/15,0,0));
and tried setting the gaps negative, on advice from another post on here. None of these seem to work, any suggestions?
Look at the all of settings of your GridLayout By default it has some margins and such. Though I might be wrong, it occurs to me this is Swing and not SWT.
Works fine for me when I use a JLabel. You don't even need to use an EmptyBorder.
Maybe the problem is that your images have a transparent border. Or maybe the problem is that you are using another component.
If you need more help than post your SSCCE that demonstrates the problem.
I have two JPanels (let's call these Panel1 and Panel2). These panels are of the same width, but varying heights.
I want to put these JPanels into one big JPanel (lets call it Panel0), and stack them on top of each other (I decided to set Panel0's layout as GridLayout(0,1)).
The problem, is that both nested panels (panels 1 and 2) end up having the same dimensions (those of the biggest between the two), instead of the setPreferredDimension and setDimension that I set to them.
Sorry, I can't really provide any code (there's a lot of crap added to the panel's, and it's all for something work-related). Any advice? Thanks!
GridLayout forces all components to be the same size; that's why it's called a grid.
Since you only have two panels, I'd suggest using a BorderLayout with one panel at NORTH and the other CENTER. If you allow resizing, then the one in CENTER will be the expand to fill any extra vertical space, so just be aware of that.
Is it possible to tell JPanel to set its size to fit all components that it contains? Something like pack() for JFrame.
edit: The trick with preferredSize didn't help. I've got JSplitPane, where in one part there is GridBagLayout with many labels (see screenshot) and labels overlap each other.
screenshot http://foto.darth.cz/pictures/screen.png
After looking at the source code for pack(), I came up with:
panel.setPreferredSize(panel.getPreferredSize());
This forces the panel to recalculate its preferred size based on the preferred sizes of its subcomponenents.
You may or may not have to call validate() afterward; in my tiny example, it seemed to make no difference, but the Javadoc says:
The validate method is used to cause a container to lay out its subcomponents again. It should be invoked when this container's subcomponents are modified (added to or removed from the container, or layout-related information changed) after the container has been displayed.
So I guess it depends on why you're having to repack your JPanel.
By default Containers have a preferred size that matches the preferred layout size given by the container. So literally all you have to do is:
panel.setSize(panel.getPreferredSize());
Presumably you are doing something odd with the parent to stop the parent's layout manager doing the equivalent of this.
maybe you can do something like that by removing from your panel
setResizable(false);
I would try:
panel.revalidate();
panel.repaint();
This will not necessarily set the panel to its preferred size, that is more dependent on what the layout manager decides to use.
This is useful in cases where you have added/removed components from a panel that is currently displayed and visible.
Update:
Based on your screenshot I can say the following:
1) Consider programatically changing the divider location.
2) Consider programatically resizing the window itself horizontally since it seems to be a little tight to show both sides of the split pane.
Or both.
You can set the divider location by doing
splitPane.setDividerLocation(newSize);
Keep in mind that there are two overloaded methods for this, one taking a float one taking an int. The float does a percentage of the size while the int is the size in pixels. The size is for the left hand panel (or top panel for that orientation).
I would consider possibly changing the divider location based on the preferred width of the panels.
The javax.swing mysteries reveal themselves only gradually, and only to those who are prepared to offer many libations (particularly torn out clumps of hair, hours burning the midnight oil, etc.) to the gods of Swing.
However, for this case in point I would suggest the following as a sort of Swiss army knife which usually does what you think the framework should do anyway:
myJPanel.getTopLevelAncestor().validate()
As the sacred text says, "Validates this container and all of its subcomponents." (Container.validate). NB getTopLevelAncestor() is a JComponent method.
Can't remember how JSplitPane fits into this: try it and you'll probably find that it validates both components (right and left, top and bottom), but I would be surprised if changing the divider doesn't do this for you anyway.
I had a similar issue using Netbeans GUI Builder. My inner panels were getting weird sizes; I was trying to adjust the minimum and preferred sizes manually, which was a frustrating exercise.
The problem was solved when I reset all the minimum and preferred sizes back to default (In Netbeans GUI Builder: right click JPanel component -> Properties -> preferredSize -> Reset to Default). When there is no imposed size, the jpanel takes the size of the inner component.
Note: GridBaLayout was used in my case
JSplitPanes are a bit fussy when it comes to its children's sizes, have a look at the Java tutorial. Are you using the GridBagLayout correctly? Looks like it's not setting the right JPanel's minimum size properly.
Here's an example of a panel which:
Resizes with it's parent.
Sets the width to the width of the parent.
Sets the height according to sum of the height of all of it's children.
JPanel panel = JPanel(new GridBagLayout())
panel.setMaximumSize(new Dimension(panel.getMaximumSize().width, panel.getPreferredSize().height))
panel.validate()
panel.repaint()