2012-07-05 10 views
7

Me gustaría tener un ScrolledComposite que tiene un padre con GridLayout pero la barra de desplazamiento no aparece, a menos que use FillLayout. Mi problema con FillLayout es que sus hijos toman partes iguales del espacio disponible.ScrolledComposite primario con GridLayout

En mi caso, hay dos widgets, el que está en la parte superior no debería ocupar más de 1/4 de la ventana y el ScrolledComposite debería ocupar el espacio restante. Sin embargo, ambos toman la mitad.

¿Hay alguna manera de usar un GridLayout con ScrolledComposite o es posible modificar el comportamiento de FillLayout?

Aquí está mi código:

private void initContent() { 

    //GridLayout shellLayout = new GridLayout(); 
    //shellLayout.numColumns = 1; 
    //shellLayout.verticalSpacing = 10; 
    //shell.setLayout(shellLayout); 
    shell.setLayout(new FillLayout(SWT.VERTICAL)); 

    searchComposite = new SearchComposite(shell, SWT.NONE); 
    searchComposite.getSearchButton().addListener(SWT.Selection, this); 

    ScrolledComposite scroll = new ScrolledComposite(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER); 
    scroll.setLayout(new GridLayout(1, true)); 

    Composite scrollContent = new Composite(scroll, SWT.NONE); 
    scrollContent.setLayout(new GridLayout(1, true)); 

    for (ChangeDescription description : getChanges(false)) { 
     ChangesComposite cc = new ChangesComposite(scrollContent, description); 
    } 

    scroll.setMinSize(scrollContent.computeSize(SWT.DEFAULT, SWT.DEFAULT)); 
    scroll.setContent(scrollContent); 
    scroll.setExpandVertical(true); 
    scroll.setExpandHorizontal(true); 
    scroll.setAlwaysShowScrollBars(true); 

} 
+3

Tengo el mismo problema, ¿alguna vez encontró una solución? –

Respuesta

1

Creo que lo que falta aquí es definir el GridData para los niños.

Un diseño controla la posición y el tamaño de los niños. Y cada clase de diseño tiene una clase de datos de diseño correspondiente que permite configurar cada niño específico dentro del diseño, si ocupan todo el espacio, cuántas células toman, etc.

Supongo que su diseño de cuadrícula podría tener 4 filas , con el widget encima tomando solo una celda y el otro tomando el resto (3). Esto se logra a través de la propiedad GridData.verticalSpan.

Eche un vistazo a Understanding Layouts in SWT y pruebe las diferentes propiedades de datos de diseño para ver lo que hacen.

+0

Lo siento, creo que no fui lo suficientemente claro. El principal problema es que ScrolledComposite no muestra su barra de desplazamiento si la coloco en un GridLayout, solo funciona con un FillLayout, pero no se ajusta a mis necesidades. Editaré la publicación original para dejar esto en claro. – gombost

+0

'FillLayout' obliga a los controles a ser del mismo tamaño. Inicialmente, los controles serán tan altos como el control más alto y tan ancho como el más ancho. Parece que este diseño hace que sus controles sean lo suficientemente grandes como para que 'ScrolledComposite' muestre las barras de desplazamiento. Pero cuando tienes un 'GridLayout' debes especificar la forma en que los controles se ubican en cada celda a través de los objetos' GridData'. Esto determina sus tamaños. Si no lo haces, tal vez el contenido no sea lo suficientemente grande. Adivinando O :) –

2

Además de setLayout(), es necesario llamar a setLayoutData(). En el siguiente ejemplo de código, observe cómo se construyen los objetos GridData y se pasan a cada una de las dos llamadas setLayoutData().

private void initContent(Shell shell) 
{ 
    // Configure shell 
    shell.setLayout(new GridLayout()); 

    // Configure standard composite 
    Composite standardComposite = new Composite(shell, SWT.NONE); 
    standardComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); 

    // Configure scrolled composite 
    ScrolledComposite scrolledComposite = new ScrolledComposite(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER); 
    scrolledComposite.setLayout(new GridLayout()); 
    scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 
    scrolledComposite.setExpandVertical(true); 
    scrolledComposite.setExpandHorizontal(true); 
    scrolledComposite.setAlwaysShowScrollBars(true); 

    // Add content to scrolled composite 
    Composite scrolledContent = new Composite(scrolledComposite, SWT.NONE); 
    scrolledContent.setLayout(new GridLayout()); 
    scrolledComposite.setContent(scrolledContent); 
} 
+1

