2010-07-04 9 views
10

¿Cómo harías para obtener una interfaz gráfica de usuario de aspecto decente cuando no sabes cuántos componentes tendrás y qué tan grandes serán?Diseño variable en Swing

Un usuario, por ejemplo, ingresa la cantidad de campos de texto que desea y cuáles de esos campos de texto se agrupan en paneles delimitados y el programa genera esto.

He estado usando GridLayout, pero el problema es que hace que todas las celdas tengan el mismo ancho y alto, lo cual está bien cuando todos los componentes tienen el mismo tamaño, pero cuando yo, por ejemplo, tengo un campo de texto y panel bordeado con campos múltiples, ya sea que el campo de texto se estira o el panel se aprieta.

Me gustaría que todos los componentes tengan su tamaño mínimo, pero aún así, usted sabe, utilizable.

Example of how it is now, using GridLayout, todos los campos son normales, JTextFields de una sola línea donde el panel titulado fecha está totalmente comprimido (tiene tres campos) y los campos de primer nivel son demasiado grandes. Alguien tiene punteros?

Respuesta

13

MiGLayout tiene un montón de atractivo, pero BoxLayout es una 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

El único problema que tengo ahora es que cuando las etiquetas en una caja son diferentes, las cajas de texto tienen un tamaño diferente, por ejemplo, http://grab.by/5gpW. ¿Hay alguna manera de arreglar esto sin escribir mi propio LayoutManager? – thepandaatemyface

+0

@thepandaatemyface: actualicé el ejemplo para mostrar un enfoque. – trashgod

+0

@mKorbel usa _mot juste_: establecer el tamaño preferido de la etiqueta es un truco arbitrario. Un enfoque más preciso podría encontrar la etiqueta más larga usando una de las técnicas discutidas [aquí] (http://stackoverflow.com/questions/5979795/how-to-calculate-the-number-of-rows-and-columns-in -each-row-a-text-takes-in-aj/5998117 # 5998117). – trashgod

3

Me gustaría ver miglayout. Es mucho más útil que cualquiera de los administradores de diseño incorporados.

3

Su objetivo general: "tamaños de componentes utilizables" choca con "número desconocido". Haga el número lo suficientemente grande y no se ajustará a ninguna pantalla.

Overthink si no estaría mejor con el uso de JTables (las celdas pueden ser editables) en conjunción con un JScrollPanel. Si desea/debe mantener su enfoque de generación de componentes, coloque todo el JPanel que contiene sus componentes en un JScrollPane, de esa manera los componentes no se comprimirán demasiado.

1

tamaño mínimo de AWT y Swing es generalmente inútil. Sugiero agregar un panel para delegar el tamaño mínimo al tamaño preferido original, y posiblemente agregar un poco al nuevo tamaño preferido. En GridBagLayout agrega pesas donde quieras espacio adicional para ir en el tamaño normal. Como menciona Durandal, aparecer barras de desplazamiento alrededor de la ventana del nivel superior supera el diseño o la salida de la pantalla (estoy escribiendo esto en una netbook, así que sé sobre ventanas más grandes que la pantalla).