2012-07-05 5 views
7

Я хотел бы иметь ScrolledComposite, у которого есть родительский элемент с GridLayout, но полоса прокрутки не отображается, если я не использую FillLayout. Моя проблема с FillLayout заключается в том, что ее дети принимают равные части доступного пространства.ScrolledComposite parent с GridLayout

В моем случае есть два виджета, один сверху должен занимать не более 1/4 окна, а ScrolledComposite должен занимать оставшееся пространство. Тем не менее, они оба берут половину.

Есть ли способ использовать GridLayout с ScrolledComposite или можно изменить поведение FillLayout?

Вот мой код:

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

У меня такая же проблема, вы когда-нибудь находили решение? –

ответ

1

Я думаю, что вам не хватает здесь, чтобы определить GridData для детей.

Макет контролирует положение и размер детей. И каждый класс макета имеет соответствующий класс данных макета, который позволяет настраивать каждого конкретного ребенка в макете, если они заполняют все пространство, сколько ячеек они берут и т. Д.

Я предполагаю, что ваш макет сетки может иметь 4 строки , с виджетами сверху, беря только одну ячейку, а другой ребенок берет остальных (3). Это достигается за счет имущества GridData.verticalSpan.

Посмотрите на Understanding Layouts in SWT и попробуйте различные свойства данных макета, чтобы увидеть, что они делают.

+0

Извините, я думаю, что я был недостаточно ясен. Основная проблема заключается в том, что ScrolledComposite не показывает свою полосу прокрутки, если я помещаю ее в GridLayout, она работает только с FillLayout, но она не соответствует моим потребностям. Я отредактирую оригинальное сообщение, чтобы это было ясно. – gombost

+0

Элементы управления FillLayout' имеют одинаковый размер. Первоначально элементы управления будут такими же высокими, как и самый высокий элемент управления, а также самый широкий. Кажется, что этот макет заставляет ваши элементы управления быть достаточно большими, чтобы 'ScrolledComposite' отображал полосы прокрутки. Но когда у вас есть «GridLayout», вы должны указать способ, которым элементы управления располагаются в каждой ячейке через объекты «GridData». Это определяет их размеры. Если вы этого не сделаете, возможно, контент недостаточно велик. Просто угадать O :) –

2

В дополнение к setLayout() необходимо вызвать setLayoutData(). В следующем примере кода рассмотрите, как объекты GridData создаются и передаются каждому из двух вызовов 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

Вызов 'scrolledComposite.setLayout (...)' ничего не делает. 'ScrolledComposite' переопределяет этот метод и не устанавливает макет, поскольку он по умолчанию имеет' ScrolledCompositeLayout'. Поэтому не знаю, что происходит в '.setLayoutData' вызывает его дочерние элементы. –

2

NB! Этот ответ основан на Eclipse RAP, который может вести себя иначе, чем обычный SWT.

Я боролся с тем же вопросом пару дней назад. У меня было две ScrolledComposite с на той же странице, и мне было нужно, чтобы левая часть не занимала больше места, которое было необходимо (даже если бы пространство было доступно).

Хотя пробуя различные решения я заметил, что поведение ScrolledComposite зависит от его LayoutData следующим образом:

  • Если layoutData установлен в new GridData(SWT.LEFT, SWT.TOP, false, true), то ScrolledComposite будет держать это предназначено размер независимо от родительского Composite изменения размера.
  • Если layoutData установлен в new GridData(SWT.LEFT, SWT.TOP, true, true), то ScrolledComposite будет сжиматься/расширяться в соответствии с изменениями размера родителя Composite. Это также включает расширение до большей ширины, что было желательно (это означает, что столбцы поддерживаются равными).

На основе такого поведения я был в состоянии решить эту проблему, добавив изменения размера слушателя к родителю Composite, который изменяет layoutData левого ScrolledComposite на основе родительского Composite size.

Этот подход проиллюстрирован на следующем примере:

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

Однако этот подход не кажется мне слишком «хаком» решение. Поэтому я хотел бы видеть лучший подход.