To get the hang of layouts, I'd recommend reading my article on them (http://java.sun.com/developer/onlineTraining/GUI/AWTLayoutMgr/). It's old, but the concepts and how FlowLayout works are detailed.
What do you mean by "on top of each other"?
If you mean like
Password
<field>
EDIT: I REMEMBERED AN EASIER WAY TO DO THIS (completely in the JDK/JRE)...
(This is similar to what I'm doing with the BoxBeans below, but you don't need the BoxBeans. I created BoxBeans to be able to use BoxLayout in a UI builder a long time ago...)
JLabel label = new JLabel("Password") {
@Override public Dimension getMaximumSize() {
return super.getPreferredSize();
}
};
JPasswordField field = new JPasswordField() {
@Override public Dimension getMaximumSize() {
return super.getPreferredSize();
}
};
field.setColumns(10);
Box verticalBox = Box.createVerticalBox();
verticalBox.add(Box.createVerticalGlue());
verticalBox.add(label);
verticalBox.add(field);
verticalBox.add(Box.createVerticalGlue());
//
Box horizontalBox = Box.createHorizontalBox();
horizontalBox.add(Box.createHorizontalGlue());
horizontalBox.add(verticalBox);
horizontalBox.add(Box.createHorizontalGlue());
add(horizontalBox);
Previous answer for reference...
I DO NOT RECOMMEND THE FOLLOWING BUT IT MAY HELP OTHER READERS WITH IDEAS
You can do something like
setLayout(FlowLayout());
JPanel group = new JPanel(new BorderLayout());
group.add(new JLabel("Password"), BorderLayout.NORTH);
group.add(passwordField, BorderLayout.SOUTH);
add(group);
This will create a little panel in the top-center of the overall UI that contains the Password and field.
Note that the nested BorderLayout ensures that the label and field each get their preferred size. You'll need to call setColumns on the field to the number of chars you'd like displayed.
If you want to center the label/field vertically as well, you could do the following
setLayout(new GridBagLayout());
//
add(new JLabel("Password"),
new GridBagConstraints(0,0,1,1,1,1,
GridBagConstraints.SOUTH,GridBagConstraints.NONE,
new Insets(3,3,3,3), 0,0));
field.setColumns(10);
add(field, new GridBagConstraints(0,1,1,1,1,1,
GridBagConstraints.NORTH,GridBagConstraints.NONE,
new Insets(3,3,3,3), 0,0));
I hate using GridBagLayout in general, so I'll add a version using BoxLayout (but it's a bit trickier due to the preferred size settings)
JFrame f = new JFrame();
f.setLayout(new BorderLayout());
//
JPanel stuffH = new JPanel();
f.add(stuffH, BorderLayout.CENTER);
stuffH.setLayout(new BoxLayout(stuffH, BoxLayout.X_AXIS));
//
JPanel stuffV = new JPanel();
stuffV.setLayout(new BoxLayout(stuffV, BoxLayout.Y_AXIS));
//
JLabel label = new JLabel("Password");
BoxAdapter labelAdapter = new BoxAdapter();
labelAdapter.add(label);
JPasswordField field = new JPasswordField();
field.setColumns(10);
BoxAdapter fieldAdapter = new BoxAdapter();
fieldAdapter.add(field);
//
stuffV.add(new VerticalGlue()); // for vertical spacing
stuffV.add(labelAdapter);
stuffV.add(fieldAdapter);
stuffV.add(new VerticalGlue()); // for vertical spacing
//
stuffH.add(new HorizontalGlue()); // for horizontal spacing
stuffH.add(stuffV);
stuffH.add(new HorizontalGlue()); // for horizontal spacing
//
f.setVisible(true);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
A few notes on this:
- I'm using my BoxBeans helper classes - see http://javadude.com/tools/boxbeans. This page is based on VisualAge for Java, but the jar at the bottom of the page can be used outside VAJ. I just tried it in eclipse, for example.
- AFAICS, you cannot set a jframe's layout directly to BoxLayout, so I added an extra panel in between. There's a check in BoxLayout that has trouble with the automatic indirection of the content pane.
- I nested the BoxLayouts so there's horizontal centering (the stuffH panel) containing a vertical centering (the stuffV panel). They are centered by surrounding them with "Glue" components, which are simply components that allow themselves to expand.
I had to put the label and field in a BoxAdapter which limits their maximum size to their preferred size. If you don't want to use BoxAdapter, you can acheive the same effect by using the following for the field and label:
JLabel label = new JLabel("Password") {
@Override public Dimension getMaximumSize() {
return super.getPreferredSize();
}
};
JPasswordField field = new JPasswordField() {
@Override public Dimension getMaximumSize() {
return super.getPreferredSize();
}
};
Hope this proves helpful to you and anyone else!
-- Scott