SWT Секционированный стол и прокрутка - PullRequest
4 голосов
/ 25 марта 2012

Я пытаюсь отобразить таблицу SWT внутри раздела формы, но у меня возникают проблемы с изменением размера и прокруткой столбцов.

Я приложил пример кода, который можно поместить в ViewPart Eclipse-подключения (3.7 - это версия, которую я использую). Если вы запустите код и измените размер столбца вправо, таблица получит горизонтальную полосу прокрутки (что я и хочу).

Теперь, если я сверну раздел (щелкните стрелку слева от «Заголовка раздела»), представление получит горизонтальную полосу прокрутки (что мне не нужно). Снова расширяя раздел, прокрутка представления остается, и теперь у таблицы больше нет таковой.

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

public class ExampleView extends ViewPart {
  /** Note: other fields / methods removed to condense snippet */

  private FormToolkit toolkit;
  private ScrolledForm scrolledForm;

  public void createPartControl(Composite parent) {
            parent.setLayout(new FillLayout());

    toolkit = new FormToolkit(parent.getDisplay());
    scrolledForm = toolkit.createScrolledForm(parent);
    scrolledForm.setExpandHorizontal(true);
    scrolledForm.setText("Form Title");

    scrolledForm.getBody().setLayout(new FillLayout());
    // here's the modification for the solution
    scrolledForm.getBody().setLayout(
            new BoundedLayout(new FillLayout(), true));

    final Section section = toolkit.createSection(scrolledForm.getBody(),
            Section.DESCRIPTION | Section.TITLE_BAR | Section.TWISTIE
                    | Section.EXPANDED);

    section.addExpansionListener(new ExpansionAdapter() {
        public void expansionStateChanged(ExpansionEvent e) {
            scrolledForm.reflow(true);
        }
    });
    section.setText("Section Title");

    final Table table = toolkit.createTable(section, SWT.FULL_SELECTION);
    TableViewer viewer = new TableViewer(table);

    table.setLinesVisible(true);
    table.setHeaderVisible(true);
    table.setItemCount(10);

    TableColumn col = new TableColumn(table, SWT.NONE);
    col.setText("Column A");
    col.setWidth(150);
    col.setResizable(true);
    col.setMoveable(true);

    TableColumn col2 = new TableColumn(table, SWT.NONE);
    col2.setText("Column B");
    col2.setWidth(150);
    col2.setResizable(true);
    col2.setMoveable(true);

    section.setClient(table);
  }
}

Ответы [ 2 ]

1 голос
/ 01 апреля 2012

Итак, вот решение, которое я придумал, используя пользовательский макет. Он оборачивает другой макет, но может привязывать computeSize либо к ширине, либо к высоте родительского композита - в основном разрешая прокрутку только в одном направлении (если есть более простой способ заставить ScrolledForm сделать это, пожалуйста, дайте мне знать !).

Есть несколько мерзких отражений, которые нужно применять, так как computeSize и layout методы protected

import java.lang.reflect.Method;

import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Layout;

public class BoundedLayout extends Layout {
  protected Layout delegateLayout;

  protected Method computeSizeMethod;
  protected Method layoutMethod;

  protected boolean widthBound;

  public BoundedLayout(Layout delegateLayout, boolean widthBound) {
      setDelegateLayout(delegateLayout);
      this.widthBound = widthBound;
  }

  public Layout getDelegateLayout() {
      return delegateLayout;
  }

  public void setDelegateLayout(Layout delegateLayout) {
      this.delegateLayout = delegateLayout;

      try {
          computeSizeMethod = delegateLayout.getClass().getDeclaredMethod(
                "computeSize", Composite.class, int.class, int.class,
                boolean.class);
          computeSizeMethod.setAccessible(true);

          layoutMethod = delegateLayout.getClass().getDeclaredMethod(
                "layout", Composite.class, boolean.class);
          layoutMethod.setAccessible(true);
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
  }

  @Override
  protected Point computeSize(Composite composite, int wHint, int hHint,
        boolean flushCache) {
    // get comp size to make sure we don't let any children exceed it
    Point compSize = composite.getSize();

    try {
        Point layoutComputedSize = (Point) computeSizeMethod.invoke(
                delegateLayout, composite, wHint, hHint, flushCache);

        if (widthBound) {
            layoutComputedSize.x = Math.min(compSize.x,
                    layoutComputedSize.x);
        } else {
            layoutComputedSize.y = Math.min(compSize.y,
                    layoutComputedSize.y);
        }

        return layoutComputedSize;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
  }

  @Override
  protected void layout(Composite composite, boolean flushCache) {
    try {
        layoutMethod.invoke(delegateLayout, composite, flushCache);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
  }
}
0 голосов
/ 31 марта 2012

Если вы добавите стиль Section.COMPACT в свой раздел, то ширина раздела будет изменена только в расширенном состоянии.В свернутом состоянии он вернется к нормальному размеру.

Если вы не хотите, чтобы сечение увеличивалось после повторного расширения, я думаю, вам придется использовать обходной путь в ExpansionAdapter.Сохраняйте ширину вручную при свертывании и возвращайте ее при расширении.

Кстати, я бы порекомендовал использовать WindowBuilder для создания графического интерфейса, чтобы его было проще настраивать и перемещать.

...