2010-07-04 15 views
10

Come faresti per ottenere un gui dall'aspetto decente generato quando non sai quanti componenti avrai e quanto saranno grandi?Layout variabile in Swing

Un utente, ad esempio, immette quanti campi di testo desiderano e quali di quei campi di testo sono raggruppati in riquadri con bordi e il programma genera questo.

Sto usando GridLayout, ma il problema è che rende tutte le celle della stessa larghezza e altezza, che va bene quando tutti i componenti hanno le stesse dimensioni, ma quando io, ad esempio, ho un campo di testo e un pannello bordato con più campi, il campo di testo viene allungato o il pannello viene compresso.

Vorrei che tutti i componenti abbiano le dimensioni minime, ma comunque, si sa, utilizzabili.

Example of how it is now, using GridLayout, tutti i campi sono normali, campi JText a una riga in cui la data del pannello è completamente compressa (contiene tre campi) ei campi di primo livello sono molto grandi. Qualcuno ha qualche indicazione?

risposta

13

MiGLayout ha un sacco di fascino, ma BoxLayout è un'alternativa.

image

import java.awt.*; 
import java.util.List; 
import java.util.ArrayList; 
import javax.swing.*; 

public class BoxTest extends JPanel { 

    private List<JTextField> fields = new ArrayList<JTextField>(); 

    public BoxTest() { 
     this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 
     this.add(createPane(3, "One ", Color.red)); 
     this.add(createPane(3, "Two ", Color.green)); 
     this.add(createPane(10, "Three ", Color.blue)); 
    } 

    private JPanel createPane(int n, String s, Color c) { 
     JPanel outer = new JPanel(); 
     outer.setLayout(new BoxLayout(outer, BoxLayout.Y_AXIS)); 
     outer.setBorder(BorderFactory.createLineBorder(c, 2)); 
     for (int i = 0; i < n; i++) { 
      JPanel inner = new JPanel(); 
      inner.setLayout(new BoxLayout(inner, BoxLayout.X_AXIS)); 
      JLabel label = new JLabel(s + i + ":", JLabel.RIGHT); 
      label.setPreferredSize(new Dimension(80, 32)); 
      inner.add(label); 
      JTextField tf = new JTextField("Stackoverflow!", 32); 
      inner.add(tf); 
      fields.add(tf); 
      outer.add(inner); 
     } 
     return outer; 
    } 

    private void display() { 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JScrollPane jsp = new JScrollPane(this, 
      JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 
      JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 
     this.validate(); 
     Dimension d = this.getPreferredSize(); 
     d.height /= 2; 
     jsp.getViewport().setPreferredSize(d); 
     jsp.getVerticalScrollBar().setUnitIncrement(
      this.getPreferredSize().height/fields.size()); 
     f.add(jsp); 
     f.pack(); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new BoxTest().display(); 
      } 
     }); 
    } 
} 
+0

L'unico problema che ho ora è che quando le etichette in una scatola sono diverse, le caselle di testo sono di dimensioni diverse, come ad esempio http://grab.by/5gpW. c'è un modo per aggiustarlo senza scrivere il mio LayoutManager? – thepandaatemyface

+0

@thepandaatemyface: ho aggiornato l'esempio per mostrare un approccio. – trashgod

+0

@mKorbel utilizza _mot juste_: l'impostazione della dimensione preferita dell'etichetta è un trucco arbitrario. Un approccio più preciso potrebbe trovare l'etichetta più lunga utilizzando una delle tecniche discusse [qui] (http://stackoverflow.com/questions/5979795/how-to-calculate-the-number-of-rows-and-columns-in -Ogni-fila-un-text-prende-in-aj/5.998.117 # 5.998.117). – trashgod

3

Vorrei dare un'occhiata a miglayout. È molto più utile di tutti i gestori di layout integrati.

2

Sì, MiGLayout è bello. Puoi fare praticamente qualsiasi cosa con esso.

3

L'obiettivo generale - "dimensioni componenti utilizzabili" si scontra con "numero sconosciuto". Rendi il numero abbastanza grande e non si adatta a nessuno schermo.

Overthink se non sarebbe meglio usare JTables (le celle possono essere modificate) in combinazione con un JScrollPanel. Se vuoi/devi mantenere il tuo approccio alla generazione dei componenti, metti l'intero JPanel che contiene i tuoi componenti in un JScrollPane, in questo modo i componenti non saranno schiacciati.

1

dimensione minima in AWT e Swing è di solito inutile. Suggerisco di aggiungere un pannello per delegare le dimensioni minime alla dimensione preferita originale e possibilmente aggiungere un po 'alla nuova dimensione preferita. In GridBagLayout aggiungi pesi dove vuoi spazio aggiuntivo per andare nelle dimensioni normali. Come menziona Durandal, spuntano le barre di scorrimento attorno alle battute della finestra di livello superiore schiacciando il layout o uscendo dallo schermo (sto scrivendo questo su un netbook, quindi conosco le finestre più grandi dello schermo).