BoxLayout неправильно понимает распорку

Я программирую простую диаграмму ввода в Swing. Я использую boxLayout для создания простого графического интерфейса пользователя. Проблема в том, что создание горизонтальной стойки между JPanel всех меток и JPanel JTextFields приводит к тому, что вся панель смещается вниз (странно), это вся панель:

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;
}

без стойки это выглядит так: введите здесь описание изображения

Со стойкой это выглядит так (я знаю, что не умею редактировать изображения):

введите здесь описание изображения


person hasdrubal    schedule 24.05.2012    source источник


Ответы (3)


Вы добавляете стойку Box к BoxLayout.

В javadoc заявляет, createHorizontalStrut(int width):

Создает невидимый компонент фиксированной ширины. В горизонтальном блоке вы обычно используете этот метод, чтобы создать определенное пространство между двумя компонентами. В вертикальном блоке вы можете использовать этот метод, чтобы блок был по крайней мере указанной ширины. Невидимый компонент не имеет высоты, если нет избыточного пространства, и в этом случае он занимает свою долю доступного пространства, как и любой другой компонент, не имеющий максимальной высоты.

Таким образом, он заполняет высоту между вашим заголовком JLabel и нижней частью JPanel.

Вместо этого вы можете рассмотреть возможность использования Box.createRigidArea(new Dimension(20, height)), где высота может быть указана или установлена ​​равной высоте labelPanel.

Или вы можете пересмотреть макет своего JPanel — взгляните на визуальный руководство.

Для дальнейшего использования, если вы не можете понять свой макет Swing, попробуйте добавить цветные LineBorder к JComponent, в которых вы не уверены. В этом случае стойки Box — это не JComponent, а Component, поэтому вам пришлось бы поместить их в JPanel, но это, по крайней мере, показало бы вам, какое место каждый компонент занимает в вашем верхнем уровне JPanel.

person amaidment    schedule 24.05.2012
comment
javax.swing.Box — это облегченный контейнер, использующий объект BoxLayout. в качестве менеджера компоновки. Box.Filler — это статический вложенный класс, который хорошо работает с Box или BoxLayout. - person trashgod; 25.05.2012

  • используйте Cardlayout для логики мастера

  • поместите JLabel(Configure...., JLabel.CENTER) к BorderLayout.NORTH

  • поместите JPanel с JButtons в BorderLayout.SOUTH

  • поместите JPanel с SpringLayout, GridLayout или GridBagLayout на BorderLayout.CENTER

  • контейнер верхнего уровня реализован BorderLayout по умолчанию, то нет необходимости переопределять BorderLayout

  • вышеупомянутые шаги называются NestedLayout

  • альтернативы помещаются все JComponents с использованием GridBagLayout, SpringLayout или сегодняшних MigLayout в один JPanel, но зачем беспокоиться

person mKorbel    schedule 24.05.2012
comment
Я поместил панель кнопок (предыдущая, следующая, завершение и отмена) в contentPane.SOUTH. в центре панели содержимого я поместил JPanel с карточным макетом. Вторая карта JPanel — это код, показанный выше. Это вторая карта расклада (плохая номенклатура, я знаю). Это хороший подход? Я выбрал BoxLayout, потому что он прост, а BorderLayout — отстой. - person hasdrubal; 25.05.2012
comment
@ user1111: BorderLayout может работать хорошо, особенно если использовать его в сочетании с другими макетами, как рекомендует mKorbel. 1+ для mKorbel. - person Hovercraft Full Of Eels; 25.05.2012

Пример вложенного макета, использующего BorderLayout, FlowLayout (по умолчанию для JPanel) и 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();
         }
      });
   }
}
person Hovercraft Full Of Eels    schedule 24.05.2012