Llamar a 'scrolledComposite.setLayout (...)' no hace nada. 'ScrolledComposite' anula el método y no establece un diseño, ya que tiene un' ScrolledCompositeLayout' por defecto. Por lo tanto, no sé qué ocurre en las llamadas '.setLayoutData' en sus hijos. –

2

NB! Esta respuesta se basa en Eclipse RAP, que podría comportarse de manera diferente a SWT normal.

Estaba luchando con el mismo problema hace un par de días. Tenía dos ScrolledComposite s en la misma página y necesitaba que el izquierdo no ocupara más espacio del necesario (incluso si el espacio estuviera disponible).

Mientras probando diferentes soluciones Noté que el comportamiento de un ScrolledComposite depende de su LayoutData de la siguiente manera:

  • Si el layoutData se establece en new GridData(SWT.LEFT, SWT.TOP, false, true), entonces el ScrolledComposite mantendrá a que se destina el tamaño independientemente de los padres Composite cambios de tamaño.
  • Si el layoutData está configurado en new GridData(SWT.LEFT, SWT.TOP, true, true), entonces el ScrolledComposite se contraerá/expandirá según los cambios de tamaño del elemento primario Composite. Esto también incluye ampliar el ancho deseado (lo que significa que las columnas se mantienen iguales).

Sobre la base de este comportamiento yo era capaz de resolver el problema mediante la adición de un oyente cambio de tamaño para los padres Composite que cambia el layoutData del ScrolledComposite la izquierda en base a la matriz Composite size.

Este enfoque se ilustra en el siguiente ejemplo:

public class LayoutingScrolledComposites extends AbstractEntryPoint { 
    public void createContents(Composite parent) {  
     parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 
     parent.setLayout(new GridLayout(2, false)); 

     ScrolledComposite sc1 = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL); 
     Composite c1 = new Composite(sc1, SWT.BORDER); 
     sc1.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true)); 
     c1.setLayout(new GridLayout(3, false)); 
     sc1.setContent(c1); 
     Label l1 = new Label (c1, SWT.BORDER); 
     l1.setText("Some text"); 
     l1 = new Label (c1, SWT.BORDER); 
     l1.setText("Some text"); 
     l1 = new Label (c1, SWT.BORDER); 
     l1.setText("Some text"); 
     c1.setSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT)); 

     ScrolledComposite sc2 = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL); 
     sc2.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true)); 
     Composite c2 = new Composite(sc1, SWT.BORDER); 
     c2.setLayout(new GridLayout(3, false)); 
     sc2.setContent(c2); 
     Label l2 = new Label (c2, SWT.BORDER); 
     l2.setText("Some text"); 
     l2 = new Label (c2, SWT.BORDER); 
     l2.setText("Some text"); 
     l2 = new Label (c2, SWT.BORDER); 
     l2.setText("Some text"); 
     c2.setSize(c2.computeSize(SWT.DEFAULT, SWT.DEFAULT)); 

     parent.addListener(SWT.Resize, new Listener() { 
      public void handleEvent(Event e) { 
       int sc1_x = sc1.getContent().getSize().x; 
       int sc2_x = sc2.getContent().getSize().x; 

       //Enable/Disable grabExcessHorizontalSpace based on whether both sc's would fit in the shell 
       if (LayoutingScrolledComposites.this.getShell().getSize().x > sc1_x+sc2_x) { 
        if (((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace) { 
         //sc1 does not change width in this mode 
         ((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace=false;       
        } 
       } else { 
        if (!((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace) { 
         //sc1 changes width in this mode 
         ((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace=true;      
        } 
       } 
       parent.layout(); //Needed so that the layout change would take effect during the same event 
      } 
     }); 
    } 
} 

Sin embargo este enfoque sí me parece un poco demasiado solución "hacker". Por lo tanto, me encantaría ver un mejor enfoque.

Cuestiones relacionadas