2011-04-18 13 views
5

Estoy intentando crear una ventana muy simple utilizando Java Layouts. Tengo tres elementos para organizar: un botón, una barra de progreso y una etiqueta. El botón debe estar centrado verticalmente, la barra de progreso debe ocupar todo el ancho y la etiqueta debe quedar alineada.Ayúdeme a comprender los problemas de alineación de BoxLayout

Aquí hay algo de código (acaba de asumir panel es el panel de contenido de un JFrame, y el botón, progressBar y la etiqueta de haber sido creado antes):

BoxLayout layout = new BoxLayout(pane, BoxLayout.Y_AXIS); 
pane.setLayout(layout); 
button.setAlignmentX(Component.CENTER_ALIGNMENT); 
pane.add(button); 
progressBar.setAlignmentX(Component.CENTER_ALIGNMENT); 
pane.add(progressBar); 
label.setAlignmentX(Component.LEFT_ALIGNMENT); 
pane.add(label); 

Cuando la prueba de la aplicación lo veo todo mal alineada y la pata : el botón y la etiqueta están indentados aleatoriamente, y si cambio el tamaño de la ventana, la cantidad de sangría cambia de forma extraña. La barra de progreso se ve bien (ancho completo).

Simplemente no entiendo lo que está pasando. ¿Puedes darme una pista?

+0

Personalmente, nunca confiar en setAlignmentX o setAlignmentY y tratar de evitarlos como la peste, también evito controladores de distribución que dependen exclusivamente de ellos. – jfpoilpret

+1

ahora entiendo por qué lo hace. ¿Qué alternativas sugerirías? – gd1

+0

Bueno, si tienes que apegarte a JDK puro, entonces probablemente usaría GridBagLayout en tu caso; eso funcionaría bien porque tu el diseño es simple (GBL comienza a ser complejo cuando su diseño tiene más componentes). De lo contrario, usaría DesignGridLayout. – jfpoilpret

Respuesta

5

Algunas veces necesitas ser un poco creativo y usar paneles anidados. Pero me gusta este enfoque mejor que tratar de aprender y memorizar todas las restricciones requeridas cuando se utilizan otros administradores de diseño (GridBagLayout, GroupLayout) diseñados para ser utilizados por el IDE de que generar código para usted.

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

public class BoxLayoutVertical extends JFrame 
{ 
    public BoxLayoutVertical() 
    { 
     Box box = Box.createVerticalBox(); 

     JButton button = new JButton("A button"); 
     button.setAlignmentX(Component.CENTER_ALIGNMENT); 
     box.add(button); 

     JProgressBar progressBar = new JProgressBar(0, 100); 
     progressBar.setAlignmentX(Component.CENTER_ALIGNMENT); 
     box.add(progressBar); 

     JPanel panel = new JPanel(new BorderLayout()); 
     JLabel label = new JLabel("A label"); 
     label.setAlignmentX(Component.LEFT_ALIGNMENT); 
     panel.add(label); 
     box.add(panel); 

     add(box, BorderLayout.NORTH); 
    } 

    public static void main(String[] args) 
    { 
     BoxLayoutVertical frame = new BoxLayoutVertical(); 
     frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     frame.setSize(300, 200); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
+0

La mejor solución de todas, porque no requiere bibliotecas adicionales, no hay clases adicionales, y está adaptada al mismo problema que estoy enfrentando. Sin embargo, seguiré las soluciones de otros usuarios para obtener más información sobre los diseños, pero en este caso estaba buscando un truco simple. – gd1

1

Tal vez su código es solo un fragmento, pero me falta una llamada al pack().

La codificación del diseño de giro a mano puede ser muy frustrante con los administradores de diseño estándar. Yo uso MiG Layout para ese propósito. Es sencillo y tienes un diseño agradable con solo unas pocas líneas de código. Si no estás obligado a utilizar BoxLayout, te sugiero que lo pruebes.

+0

Me gusta este diseño MiG, pero realmente no quiero vincular otros JAR y llevar las cosas a un nivel más "complicado" para una aplicación muy, muy simple como esta. – gd1

+0

@Giacomo: bastante bien;) El paquete "perdido"() no era el problema, entonces? –

+0

No, no fue ... – gd1

1

No use BoxLayout. Funciona solo para casos muy simples.

Para su caso, recomendaría GridBagLayout o (mi lista) GroupLayout favorita.


Para GroupLayout, he creado una subclase (LayoutHelper) con algunos métodos de utilidad y constructores útiles, lo que hace que escribir el diseño mucho más fácil.

Por supuesto, generalmente alineo todos los componentes en un grupo de la misma manera, por lo que no es tan corto en your case como lo sería en el caso simple.

LayoutHelper h = new LayoutHelper(pane); 

    h.setVerticalGroup 
     (h.sequential(button, progressBar, label)); 

    h.setHorizontalGroup 
     (((ParallelGroup)h.parallel()) 
      .addComponent(button, Alignment.CENTER) 
      .addComponent(progressBar) 
      .addComponent(label, Alignment.TRAILING)); 

Aquí está una captura de pantalla:

screenshot

Para un simple "todo alineado de la misma manera", el grupo horizontal se vería así:

h.setHorizontalGroup 
     (h.parallel (button, progressBar, label)); 

(opcionalmente con un primer argumento que indica la alineación).

+0

@Paulo you _hand-code_ GroupLayout? Entonces parece que tiene demasiado tiempo libre :-) – kleopatra

+0

@kleopatra: Tengo una clase de envoltura que lo relaciona un poco. (Añadiré cómo se vería con esto). A simple vista, GroupLayout no es agradable, pero no mucho mejor que GridBagLayout. –

+0

@Giacomo: No sé para qué BoxLayout es bueno, sinceramente. También tuve problemas para usarlo, especialmente la alineación ortogonal a su dirección de diseño. –

2

Para complementar mi comentario a la pregunta original, aquí es un fragmento que utiliza DesignGridLayout:

JButton button = new JButton("Button"); 
JProgressBar progressBar = new JProgressBar(); 
JLabel label = new JLabel("Label"); 

// The interesting stuff is in the next 4 lines 
DesignGridLayout layout = new DesignGridLayout(getContentPane()); 
layout.row().center().add(button).withOwnRowWidth(); 
layout.row().center().fill().add(progressBar); 
layout.row().left().add(label); 

pack(); 

que hace exactamente lo que está describen en su pregunta y no requiere ninguna llamada específica de cualquiera de los componentes .

7

BoxLayout no puede manejar diferentes alineaciones: ver http://download.oracle.com/javase/tutorial/uiswing/layout/box.html

citando de que el artículo: ". En general, todos los componentes controlados por un objeto de arriba a abajo BoxLayout deben tener la misma alineación X Del mismo modo, todos los componentes controlado por un boxlayout de izquierda a derecha generalmente debe tener la misma alineación Y."

+0

Gracias, por lo tanto BoxLayout es una mierda para mí. Seguiré todas tus sugerencias. – gd1

+0

¿Estás seguro de que no puede manejar diferentes alineaciones? http://docs.oracle.com/javase/tutorial/uiswing/layout/box.html –

+0

@AndrewS: ¿a qué parte del tutorial se está refiriendo cuando sugiere que Box puede manejar diferentes alineamientos? ¿La solución implica el uso de Box.createHorizontalGlue(), o es posible de otra manera? – mins

Cuestiones relacionadas