2013-08-23 3 views
8

Столкнувшись с проблемой использования BoxLayoutкак установить размер компонентов внутри контейнера с BoxLayout

В моем примере, я стараюсь, чтобы уменьшить высоту текстового поля и изменить ширину кнопок (как показано на зеленый маркер на картинке). Я знаю о методах setPrefferedSize() и setMaximumSize(), но он не работает должным образом. Строка add (Box.createHorizontalGlue()) также не помогла.

Спасибо за любую идею

public class Testy extends JPanel { 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       constructGUI(); 
      } 
     }); 
    } 

    private static void constructGUI() { 
     JFrame frame = new JFrame("Testy"); 
     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     JPanel centerPanel = new JPanel(); 
     centerPanel.setBackground(Color.DARK_GRAY); 
     centerPanel.setPreferredSize(new Dimension(100, 400)); 
     frame.add(centerPanel, BorderLayout.CENTER); 

     Testy eastPanel = new Testy(); 
     frame.add(eastPanel, BorderLayout.EAST); 

     frame.pack(); 
     frame.setVisible(true); 
    } 

    public Testy() { 
     setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); 

     JButton button = new JButton("Button ...... 1"); 
     //button.setPreferredSize(...); 
     //button.setMaximumSize(...); 
     add(button); 

     button = new JButton("Button 2"); 
     //button.setPreferredSize(...); 
     //button.setMaximumSize(...); 
     add(button); 

     button = new JButton("Button ........... 3"); 
     //button.setPreferredSize(...); 
     //button.setMaximumSize(...); 
     add(button); 

     JLabel label = new JLabel("Label"); 
     //label.setPreferredSize(...); 
     //label.setMaximumSize(...); 
     add(label); 

     JTextField textField = new JTextField(); 
     //textField.setPreferredSize(...); 
     //textField.setMaximumSize(...); 
     add(textField); 

     button = new JButton("Button 4"); 
     //button.setPreferredSize(...); 
     //button.setMaximumSize(...); 
     add(button); 

     //add(Box.createHorizontalGlue()); 
    } 
} 

picture

+2

В качестве быстрого средства правовой защиты, вы можете использовать вложенные макеты, в том смысле, что с правой стороны, создать 'JPanel' с' BorderLayout', поместите 'JPanel (say centerPanel)' в 'CENTER' и' JPanel (say buttonPanel) 'в' PAGE_END'. Теперь используйте новый 'JPanel (say compPanel)' с 'GridLayout' и поместите на него все компоненты и поместите этот' compPanel' внутри 'centerPanel'. Поместите 'JButton (button4)' внутри 'buttonPanel' как есть. Я думаю, это сработает :-) –

+2

Чтобы лучше помочь, опубликуйте [SSCCE] (http://sscce.org/). SSCCE должен включать импорт, определение класса и метод 'main'. –

ответ

21

Сначала вы должны понимать, что положение компонентов и размер в Java Swing зависит от менеджера компоновки (если менеджер компоновки установлен) не на самом устройстве. Компонент запрашивает у менеджера размер.

Для этого случая я бы использовал различную компоновку - комбинация GridLayout и BorderLayout достаточно и очень проста и понятна. Но если хотите использовать BoxLayout, то ...

  1. Документация говорит:

    BoxLayout обращает внимание запрошенному минимума компонента, предпочтительный и максимальный размер. Пока вы настраиваете макет, вам, возможно, придется отрегулировать размеры этих . ... Например, максимальный размер кнопки обычно равен так же, как и его предпочтительный размер. Если вы хотите, чтобы кнопка была увеличена до , когда доступно дополнительное пространство, вам необходимо изменить его максимальный размер .

  2. Затем набор компонентов максимальный размер: c.setMaximumSize(new Dimension(Integer.MAX_VALUE, c.getMinimumSize().height)); (c означает button, label и textField в вашем примере)

Edit 1:

Здесь работает исходный код:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 

import javax.swing.BoxLayout; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.SwingUtilities; 
import javax.swing.WindowConstants; 

public class Testy extends JPanel { 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       constructGUI(); 
      } 
     }); 
    } 

    private static void constructGUI() { 
     JFrame frame = new JFrame("Testy"); 
     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     JPanel centerPanel = new JPanel(); 
     centerPanel.setBackground(Color.DARK_GRAY); 
     centerPanel.setPreferredSize(new Dimension(100, 400)); 
     frame.add(centerPanel, BorderLayout.CENTER); 

     Testy eastPanel = new Testy(); 
     frame.add(eastPanel, BorderLayout.EAST); 

     frame.pack(); 
     frame.setVisible(true); 
    } 

    public Testy() { 
     setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); 

     JButton button = new JButton("Button ...... 1"); 
     //button.setPreferredSize(...); 
     button.setMaximumSize(new Dimension(Integer.MAX_VALUE, button.getMinimumSize().height)); 
     add(button); 

     button = new JButton("Button 2"); 
     //button.setPreferredSize(...); 
     button.setMaximumSize(new Dimension(Integer.MAX_VALUE, button.getMinimumSize().height)); 
     add(button); 

     button = new JButton("Button ........... 3"); 
     //button.setPreferredSize(...); 
     button.setMaximumSize(new Dimension(Integer.MAX_VALUE, button.getMinimumSize().height)); 
     add(button); 

     JLabel label = new JLabel("Label"); 
     //label.setPreferredSize(...); 
     label.setMaximumSize(new Dimension(Integer.MAX_VALUE, label.getMinimumSize().height)); 
     add(label); 

     JTextField textField = new JTextField(); 
     //textField.setPreferredSize(...); 
     textField.setMaximumSize(new Dimension(Integer.MAX_VALUE, textField.getMinimumSize().height)); 
     add(textField); 

     button = new JButton("Button 4"); 
     //button.setPreferredSize(...); 
     button.setMaximumSize(new Dimension(Integer.MAX_VALUE, button.getMinimumSize().height)); 
     add(button); 

     // add(Box.createVerticalGlue()); 
    } 
} 

Screenshot

Edit 2:

Если вы хотите выложили кнопку 4 в нижней части правой колонки добавьте эту строку add(Box.createVerticalGlue()); между add(textField); и button = new JButton("Button 4");.

+0

Мне понравилось это обновление, хотя он уже давно его поддержал, прежде чем, чтобы отрицать нисходящее движение, сделанное кем-то другим, поскольку не было дано объяснений относительно того же. –

+0

Мне определенно нужен макет коробки, и ваш пример работает так, как должен. Спасибо за разъяснение – Dumas45

+0

@ Dumas45 _I определенно нужна коробка layout_ - почему? BTW, -1 для [setXXSize, который не является ни когда-либо] (http://stackoverflow.com/a/7229519/203657) – kleopatra

1

Это должно приблизиться, основываясь на вашем розыгрыше, просто нужно работать над этим компонентом ниже JLabel (с использованием setPreferredSize()):

JPanel main = new JPanel(new GridLayout(1, 2)); 

JPanel left = new JPanel(); 
//left.setPreferredSize(some size); 
JPanel right = new JPanel(new GridLayout(6, 1)); 
//right.setPreferredSize(some size); 

right.add(new JButton("Button 1")); 
//... 
right.add(new JButton("Button 4")); 

main.add(left); 
main.add(right); 
+2

Лучше использовать 'new GridLayout (0, 1)', это означает любое количество строк, но ровно один столбец - это имеет лучший смысл. Во всяком случае, я не знаю, что произойдет, когда я добавлю более 6 компонентов. –

3

В качестве быстрого средства правовой защиты, вы можете использовать вложенные макеты, в том смысле, что с правой стороны создайте JPanel с BorderLayout, поставьте JPanel(say compPanel) на CENTER и JPanel(say buttonPanel) на PAGE_END.Теперь используйте новый JPanel(say panel) с GridLayout и поставьте на него все компоненты и поместите это compPanel внутри centerPanel. Place JButton(button4) внутри buttonPanel как есть.

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

Вот рабочий пример:

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

public class Testy extends JPanel {   

    private JPanel panel; 
    private JPanel buttonPanel; 

    public Testy() { 
     setLayout(new BorderLayout(5, 5)); 

     JPanel compPanel = new JPanel(); 
     panel = new JPanel(new GridLayout(6, 1, 5, 5));  
     JButton button = new JButton("Button ...... 1"); 
     //button.setPreferredSize(...); 
     //button.setMaximumSize(...); 
     panel.add(button); 

     button = new JButton("Button 2"); 
     //button.setPreferredSize(...); 
     //button.setMaximumSize(...); 
     panel.add(button); 

     button = new JButton("Button ........... 3"); 
     //button.setPreferredSize(...); 
     //button.setMaximumSize(...); 
     panel.add(button); 

     JLabel label = new JLabel("Label"); 
     //label.setPreferredSize(...); 
     //label.setMaximumSize(...); 
     panel.add(label); 

     JTextField textField = new JTextField(); 
     //textField.setPreferredSize(...); 
     //textField.setMaximumSize(...); 
     panel.add(textField); 
     compPanel.add(panel); 

     buttonPanel = new JPanel(); 
     button = new JButton("Button 4"); 
     buttonPanel.add(button); 

     add(compPanel, BorderLayout.CENTER); 
     add(buttonPanel, BorderLayout.PAGE_END); 
    } 

    private void constructGUI() { 
     JFrame frame = new JFrame("Testy"); 
     frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 

     JPanel centerPanel = new JPanel(); 
     frame.getContentPane().setLayout(new BorderLayout(5, 5)); 
     centerPanel.setBackground(Color.DARK_GRAY); 
     frame.add(centerPanel, BorderLayout.CENTER); 

     frame.add(this, BorderLayout.LINE_END); 

     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Testy().constructGUI(); 
      } 
     }); 
    } 
} 

ВЫВОД:

LAYOUT EXAMPLE

+2

+1 Это лучшее решение, если вам не нужно использовать BoxLayout. –