Почему GridBagLayout сосредоточивает мои компоненты, а не кладет их в угол?
До сих пор мне удалось избежать использования 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;
все тот же результат.
Я здесь не прав?
Из сообщения SUN:
Укажите строку и столбец в левом верхнем углу компонента. leftmost column имеет адрес gridx = 0, а верхняя строка имеет адрес Gridy = 0.
Ответы
Ответ 1
Добавьте constraints.weighty = 1;
к ограничениям JLabel и constraints.anchor = GridBagConstraints.NORTHWEST;
к ограничениям TextField.
EDIT:
Из Oracle Руководство GridBagLayout:
Более крупные номера указывают, что в строке или столбце компонента должно быть больше места. Для каждого столбца вес связан с наивысшим значением weightx, указанным для компонента внутри этого столбца, причем каждый вес компонента многоколонома разделяется каким-то образом между столбцами, в которых находится компонент. Аналогично, каждый вес строки связан с самым высоким весом, указанным для компонента внутри этой строки. Дополнительное пространство имеет тенденцию идти к самому правому столбцу и нижнему ряду.
Ответ 2
Вам нужно прочитать далее в учебнике Swing для раздела weightX/weightY
, где указано:
Если вы не указали хотя бы одно ненулевое значение для weightx или weighty, все компоненты скомпонованы в центре их контейнера.
Вы указали weightX, но не вес.
Изменить, это сложнее, чем я думал. Похоже, вам также необходимо указать:
constraints.anchor = GridBagConstraints.FIRST_LINE_START;
для обеих компонент в добавлении к весовому.
Ответ 3
Вы можете достичь этого, используя трюк, добавить фиктивный компонент после своей строки и расширить его, чтобы заполнить вертикальное пространство. Также вы можете повторно использовать ограничения, не нужно создавать новый объект:
EDIT: ok забудьте трюк:( Правильный путь - это как Deon Botha и BenCole, я обновил свой код, используя якорь
Пожалуйста, НЕ принимайте этот ответ, принимайте Deon или Ben's
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);
}
}
Ответ 4
Возможно, я не отвечаю на ваш вопрос напрямую, но поверьте мне, что вы должны сделать пробную версию и erros на макетах с помощью IDE. Я лично предлагаю Netbeans. Там вы можете перетащить, а затем взглянуть на свойства. Сначала у вас будут значения по умолчанию, указанные в инспекторе свойств, и, следовательно, для этого будет создан менее сгенерированный код. Но тогда, как только вы начнете играть с макетами, вы сможете увидеть код и получить хорошее представление о том, как вы себя делаете.
Ответ 5
Это сработало для меня:
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;
}