2011-09-01 8 views
13

Hasta ahora logré evitar usar el código GridBagLayout (a mano) tanto como sea posible, pero no pude evitarlo esta vez y estoy leyendo el tutorial de SUN GridBagLayout Hasta ahora no está yendo bien. Creo que estoy mal entendiendo algo.
Por ejemplo I tratar el siguiente código (similar a la que en el post de SUN):¿Por qué GridBagLayout centra mis componentes en lugar de ponerlos en la esquina?

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

     // 
    } 

} 

tengo la etiqueta y el campo de texto una al lado de la otra en el centro del marco.
Pero esperaba que aparecieran en la esquina superior izquierda dado que la cuadrícula y la cuadrícula son 0 para la etiqueta.
Incluso si configuro constraints.anchor = GridBagConstraints.FIRST_LINE_START;, el resultado es el mismo.
¿Me equivoco aquí?
Desde el puesto del sol:

especificar la fila y la columna en la parte superior izquierda del componente. La columna más a la izquierda tiene la dirección gridx = 0 y la fila superior tiene la dirección gridy = 0.

+0

enlace está roto. – mre

+1

@mre: Enlace fijo – Cratylus

+3

http://madbean.com/anim/totallygridbag/ – keuleJ

Respuesta

11

Agregue constraints.weighty = 1; a las restricciones JLabel y constraints.anchor = GridBagConstraints.NORTHWEST; a las restricciones de TextField.

EDIT:

De Oracle de GridBagLayout guide:

Los números mayores indican esa fila o columna del componente deben conseguir más espacio. Para cada columna, el peso está relacionado con el mayor pesox especificado para un componente dentro de esa columna, dividiendo el peso de cada componente de la columna por columnas entre las columnas en las que se encuentra el componente. De manera similar, el peso de cada fila está relacionado con el peso más alto especificado para un componente dentro de esa fila. El espacio extra tiende a ir hacia la columna más a la derecha y la fila inferior.

+0

Funciona si también configuro' constraints.weighty = 1' en la etiqueta y ancle a la etiqueta 'FIRST_LINE_START'. Pero ¿Qué significa realmente el valor 1 en peso? – Cratylus

+2

Además, en su ejemplo de código, aparece esta línea de código, con comentario: 'c.weighty = 1.0; // solicite espacio vertical adicional' – BenCole

+0

Para JButton5, lo veo. Pero no creo que esta sea una buena presentación. De todos modos, por qué 1 y no 0.8, por ejemplo. No entiendo cómo se seleccionan estos números – Cratylus

2

Puede lograr esto utilizando un truco, agregar un componente ficticio después de su fila y expandirlo para llenar el espacio vertical. También puede volver a utilizar las restricciones, no es necesario crear un nuevo objeto:

EDITAR: ok olvidar el truco :(La manera correcta es como Deon Botha y BenCole dijeron, he actualizado mi código utilizando el ancla

favor nO sí aceptan esta respuesta, aceptar cualquiera de Deon o de Ben

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);      
} 
} 
+0

¿Pero por qué necesito este componente ficticio? ¿Deben los componentes colocarse en la esquina superior izquierda por el administrador de disposición? ¿Cuál es el significado de gridx = gridy = 0 entonces? – Cratylus

+0

Tienes razón, 'debería funcionar', pero GridBayLayout es pura maldad, bueno, en realidad es muy bueno ... simplemente complicado, no soy el purista, si funciona con una etiqueta ficticia, ¿por qué no usarla? – eon

+2

Alternativamente, podría establecer 'constraints.weighty = 1.0; constraints.anchor = GridBagConstraints.FIRST_LINE_START; ' – dbotha

2

no esté contestando a su pregunta directamente, pero confía en mí usted debe hacer su ensayo y erros en los diseños con un IDE . Yo personalmente sugiero Netbeans. Allí puedes arrastrar y soltar y luego echar un vistazo a la propiedades. Al principio tendría algunos valores predeterminados en el inspector de propiedades y, por lo tanto, menos código generado automáticamente para eso. Pero luego, una vez que comienzas a jugar con los diseños, puedes ver el código y obtener una buena comprensión de cómo haces lo que haces.

10

usted necesita leer más abajo en el tutorial de oscilación para la sección sobre weightX/weightY donde se afirma:

A menos que se especifique al menos un valor distinto de cero para weightx o pesada, todos los componentes se agrupan en el centro de su contenedor.

Has especificado un pesoX pero no un pesoY.

Editar, es más complicado de lo que pensaba. Parece que también necesita especificar:

constraints.anchor = GridBagConstraints.FIRST_LINE_START; 

para ambos componentes en adición a la pesada.

+0

La cita de SUN dice weightx o weighty (así que no esperaba que necesite ambas cosas). De todos modos intenté con weight = 1 para label y weighty = 0.5 para texto y de peso = 0.5 para ambos pero el mismo resultado – Cratylus

+0

weightx si para el posicionamiento horizontal. de peso es para el posicionamiento vertical. Usé 1.0 para ambos, así como FIRST_LINE_START para ambos y funcionó para mí. – camickr

+0

Sí, ahora funciona. Pero, ¿qué significa realmente el valor 1 en peso? No lo entiendo. También me parece (por la necesidad de anclaje) que de alguna manera la cuadrícula ya está allí y no está construida al colocar los componentes en él. ¿Correcto? – Cratylus

1

Esto funcionó para mí:

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