Re: more quirks with GridBagLayout
On 2008-05-21, LC's No-Spam Newsreading account <nospam@mi.iasf.cnr.it> wrote:
In the past I succeeded in having the top panel in my applet to be
divided vertically in three areas of unequal height :
panel = new JPanel(new GridBagLayout());
tabPane.setPreferredSize(new Dimension(MYWIDTH,450));
panel.add(tabPane ,c1);
scrollPane1.setPreferredSize(new Dimension(MYWIDTH,100));
panel.add(scrollPane1,c2);
scrollPane2.setPreferredSize(new Dimension(MYWIDTH,300));
panel.add(scrollPane2,c3) ;
where c1, c2, c3 are "appropriate" GridBagConstraints (according to
previous correspondence all what matters was to set gridx=0 and letting
setPreferredSize do everything ... however I had other, perhaps
redundant, constraints set).
Now I want to achieve the same thing (i.e. divide vertically in three
areas of unequal height) for one of the panels of the tabbed pane, so
far unused.
I first created my layout using three equal-height areas
JPanel panel3 = new JPanel(new GridLayout(3, 1));
panel3.add(panel3a);
panel3.add(panel3b);
panel3.add(panel3c);
incidentally panel3a is a GridLayout with three lines of JLabels or
JButtons, panel3b is a GridLayout(15, 1), panel3c is a GridLayout(2, 1)
which contains a single label and a slider.
This is not OK as the rows in the central panel3b are too squeezed while
the top and bottom space occupy more space than they need.
So I replaced the definition of panel3 with
JPanel panel3 = new JPanel(new GridBagLayout());
and then I set the preferred sizes of the three sub panels (the sum
should make 450 which is the height of the tab pane to which panel3
belongs)
panel3a.setPreferredSize(new Dimension(MYWIDTH,50));
panel3b.setPreferredSize(new Dimension(MYWIDTH,350));
panel3c.setPreferredSize(new Dimension(MYWIDTH,50 ));
panel3.add(panel3a,c1);
panel3.add(panel3b,c2);
panel3.add(panel3c,c3);
where the initial GridBagConstraints are like the functioning case
c1.gridx=0 ; c1.gridy=0 ;
c1.gridwidth=GridBagConstraints.REMAINDER ;
c1.gridheight=3 ;
c1.fill=GridBagConstraints.BOTH ;
c1.anchor=GridBagConstraints.PAGE_START;
c1.weightx=1.0 ; c1.weighty=0.0 ;
c2.gridx=0 ; c2.gridy=3 ; //
c2.gridwidth=GridBagConstraints.REMAINDER ;
c2.gridheight=15 ;
c2.fill=GridBagConstraints.BOTH ;
c2.anchor=GridBagConstraints.LINE_END ;
c2.weightx=1.0 ; c2.weighty=0.0 ;
c3.gridx=0 ; c3.gridy=17 ; //
c3.gridwidth=GridBagConstraints.REMAINDER ;
c3.gridheight=3 ;//GridBagConstraints.REMAINDER ;
c3.fill=GridBagConstraints.BOTH ;
c3.anchor=GridBagConstraints.PAGE_END;
c3.weightx=1.0 ; c3.weighty=0.0 ;
where the gridheight and gridy were chosen according to the approximate
number of "text lines" in the three subpanels.
What I get is that part of the central subpanel is obscured by the top
subpanel, while the bottom subpanel is not visible at all (obscured by
the central one or off the bottom ?)
I tried changing the PreferredSize of some of the component, but this
seems to have no effect at all.
I also tried playing around with other constraints, but they are too
many for a change-one-at-a-time test to make sense.
Is there some more basic reason why setPreferredSize should not be
honoured when panel3 is part of the tabbedPane ?
Or some other error in the above arrangement ?
A basic error is that the relative gridheights of components in the
same column do not affect how the available height is distributed
among the components. The gridheight affects how a component is
positioned vertically versus other components in other columns that
occupy some or all of the same rows.
For example, in a layout of three components like
+-----+-----+
| A | |
+-----+ C |
| B | |
| | |
+-----+-----+
Components A and B in the left column would have a gridheight of 1 while
component C in the right column would have a gridheight of 2 to align
- the tops of the tops cell occupied by components A and C
- the bottoms of the bottom cell occupied by components A and B
The relative weighty values determine how the available height is
distributed among the componentsi.
It usually helps to post an example that others can compile and run.
Here is one that sets the height of three components in the 50/350/50
distribution that you want (as long as the container is at leas high
enough to fit the components at those heights).
import java.awt.*;
import javax.swing.*;
public class Vratio {
static final int MYWIDTH = 400;
static final int heights[] = {50, 350, 50};
static final Color colors[] = {Color.RED, Color.YELLOW, Color.GREEN};
public static void main(String args[]) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container cp = f.getContentPane();
cp.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.VERTICAL;
for (int i = 0; i < heights.length; i++) {
JPanel p = new JPanel();
p.setPreferredSize(new Dimension(MYWIDTH, heights[i]));
p.setBackground(colors[i]);
gbc.weighty = heights[i];
cp.add(p, gbc);
}
f.pack();
f.show();
}
}