2011-01-15 41 views
9

Estoy trabajando en una GUI más grande con Java y me estoy enojando con los administradores de diseño.¿Cómo establecer el tamaño del componente con GridLayout? ¿Hay una mejor manera?

Tengo un "Panel de configuración" con un número variable de JComponentes (Etiquetas, Botones, JSpinners, JSliders, ...). Sólo quiero lo siguiente:

JLabel < -> JComponent

JLabel < -> JComponent

JLabel < -> JComponent

...

Mi cuadro tiene un tamaño de 500px, por lo que hay suficiente espacio para muchos componentes. Desafortunadamente, GridLayout siempre extiende el tamaño de los Componentes a todo el Panel, incluso si configuro un MaximumSize para cada componente. Parece estúpido si solo hay dos botones, cada uno con una altura de 250px.

Intenté el diseño de flujo, pero no puedo encontrar una manera de hacer nuevas líneas correctamente. Intenté BoxLayout.Y_AXIS, pero los componentes están siempre centrados, y Label y Component no están en la misma línea.

¿Alguien sabe una buena y breve forma con LayoutManagers para manejar esto correctamente?

+0

¿Alguna vez obtuvo una respuesta decente a esto? Originalmente estaba usando BoxLayout y me encontré con este problema exacto, por lo que todos me dijeron que usara GridLayout, y tengo el mismo problema que el anterior. Ahora sus comentaristas dicen que vayan a GridBagLayout. ¿Cuál fue la solución real? – theJollySin

+1

Desafortunadamente, nunca obtuve mejores respuestas que estas aquí. Creo que finalmente estaba usando GridBagLayout, pero actualmente no me interesan mucho las GUI de Java. – Blackbam

+0

Al final, la única solución que funcionó para mí fue configurar manualmente las posiciones de todo. No es tan difícil, y me hace pensar que todos estos diseños preestablecidos son realmente muy limitados: uso-caso. – theJollySin

Respuesta

4

No utilice GridLayout para algo que no estaba destinado a hacer. Me parece que GridBagLayout sería más apropiado para ti, o eso o MigLayout (aunque tendrás que descargarlo primero, ya que no forma parte de Java estándar). O eso o combine los administradores de diseño como BoxLayout para las líneas y GridLayout para contener todas las filas.

Por ejemplo, el uso de GridBagLayout:

import java.awt.*; 
import javax.swing.*; 

public class LayoutEg1 extends JPanel{ 
    private static final int ROWS = 10; 

    public LayoutEg1() { 
     setLayout(new GridBagLayout()); 
     for (int i = 0; i < ROWS; i++) { 
      GridBagConstraints gbc = makeGbc(0, i); 
      JLabel label = new JLabel("Row Label " + (i + 1)); 
      add(label, gbc); 

      JPanel panel = new JPanel(); 
      panel.add(new JCheckBox("check box")); 
      panel.add(new JTextField(10)); 
      panel.add(new JButton("Button")); 
      panel.setBorder(BorderFactory.createEtchedBorder()); 
      gbc = makeGbc(1, i); 
      add(panel, gbc); 
     } 
    } 

    private GridBagConstraints makeGbc(int x, int y) { 
     GridBagConstraints gbc = new GridBagConstraints(); 
     gbc.gridwidth = 1; 
     gbc.gridheight = 1; 
     gbc.gridx = x; 
     gbc.gridy = y; 
     gbc.weightx = x; 
     gbc.weighty = 1.0; 
     gbc.insets = new Insets(5, 5, 5, 5); 
     gbc.anchor = (x == 0) ? GridBagConstraints.LINE_START : GridBagConstraints.LINE_END; 
     gbc.fill = GridBagConstraints.HORIZONTAL; 
     return gbc; 
    } 

    private static void createAndShowUI() { 
     JFrame frame = new JFrame("Layout Eg1"); 
     frame.getContentPane().add(new LayoutEg1()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 
4

Para diseños más complejos solía usar GridBagLayout, que es más complejo, pero ese es el precio. Hoy, probablemente verifique MiGLayout.

12

Una alternativa a otros diseños, podría ser poner su panel con el GridLayout, dentro de otro panel que es un FlowLayout. De esa forma, su espacio permanecerá intacto, pero no se expandirá por todo el espacio disponible.

+1

+1, sí, nunca se ve obligado a utilizar un solo administrador de diseño. Un consejo simple como este puede ayudar en muchos casos. – camickr

+0

Esta respuesta es excelente en su simplicidad, funcionó perfectamente para mí también, aparte de eso para tratar con algunos problemas de alineación horizontal. Puse mi GridLayout dentro de un BoxLayout en lugar de un FlowLayout, pero el mismo principio. – nigelg

3

En mi proyecto logré usar GridLayout y los resultados son muy estables, sin parpadeos y con una barra de desplazamiento vertical que funciona perfectamente.

Primero creé un JPanel para la configuración; en mi caso, es una grilla con una fila para cada parámetro y dos columnas: la columna izquierda es para las etiquetas y la columna derecha es para los componentes. Creo que tu caso es similar.

JPanel yourSettingsPanel = new JPanel(); 
yourSettingsPanel.setLayout(new GridLayout(numberOfParams, 2)); 

entonces pueblan este panel iterando mis parámetros y alterna entre añadir un JLabel y la adición de un componente.

for (int i = 0; i < numberOfParams; ++i) { 
    yourSettingsPanel.add(labels[i]); 
    yourSettingsPanel.add(components[i]); 
} 

Para evitar yourSettingsPanel se extienda a todo el contenedor I primero envuelve en la región norte de un panel simulado, que llamé northOnlyPanel.

JPanel northOnlyPanel = new JPanel(); 
northOnlyPanel.setLayout(new BorderLayout()); 
northOnlyPanel.add(yourSettingsPanel, BorderLayout.NORTH); 

Por último, me enrolle el northOnlyPanel en un JScrollPane, que debe comportarse bien casi en cualquier lugar.

JScrollPane scroll = new JScrollPane(northOnlyPanel, 
            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 
            JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 

Es muy probable que desee mostrar este JScrollPane extendido dentro de un JFrame; puedes añadir a un BorderLayout JFrame, en la región CENTRO:

window.add(scroll, BorderLayout.CENTER); 

En mi caso lo puse en la columna izquierda de un GridLayout (1, 2) del panel, y utilizo la columna de la derecha para mostrar contextual ayuda para cada parámetro

JTextArea help = new JTextArea(); 
help.setLineWrap(true); 
help.setWrapStyleWord(true); 
help.setEditable(false); 

JPanel split = new JPanel(); 
split.setLayout(new GridLayout(1, 2)); 
split.add(scroll); 
split.add(help); 
+0

La combinación de un GridLayout dentro de un BorderLayout funciona muy bien para obtener las características de un GridLayout sin estirar sus contenidos de forma no natural. ¡Buena idea! – David

Cuestiones relacionadas