fighting the BorderLayout

O

onetitfemme

I need to place components which I previously add()'ed to JPanels on
the top row of a swing GUI. The JPanels containing the components
should go on the far left, the center and the far right. So I thought
that a BorderLayout would do. I tested all JPanels separately placing
them in the BorderLayout.CENTER of a JApplet, however when I try to put
them together and use BorderLayout{.EAST, .CENTER, .WEST}, the panel of
the left gets squeezed to the point you can not see it.
..
I think I might be stumbling on some gotcha. How could you fix this
problem? What is it I am not getting right?
..
thanks
onetitfemme
 
E

Eric Sosman

onetitfemme said:
I need to place components which I previously add()'ed to JPanels on
the top row of a swing GUI. The JPanels containing the components
should go on the far left, the center and the far right. So I thought
that a BorderLayout would do. I tested all JPanels separately placing
them in the BorderLayout.CENTER of a JApplet, however when I try to put
them together and use BorderLayout{.EAST, .CENTER, .WEST}, the panel of
the left gets squeezed to the point you can not see it.
.
I think I might be stumbling on some gotcha. How could you fix this
problem? What is it I am not getting right?

Have you tried setting preferred sizes or minimum sizes
for the JPanels or for their contents? See the JavaDoc for
the JComponent methods setPreferredSize, et al.
 
I

Ian Wilson

onetitfemme said:
I need to place components which I previously add()'ed to JPanels on
the top row of a swing GUI. The JPanels containing the components
should go on the far left, the center and the far right. So I thought
that a BorderLayout would do. I tested all JPanels separately placing
them in the BorderLayout.CENTER of a JApplet, however when I try to put
them together and use BorderLayout{.EAST, .CENTER, .WEST}, the panel of
the left gets squeezed to the point you can not see it.
.
I think I might be stumbling on some gotcha. How could you fix this
problem? What is it I am not getting right?
.

IFAIK BorderLayout likes to give priority to the centre panel. You can
tweak the preferred sizes but I'd try a more appropriate layout manager:

setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS);
add(leftPanel);
add(midPanel);
add(rightPanel);
 
M

Mark Rafn

Eric Sosman said:
Have you tried setting preferred sizes or minimum sizes
for the JPanels or for their contents? See the JavaDoc for
the JComponent methods setPreferredSize, et al.

This is likely enough to solve the immediate problem. Minimum and Preferred
sizes are vital to letting your layoutmanager know how you expect to be
displayed.

However, I'll pass along a piece of advice I was given long ago, which I now
ignore often but still has a ton of value:

Use only GridBagLayout.

This is worthwhile for two reasons: First, you will learn more about
AWT/Swing layout from doing a few mildly complex GridBag layouts than you will
from doing dozens of Border/Box/Grid layouts.

Second, you will realize that the spec for a good resizable layout is harder
than you think, and in putting together GridBagConstraints for each component
you will get a much better understanding of how you want your app to work.

It's possible that SpringLayout has replaced GridBagLayout for this level of
generality, and you should learn that instead (or in addition).
 
O

onetitfemme

Ian said:
IFAIK BorderLayout likes to give priority to the centre panel. You can
tweak the preferred sizes but I'd try a more appropriate layout manager:

setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS);
add(leftPanel);
add(midPanel);
add(rightPanel);
..
I might not have grasped your tip entirely, but I think the BoxLayout
as you recommend it to me, does not solve my problem. Here is a pice of
complete demo code to show you that the buttons are aligned to the left
anyone one after the other. I meant a component in the FAR left,
another in the middle and another one in the FAR right, not just one
componente next to the other in this order.
..
I think gridbag layouts would be ideal but I might have to do it this
way in a second iteration
..
// __ from:
http://java.sun.com/docs/books/tutorial/uiswing/layout/box.html

import java.awt.*;
import javax.swing.*;

public class BxLO00Test{
public static void addComponentsToPane(Container pane) {
pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS));
JButton JBtn00, JBtn02, JBtn04;
// __
JBtn00 = new JButton("JBtn00");
JBtn00.setAlignmentX(Component.LEFT_ALIGNMENT);
// __
JBtn02 = new JButton("JBtn02");
JBtn02.setAlignmentX(Component.CENTER_ALIGNMENT);
// __
JBtn04 = new JButton("JBtn04");
JBtn04.setAlignmentX(Component.RIGHT_ALIGNMENT);
// __
pane.add(JBtn00);
pane.add(JBtn02);
pane.add(JBtn04);
// __
}
// __
private static void createAndShowGUI() {
// __ Create and set up the window.
JFrame JFrm = new JFrame("BxLO00Test");
JFrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JFrm.setSize(800, 25);
// __ Set up the content pane.
addComponentsToPane(JFrm.getContentPane());
// __ Display the window.
// JFrm.pack();
JFrm.setVisible(true);
}
// __
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() { createAndShowGUI(); }
});
}
}
 
