2011-12-13 10 views
9

Sto utilizzando GroupLayout per gestire i componenti in alcuni moduli di input di dati generati dinamicamente. Il layout è più o meno in questo modo:Swing GroupLayout: ridimensionamento e limitazione delle dimensioni dei componenti

*-----------------------------------------------* 
| label A  | field A      | 
| label B  | field B      | 
| label C  | field C      | 
*-----------------------------------------------* 

sto usando 2 gruppi paralleli per la disposizione orizzontale e un singolo gruppo sequenziale per il layout verticale. Per la maggior parte, tutto funziona perfettamente.

Voglio limitare la larghezza massima delle etichette (che sono solo esempi di JLabel) a 1/3 della larghezza del genitore JFrame. Se lo JFrame fosse di dimensioni fisse, sarebbe banale, ma devo gestirlo ridimensionandolo.

Sto ricevendo gli eventi ComponentListener.componentResized() dallo JFrame ma sono un po 'bloccato su cosa fare una volta ricevuto questo evento.

Ho provato questo approccio senza alcuna fortuna:

public void componentResized(ComponentEvent e) { 
    int maxW = parentFrame.getWidth()/3; 
    for (JLabel l : labels) { 
     l.setMaximumSize(// have also tried setSize() and setPreferredSize() 
      new Dimension(
       Math.min(l.getSize().width, maxW), 
       l.getMaximumSize().height)); 
    } 
    groupLayout.invalidateLayout(getContentSpace()); 
} 

Qualcuno può suggerire un modo per limitare la larghezza delle etichette che funzionano?

Probabilmente potrei ricostruire il layout da zero ogni volta, ma sento che dovrebbe esserci un modo più semplice.

+0

non setXXSize mai: http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi – kleopatra

+0

C'è qualche motivo per cui un'etichetta cresce più grande della dimensione preferita dell'etichetta più grande? – trashgod

+0

@trashgod No non c'è. Sto volendo impostare un limite superiore sulla larghezza delle etichette, non un limite minimo. Ho modificato la domanda per renderla più chiara. – vaughandroid

risposta

27

In questo esempio, GroupLayout può semplicemente fare affidamento sulla dimensione preferita dell'etichetta, senza dover ricorrere a alcun metodo setXXXSize(). In questo approccio,

  • Lo spazio per le etichette accoglie sempre l'etichetta più grande.
  • I campi di testo sono ridimensionabili in modo utile.
  • Il risultato è corretto su piattaforme e tipi di carattere.
  • "Non è necessario specificare niente per la maggior parte dei componenti ... perché i componenti stessi hanno il comportamento di ridimensionamento desiderata come predefinita." - How to Use GroupLayout: Component Size and Resizability

L'uso di GroupLayout.Alignment.TRAILING a destra giustificare le etichette è un personal preferenza, e ho aggiunto un secondo pannello per mostrare come funziona annidato in un altro layout.

enter image description here

import java.awt.EventQueue; 
import javax.swing.BorderFactory; 
import javax.swing.Box; 
import javax.swing.BoxLayout; 
import javax.swing.GroupLayout; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 

/** @see http://stackoverflow.com/questions/8492065 */ 
public class GroupPanel extends JPanel { 

    private JLabel label1 = new JLabel("Primary:"); 
    private JTextField field1 = new JTextField(16); 
    private JLabel label2 = new JLabel("Secondary:"); 
    private JTextField field2 = new JTextField(16); 
    private JLabel label3 = new JLabel("Tertiary:"); 
    private JTextField field3 = new JTextField(16); 

    public GroupPanel(int n) { 
     this.setBorder(BorderFactory.createTitledBorder("Panel " + n)); 
     GroupLayout layout = new GroupLayout(this);   
     this.setLayout(layout); 
     layout.setAutoCreateGaps(true); 
     layout.setAutoCreateContainerGaps(true); 
     layout.setHorizontalGroup(layout.createSequentialGroup() 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) 
       .addComponent(label1) 
       .addComponent(label2) 
       .addComponent(label3)) 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) 
       .addComponent(field1) 
       .addComponent(field2) 
       .addComponent(field3)) 
     ); 
     layout.setVerticalGroup(layout.createSequentialGroup() 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) 
       .addComponent(label1) 
       .addComponent(field1)) 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) 
       .addComponent(label2) 
       .addComponent(field2)) 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) 
       .addComponent(label3) 
       .addComponent(field3)) 
     ); 
    } 

    private static void display() { 
     JFrame f = new JFrame("GroupPanel"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLayout(new BoxLayout(f.getContentPane(), BoxLayout.Y_AXIS)); 
     f.add(new GroupPanel(1)); 
     f.add(new GroupPanel(2)); 
     f.add(Box.createVerticalGlue()); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

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

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

Questo è un esempio molto chiaro, quindi grazie per quello. Il codice che hai fornito è quasi identico a quello che ho già implementato io stesso, ma il bit chiave era "Non è necessario specificare nulla per la maggior parte dei componenti ... perché i componenti stessi hanno il comportamento di ridimensionamento desiderato come predefinito. ". Immagino che le mie etichette debbano essere implementazioni personalizzate che sovrascrivono getPreferredSize(). – vaughandroid

+0

Eccellente; guarda anche questo (meno flessibile) [esempio] (http://stackoverflow.com/a/3175280/230513). – trashgod

+1

Vedere anche questo (_more_ flexible) [esempio] (http://stackoverflow.com/a/14858272/230513). – trashgod

Problemi correlati