2011-09-01 8 views
13

Finora sono riuscito a evitare il più possibile il GridBagLayout (a mano), ma non ho potuto evitarlo questa volta e sto leggendo il tutorial del SUN GridBagLayout Finora non sta andando bene. Penso di essere qualcosa di incomprensibile.
Ad esempio provo il seguente codice (simile a quello nel post di SUN):Perché GridBagLayout centra i miei componenti invece di metterli nell'angolo?

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

     // 
    } 

} 

ottengo l'etichetta e il campo di testo uno accanto all'altro nel centro del telaio.
Ma mi aspettavo che si sarebbero mostrati nell'angolo in alto a sinistra poiché la griglia e la griglia erano 0 per l'etichetta.
Anche se ho impostato lo constraints.anchor = GridBagConstraints.FIRST_LINE_START; lo stesso risultato.
Mi sbaglio qui?
dal post del sole:

specificare la riga e la colonna in alto a sinistra del componente. La colonna a sinistra ha l'indirizzo gridx = 0 e la riga superiore ha l'indirizzo gridy = 0.

+0

legame è spezzato. – mre

+1

@mre: collegamento fisso – Cratylus

+3

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

risposta

11

Aggiungere constraints.weighty = 1; ai vincoli JLabel e constraints.anchor = GridBagConstraints.NORTHWEST; ai vincoli Campo di testo.

EDIT:

da Oracle di GridBagLayout guide:

numeri più grandi indicano che riga o colonna del componente dovrebbe avere più spazio. Per ogni colonna, il peso è correlato al più alto pesox specificato per un componente all'interno di quella colonna, con il peso di ciascun componente a più colonne che viene diviso in qualche modo tra le colonne in cui si trova il componente. Analogamente, il peso di ogni riga è correlato al peso più elevato specificato per un componente all'interno di quella riga. Lo spazio extra tende a spostarsi verso la colonna più a destra e la riga inferiore.

+0

Funziona anche impostando' constraints.weighty = 1' sull'etichetta e ancoraggio all'etichetta 'FIRST_LINE_START'.But cosa significa in realtà il valore 1 in peso? – Cratylus

+2

Inoltre, nel loro esempio di codice, questa riga di codice, con commento, viene visualizzata: 'c.weighty = 1.0; // richiedi uno spazio verticale extra' – BenCole

+0

Per JButton5, lo vedo.Ma non penso che questa sia una buona presentazione.Anche perché 1 e non 0.8 per esempio. Non capisco come siano selezionati questi numeri – Cratylus

2

È possibile ottenere ciò utilizzando un trucco, aggiungere un componente fittizio dopo la riga ed espanderlo per riempire lo spazio verticale. Inoltre puoi riutilizzare i vincoli, non c'è bisogno di creare un nuovo oggetto:

MODIFICA: ok dimentica il trucco :(Il modo giusto è come Deon Botha e BenCole hanno detto, ho aggiornato il mio codice usando l'ancora

prega nON accettare questa risposta, accetta sia di Deon o 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

Ma perché ho bisogno di questo componente fittizio? I componenti dovrebbero essere posizionati nell'angolo in alto a sinistra dal gestore di layout? Qual è il significato di gridx = gridy = 0 allora? – Cratylus

+0

Hai ragione, 'dovrebbe funzionare' ma GridBayLayout è puro male, beh, in realtà è molto buono ... solo complicato, non sono il purista, se funziona con un'etichetta fittizia, allora perché non usarlo? – eon

+2

In alternativa è possibile impostare 'constraints.weighty = 1.0; constraints.anchor = GridBagConstraints.FIRST_LINE_START; ' – dbotha

2

io non sia rispondere alla tua domanda direttamente, ma la fiducia di me si dovrebbe fare la versione di prova e erros sui tracciati con un IDE Personalmente suggerisco Netbeans. Qui puoi trascinare e rilasciare e quindi dare un'occhiata al proprietà. All'inizio avresti alcuni valori predefiniti dati nella finestra di ispezione proprietà e quindi meno codice generato automaticamente per quello. Ma poi, una volta che inizi a giocare con i layout, puoi vedere il codice e ottenere una buona comprensione di sapere cosa fai come fai.

10

avete bisogno di leggere più in basso nel tutorial Altalena per la sezione weightX/weightY dove si afferma:

A meno che non si specifica almeno un valore diverso da zero per weightx o pesante, tutti i componenti ciuffo insieme nel centro del loro contenitore.

Hai specificato un pesoX ma non un pesoY.

Modifica, è più complicato di quanto pensassi. Sembra inoltre necessario specificare:

constraints.anchor = GridBagConstraints.FIRST_LINE_START; 

per entrambi i componenti in aggiunta al peso.

+0

La citazione da SUN dice weightx o pesante (quindi non mi aspettavo che ne avesse bisogno entrambi). In ogni caso ho provato peso = 1 per etichetta e peso = 0,5 per testo e peso = 0,5 per entrambi ma stesso risultato – Cratylus

+0

weightx se per il posizionamento orizzontale. pesante è per il posizionamento verticale. Ho usato 1.0 per entrambi e FIRST_LINE_START per entrambi e ha funzionato per me. – camickr

+0

Sì, ora funziona.Ma cosa significa in realtà il valore 1 in pesante? Io non capisco.Inoltre mi sembra (per la necessità di ancoraggio) che in qualche modo la griglia è già lì e non costruita ponendo i componenti su di esso.Right? – Cratylus

1

questo ha funzionato per me:

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