B

Babu Kalakrishnan

Mark said:
This is likely enough to solve the immediate problem. Minimum and Preferred
sizes are vital to letting your layoutmanager know how you expect to be
displayed.

However, I'll pass along a piece of advice I was given long ago, which I now
ignore often but still has a ton of value:

Use only GridBagLayout.

I would disagree with that advice - pretty strongly. There are places
where a GridBagLayout would be the ideal one - but there are tons of
situations where it is very ill-suited to serve the purpose and
misbehaves pretty badly. (For example try putting a JScrollPane inside a
GridBagLayout - you'll find that the layout doesn't behave as one
expects when the container is resized with whatever combinations of
constraints you use - you'd be forced to fiddle with minimum sizes /
preferred sizes to get it to behave in a reasonable manner). Any
component that has a minimum size that is very different from its
preferred size does not play well with a GridBagLayout - (I'm of the
opinion that this is a defect in its implementation - Sun doesn't agree
with it though)

So the best thiong to do is - learn about the strengths and weaknesses
of the different layout managers available, and use the one (or multiple
ones) that most appropriate for the job at hand (And the capability to
make that decision comes only when you know what each layout manager is
capable of doing, and what it cannot do)

BK
 
L

Larry Barowski

Babu Kalakrishnan said:
... There are places
where a GridBagLayout would be the ideal one - but there are tons of
situations where it is very ill-suited to serve the purpose and
misbehaves pretty badly. (For example try putting a JScrollPane inside a
GridBagLayout - you'll find that the layout doesn't behave as one
expects when the container is resized with whatever combinations of
constraints you use - you'd be forced to fiddle with minimum sizes /
preferred sizes to get it to behave in a reasonable manner). Any
component that has a minimum size that is very different from its
preferred size does not play well with a GridBagLayout - (I'm of the
opinion that this is a defect in its implementation - Sun doesn't agree
with it though)

I'd say they do agree, since this problem was fixed twice. Both times
the fix was backed out because it broke existing applications. I'm
not too upset with that because in this case it isn't really a bug, it's
just not-very-useful behavior. In other cases though, they have done
the same for the same reason with things that are bugs.

The version of GBL that distributed extra space so that the fraction
of space difference between minimum and preferred size for each
component was distributed equally when preferred sizes could not
be reached was pretty good. I think that may have been in some of
the 1.5 Betas or early access versions.
 
B

Babu Kalakrishnan

Larry said:
I'd say they do agree, since this problem was fixed twice. Both times
the fix was backed out because it broke existing applications. I'm
not too upset with that because in this case it isn't really a bug, it's
just not-very-useful behavior. In other cases though, they have done
the same for the same reason with things that are bugs.

The version of GBL that distributed extra space so that the fraction
of space difference between minimum and preferred size for each
component was distributed equally when preferred sizes could not
be reached was pretty good. I think that may have been in some of
the 1.5 Betas or early access versions.

Possible that my information is somewhat out of date since I haven't
been dabbling much in Swing the past couple of years. The basis of my
statement was some of their own comments in bug reports related to the
issue which went something like - "Not a bug - will not be fixed"

If they did fix the GBL behaviour and it caused backward incompatibility
issues, the least they could have done was to release the fixed version
as say "GridBagLayout2" (After all they do have an interface named
LayoutManager2 - so I think they would be OK with the ugliness of the
class name :) )


BK
 
L

Larry Barowski

Babu Kalakrishnan said:
If they did fix the GBL behaviour and it caused backward incompatibility
issues, the least they could have done was to release the fixed version
as say "GridBagLayout2" (After all they do have an interface named
LayoutManager2 - so I think they would be OK with the ugliness of the
class name :) )

Agreed. Or they could just add a constructor with a flags
argument to GridBagLayout, so that various aspects of
the layout behavior could be selected.
 
R

RedGrittyBrick

onetitfemme said:
.
I might not have grasped your tip entirely, but I think the BoxLayout
as you recommend it to me, does not solve my problem. Here is a pice of
complete demo code to show you that the buttons are aligned to the left
anyone one after the other. I meant a component in the FAR left,
another in the middle and another one in the FAR right, not just one
componente next to the other in this order.
.

Use horizontal glue
pane.add(JBtn00);
pane.add(Box.createHorizontalGlue()); // <------------ *GLUE*
pane.add(JBtn02);
pane.add(Box.createHorizontalGlue()); // <------------ *GLUE*
pane.add(JBtn04);

See http://java.sun.com/docs/books/tutorial/uiswing/layout/box.html

Also, reinstate your
Jfrm.pack()
and resize the frame to observer the effect your desire.
Or just set the frame size explicitly rather than using .pack().
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top