BoxLayout misunderstanding racks
I am planning a simple input diagram in Swing. I use boxLayout to create a simple graphical user interface. The problem is that creating a horizontal bar between the JPanel of all labels and the JPanel JTextFields causes the whole panel to move down (weird), this is the whole panel:
private JPanel secondCard() { //main panel. set the boxlayout secondCard = new JPanel(); secondCard.setLayout(new BoxLayout(secondCard,BoxLayout.Y_AXIS)); // create vertical strut for looks secondCard.add(Box.createVerticalStrut(20)); // create title. center it. JLabel title = new JLabel("Configure main network parameters "); title.setAlignmentX(CENTER_ALIGNMENT); secondCard.add(title); // create vertical strut for looks secondCard.add(Box.createVerticalStrut(20)); // create panel for the description labels JPanel labelPanel = new JPanel(); labelPanel.setLayout(new BoxLayout(labelPanel,BoxLayout.Y_AXIS)); labelPanel.setAlignmentX(LEFT_ALIGNMENT); JLabel inPut =new JLabel("number of inputs"); inPut.setAlignmentX(LEFT_ALIGNMENT); labelPanel.add(inPut); inPut =new JLabel("number of outputs"); inPut.setAlignmentX(LEFT_ALIGNMENT); labelPanel.add(inPut); inPut =new JLabel("number of layers"); inPut.setAlignmentX(LEFT_ALIGNMENT); labelPanel.add(inPut); JPanel textFieldPanel = new JPanel(); textFieldPanel.setLayout(new BoxLayout(textFieldPanel,BoxLayout.Y_AXIS)); textFieldPanel.setAlignmentX(LEFT_ALIGNMENT); JTextField inputTextField = new JTextField(); inputTextField.setAlignmentX(LEFT_ALIGNMENT); textFieldPanel.add(inputTextField); inputTextField.setMinimumSize(new Dimension(0,0)); inputTextField = new JTextField(); inputTextField.setAlignmentX(LEFT_ALIGNMENT); textFieldPanel.add(inputTextField); inputTextField.setMinimumSize(new Dimension(0,0)); inputTextField = new JTextField(); inputTextField.setAlignmentX(LEFT_ALIGNMENT); textFieldPanel.add(inputTextField); inputTextField.setMinimumSize(new Dimension(0,0)); textFieldPanel.setMaximumSize(new Dimension(50, labelPanel.getMaximumSize().height)); JPanel inputPanel = new JPanel(); inputPanel.setLayout(new BoxLayout(inputPanel,BoxLayout.X_AXIS)); inputPanel.setAlignmentX(CENTER_ALIGNMENT); inputPanel.add(labelPanel); //this is the problem strut!! it causes inputPanel to shift downwards inputPanel.add(Box.createHorizontalStrut(20)); inputPanel.add(textFieldPanel); secondCard.add(inputPanel); return secondCard; }
without a rack, it looks like this:
With a stand it looks like (I know what to suck when editing images):
You add Box
binding to BoxLayout
.
As javadoc pointed out, createHorizontalStrut(int width)
:
Creates an invisible fixed-width component. In a horizontal box, you usually use this method to create a certain amount of space between two components. In a vertical box, you can use this method to force the field to be at least the specified width. An invisible component has no height if there is excess space, in which case its shares in the available space, like any other component that has no maximum height.
This way it fills the height between your JLabel
header and the bottom of the JPanel
.
Instead, you can use Box.createRigidArea(new Dimension(20, height))
, where the height can be specified or set to the height of the labelPanel
.
Or you can review the layout for your JPanel
- take a look at the visual guide .
In the future, if you cannot understand your Swing layout, try adding a color LineBorder
to a JComponent
that you are not aware of. In this case, the Box
racks are not JComponent
, but Component
s, so you have to put them in a JPanel
, but that would at least show you how much space each component occupied your top JPanel
.
use cardlayout for logic wizard
put JLabel (Configure ...., JLabel.CENTER) in
BorderLayout.NORTH
type JPanel with JButtons in BorderLayout.SOUTH
type JPanel with SpringLayout , GridLayout , or GridBagLayout in
BorderLayout.CENTER
The top-level container is implemented by default BorderLayout , then there is no reason for re_define
BorderLayout
the above steps are called
NestedLayout
an alternative is put on all
JComponents
usingGridBagLayout
,SpringLayout
or todayMigLayout
onJPanel
, but why bother
An example of a nested layout, one using BorderLayout, FlowLayout (JPanel by default) and GridBagLayout:
import java.awt.BorderLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.util.HashMap; import java.util.Map; import javax.swing.*; public class LayoutFoo { private static final String TITLE = "Configure Main Foobar Parameters"; private static final String[] LABEL_TEXTS = { "Number of Spams", "Number of Frapzats", "Number of Zignuts" }; private static final int TEXTFIELD_SIZE = 10; private static final Insets WEST_INSETS = new Insets(5, 5, 5, 10); private static final Insets EAST_INSETS = new Insets(5, 10, 5, 5); private static final int EB_GAP = 5; private Map<String, JTextField> textFieldMap = new HashMap<String, JTextField>(); public JPanel getConfigFooPanel() { JPanel textFieldPanel = new JPanel(new GridBagLayout()); for (int i = 0; i < LABEL_TEXTS.length; i++) { addTextAndField(textFieldPanel, LABEL_TEXTS[i], i); } int blVertGap = 20; JPanel borderLayoutPanel = new JPanel(new BorderLayout(0, blVertGap)); borderLayoutPanel.setBorder(BorderFactory.createEmptyBorder(EB_GAP, EB_GAP, EB_GAP, EB_GAP)); JLabel titleLabel = new JLabel(TITLE, JLabel.CENTER); borderLayoutPanel.add(titleLabel, BorderLayout.PAGE_START); borderLayoutPanel.add(textFieldPanel, BorderLayout.CENTER); JPanel outerWrapperFlowPanel = new JPanel(); outerWrapperFlowPanel.add(borderLayoutPanel); return outerWrapperFlowPanel; } public String getFieldText(String labelText) { JTextField field = textFieldMap.get(labelText); if (field == null) { return ""; // ?? throw exception } else { return field.getText(); } } private void addTextAndField(JPanel panel, String text, int i) { JLabel label = new JLabel(text, JLabel.LEFT); JTextField textField = new JTextField(TEXTFIELD_SIZE); textFieldMap.put(text, textField); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = i; gbc.gridwidth = 1; gbc.gridheight = 1; gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.anchor = GridBagConstraints.WEST; gbc.insets = WEST_INSETS; panel.add(label, gbc); gbc.gridx = 1; gbc.anchor = GridBagConstraints.EAST; gbc.insets = EAST_INSETS; panel.add(textField, gbc); } private static void createAndShowGui() { JFrame frame = new JFrame("LayoutFoo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new LayoutFoo().getConfigFooPanel()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } }