Почему GridBagLayout центрирует мои компоненты, а не помещает их в угол? - PullRequest
16 голосов
/ 01 сентября 2011

До сих пор мне удавалось максимально избегать использования GridBagLayout (от руки), но я не мог избежать этого на этот раз, и я читаю учебное пособие SUN GridBagLayout Пока что все идет не очень хорошо. Я думаю, что что-то неправильно понимаю.
Например, я пробую следующий код (похожий на тот, что был в сообщении SUN):

public class MainFrame extends JFrame { 


    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainFrame frame = new MainFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame
     */
    public MainFrame() {
        super();
        setBounds(100, 100, 500, 375);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Container mainContainer = getContentPane();

        mainContainer.setLayout(new GridBagLayout());       

        //add label
        JLabel someLabel = new JLabel("Label 1:");
        GridBagConstraints constraints = new GridBagConstraints();

        constraints.gridx = 0;
        constraints.gridy = 0;
        //constraints.anchor = GridBagConstraints.FIRST_LINE_START;
        //constraints.weightx = 0.5;
        mainContainer.add(someLabel, constraints);      

        JTextField someText = new JTextField(30);

        constraints = new GridBagConstraints();

        constraints.gridx = 1;
        constraints.gridy = 0;
        constraints.weightx = 0.5;
        mainContainer.add(someText, constraints);

        //
    }

}

Я получаю метку и текстовое поле одно рядом с другим в центре кадра.
Но я ожидал, что они появятся в верхнем левом углу, так как для метки gridx и gridy равны 0.
Даже если я установлю constraints.anchor = GridBagConstraints.FIRST_LINE_START; все тот же результат.
Я здесь не прав?
Из сообщения СОЛНЦА:

Укажите строку и столбец в верхнем левом углу компонента. крайний левый столбец имеет адрес gridx = 0, а верхний ряд имеет адрес Gridy = 0.

Ответы [ 5 ]

13 голосов
/ 01 сентября 2011

Вы должны прочитать далее в учебнике по Swing раздел, посвященный weightX/weightY, где говорится:

Если вы не укажете хотя бы одно ненулевое значение для weightx или weightty, все компоненты слипаются в центре своего контейнера.

Вы указали вес X, но не вес Y.

Редактировать, это сложнее, чем я думал. Похоже, вам также нужно указать:

constraints.anchor = GridBagConstraints.FIRST_LINE_START;

для обоих компонентов в дополнение к весомым.

13 голосов
/ 01 сентября 2011

Добавьте constraints.weighty = 1; к ограничениям JLabel и constraints.anchor = GridBagConstraints.NORTHWEST; к ограничениям TextField.

РЕДАКТИРОВАТЬ:

Из руководства Oracle GridBagLayout :

Большие числа указывают, что строка или столбец компонента должны занимать больше места.Для каждого столбца вес относится к наибольшему весу, указанному для компонента в этом столбце, причем вес каждого многоколоночного компонента каким-то образом делится между столбцами, в которых находится компонент. Аналогично, вес каждой строки связан с самым высоким весом, указанным длякомпонент в этой строке.Дополнительное пространство имеет тенденцию идти к крайнему правому столбцу и нижнему ряду.

2 голосов
/ 01 сентября 2011

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

2 голосов
/ 01 сентября 2011

Вы можете добиться этого, используя хитрость, добавив фиктивный компонент после строки и разверните его, чтобы заполнить вертикальное пространство.Также вы можете повторно использовать ограничения, нет необходимости создавать новый объект:

РЕДАКТИРОВАТЬ: хорошо, забудьте об этом :( Правильный путь, как сказали Деон Бота и БенКоле, я обновил свой код, используяякорь

Пожалуйста, НЕ примите этот ответ, примите либо Деона, либо Бена

public class MainFrame extends JFrame { 
    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainFrame frame = new MainFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

public MainFrame() {
    super();
    setBounds(100, 100, 500, 375);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Container mainContainer = getContentPane();
    mainContainer.setLayout(new GridBagLayout());       

    JLabel someLabel = new JLabel("Label 1:");
    JTextField someText = new JTextField(30);

    GridBagConstraints constraints = new GridBagConstraints();
    constraints.anchor = GridBagConstraints.FIRST_LINE_START;

    constraints.gridx = 0;
    constraints.gridy = 0;    
    constraints.weightx = 1.0;
    mainContainer.add(someLabel, constraints);      

    constraints.gridx = 1;                       
    constraints.weightx = 1.0;
    constraints.weighty = 1.0;        
    mainContainer.add(someText, constraints);                       
}
}
1 голос
/ 27 сентября 2015

Это сработало для меня:

public class NewJFrame extends javax.swing.JFrame {

    public NewJFrame() {
        initComponents();
    }

    @SuppressWarnings("unchecked")
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jPanel2 = new javax.swing.JPanel();
        jComboBox3 = new javax.swing.JComboBox();
        jComboBox4 = new javax.swing.JComboBox();
        jComboBox5 = new javax.swing.JComboBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setBackground(new java.awt.Color(255, 204, 51));
        setMinimumSize(new java.awt.Dimension(800, 600));
        getContentPane().setLayout(null);

        jPanel2.setLayout(new java.awt.GridBagLayout());

        jComboBox3.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        jPanel2.add(jComboBox3, gridBagConstraints);

        jComboBox4.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        jPanel2.add(jComboBox4, gridBagConstraints);

        jComboBox5.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        jPanel2.add(jComboBox5, gridBagConstraints);

        getContentPane().add(jPanel2);
        jPanel2.setBounds(30, 40, 150, 260);

        pack();
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }

    private javax.swing.JComboBox jComboBox3;
    private javax.swing.JComboBox jComboBox4;
    private javax.swing.JComboBox jComboBox5;
    private javax.swing.JPanel jPanel2;
}
...