2011-12-13 37 views
9

Estoy usando GroupLayout para administrar componentes en algunos formularios de entrada de datos generados dinámicamente. El diseño es más o menos así:Swing GroupLayout: cambio de tamaño y limitación de tamaños de componentes

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

estoy usando 2 grupos paralelos para el diseño horizontal, y un solo grupo secuencial para la disposición vertical. En su mayor parte, todo está funcionando bien.

Quiero limitar el ancho máximo de las etiquetas (que son solo casos de JLabel) a 1/3 del ancho del elemento principal JFrame. Si el JFrame tuviera un tamaño fijo, esto sería trivial, pero tengo que lidiar con el cambio de tamaño.

Estoy recogiendo ComponentListener.componentResized() eventos del JFrame pero estoy un poco atascado en qué hacer una vez que recibo tal evento.

He intentado este enfoque sin ninguna suerte:

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

¿Puede alguien sugerir una manera de limitar el ancho de las etiquetas que van a trabajar?

Probablemente podría reconstruir el diseño desde cero cada vez, pero creo que debería haber una manera más simple.

+0

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

+0

¿Hay alguna razón para que una etiqueta crezca más grande que el tamaño preferido de la etiqueta más grande? – trashgod

+0

@trashgod No, no hay. Quiero establecer un límite superior en el ancho de las etiquetas, no un límite mínimo. He editado la pregunta para aclararlo. – vaughandroid

Respuesta

27

En este ejemplo, GroupLayout puede simplemente confiar en el tamaño preferido de la etiqueta, sin tener que recurrir a ningún método setXXXSize(). En este enfoque,

  • El espacio para las etiquetas siempre se adapta a la etiqueta más grande.
  • Los campos de texto se pueden redimensionar de una manera útil.
  • El resultado es correcto en todas las plataformas y fuentes.
  • "No es necesario especificar nada para la mayoría de los componentes ... porque los propios componentes tienen el comportamiento de cambio de tamaño deseado como predeterminado." - How to Use GroupLayout: Component Size and Resizability

El uso de GroupLayout.Alignment.TRAILING de justificación a la derecha de las etiquetas es una personal preferencia, y he agregado un segundo panel para mostrar cómo funciona anidado en otro diseño.

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

Ese es un ejemplo muy claro, así que gracias por eso. El código que ha proporcionado es casi idéntico al que ya he implementado, pero el bit clave era "No es necesario especificar nada para la mayoría de los componentes ... porque los componentes mismos tienen el comportamiento de cambio de tamaño deseado como predeterminado". ". Me imagino que mis etiquetas deben ser implementaciones personalizadas que anulen getPreferredSize(). – vaughandroid

+0

Excelente; ver también esto (menos flexible) [ejemplo] (http://stackoverflow.com/a/3175280/230513). – trashgod

+1

Vea también esto (_more_ flexible) [ejemplo] (http://stackoverflow.com/a/14858272/230513). – trashgod

Cuestiones relacionadas