Package org.cishell.utility.swt

Source Code of org.cishell.utility.swt.ExpandableComponentWidget

package org.cishell.utility.swt;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;

/** See ScrolledComponentFactory for more information on the overall picture of the layer that this
* class is part of.
* A LITTLE BIT OF HISTORY:
** When tasked with writing the Static Executable Wizard, I ran into a lot of difficulty with
** gracefully handling the dynamic addition and deletion of child components to scrolling
** components. (By scrolling components, I mean the components that actually do the scrolling; that
** is, they SCROLL their child components.) The problem relates to how SWT grid layouts want to be
** sized--I believe that SWT is largely implemented to only handle GUIs that've been setup by time
** the user interacts with them.
** In order to try to make this process more graceful, I came up with this and its
** related classes.
* HOW TO USE IT:
** This class only makes sense if T corresponds to a GUI component in some fashion (though it
** doesn't literally have to be an SWT component).
** Override getColumnCount() to specify the number of columns each row has.
** Override createHeaderArea() and createFooterArea() to specify if there should be a header and
** footer, respectively, that is OUTSIDE of the scrolling area.
** Override createColumnLabelTexts() to specify the column labels. The default implementation of
** this method uses the column index to generate labels.
** It's recommended against overriding addComponent() and removeComponent().
** This class should be subclassed so specific column labels and any desired header/footer
** can be generated.
*/
public class ExpandableComponentWidget<T> extends Composite {
  public static final int COLUMN_AREA_LAYOUT_VERTICAL_SPACING = 1;
  public static final int VERTICAL_SCROLL_INCREMENT = 50;

  private ScrolledComponentFactory<T> componentFactory;
  private Composite headerArea;
  private ScrolledComposite scrollingArea;
  private GridContainer scrolledAreaGrid;
  private Composite footerArea;
  private List<T> components = new ArrayList<T>();
  private int uniqueComponentCount = 0;
  private Collection<Label> columnLabels;

  public ExpandableComponentWidget(
      Composite parent, ScrolledComponentFactory<T> componentFactory) {
    super(parent, SWT.NONE);
    this.componentFactory = componentFactory;

    setLayout(createLayout());
    this.headerArea = createHeaderArea();
    this.scrollingArea = createScrollingArea();
    this.footerArea = createFooterArea();
    this.scrolledAreaGrid = createScrolledAreaGrid(this.scrollingArea);

    this.scrollingArea.setExpandHorizontal(true);
    this.scrollingArea.setExpandVertical(true);
    this.scrollingArea.setAlwaysShowScrollBars(true);
    fixSize();
    this.scrollingArea.setContent(this.scrolledAreaGrid.getActualParent());
    this.scrollingArea.getVerticalBar().setPageIncrement(VERTICAL_SCROLL_INCREMENT);
    this.columnLabels = createColumnLabels(this.scrolledAreaGrid.getActualParent(), SWT.NONE);
  }

  public Composite getHeaderArea() {
    return this.headerArea;
  }

  public Composite getFooterArea() {
    return this.footerArea;
  }

  public List<T> getComponents() {
    return Collections.unmodifiableList(this.components);
  }

  public int getColumnCount() {
    return 1;
  }

  public T addComponent(int style, Map<String, Object> arguments)
      throws WidgetConstructionException {
    // TODO: Fix this terrible hack?
    if (this.components.size() == 0) {
      for (Label columnLabel : this.columnLabels) {
        columnLabel.setVisible(true);
      }
    }

    final int componentCount = this.components.size();
    T component = this.componentFactory.constructWidget(
      this,
      this.scrolledAreaGrid,
      style,
      arguments,
      componentCount,
      this.uniqueComponentCount);
    this.uniqueComponentCount++;

    fixSize();

    this.components.add(component);

    return component;
  }

  public void removeComponent(int index) {
    this.scrolledAreaGrid.removeRow(index);
    this.components.remove(index);
    fixSize();

    for (int ii = 0; ii < this.components.size(); ii++) {
      this.componentFactory.reindexComponent(this.components.get(ii), ii);
    }

    // TODO: Fix this terrible hack?
    if (this.components.size() == 0) {
      for (Label columnLabel : this.columnLabels) {
        columnLabel.setVisible(false);
      }
    }
  }

  public Collection<Label> createColumnLabels(Composite parent, int style) {
    List<Label> columnLabels = new ArrayList<Label>();

    for (String columnLabelText : createColumnLabelTexts()) {
      Label columnLabel = new Label(parent, style);
      columnLabel.setLayoutData(createColumnLabelLayoutData());
      columnLabel.setText(columnLabelText);
      columnLabels.add(columnLabel);
    }

    return columnLabels;
  }

  public Collection<String> createColumnLabelTexts() {
    List<String> columnLabelTexts = new ArrayList<String>();

    for (int ii = 0; ii < getColumnCount(); ii++) {
      columnLabelTexts.add("Column " + ii);
    }

    return columnLabelTexts;
  }

  private void fixSize() {
    Composite scrolledArea = this.scrolledAreaGrid.getActualParent();
    this.scrollingArea.setMinSize(scrolledArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));
    scrolledArea.pack();
  }

  protected Composite createHeaderArea() {
    Composite headerArea = new Composite(this, SWT.NONE);
    headerArea.setLayoutData(createHeaderAreaLayoutData());
    headerArea.setLayout(createHeaderLayout());

    return headerArea;
  }

  protected GridData createHeaderAreaLayoutData() {
    GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, false);

    return layoutData;
  }

  protected GridLayout createHeaderLayout() {
    GridLayout layout = new GridLayout(1, false);
    GUIBuilderUtilities.clearMargins(layout);
    GUIBuilderUtilities.clearSpacing(layout);

    return layout;
  }

  protected ScrolledComposite createScrollingArea() {
    ScrolledComposite scrollingArea =
      new ScrolledComposite(this, SWT.BORDER | SWT.V_SCROLL);
    scrollingArea.setLayoutData(createScrollingAreaLayoutData());
    scrollingArea.setLayout(createScrollingLayout());

    return scrollingArea;
  }

  protected GridData createScrollingAreaLayoutData() {
    GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);

    return layoutData;
  }

  private GridLayout createScrollingLayout() {
    GridLayout layout = new GridLayout(1, true);
    GUIBuilderUtilities.clearMargins(layout);
    GUIBuilderUtilities.clearSpacing(layout);

    return layout;
  }

  protected Composite createFooterArea() {
    Composite footerArea = new Composite(this, SWT.BORDER);
    footerArea.setLayoutData(createFooterAreaLayoutData());
    footerArea.setLayout(createFooterLayout());

    return footerArea;
  }

  protected GridData createFooterAreaLayoutData() {
    GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, false);

    return layoutData;
  }

  protected GridLayout createFooterLayout() {
    GridLayout layout = new GridLayout(1, false);
    GUIBuilderUtilities.clearMargins(layout);
    GUIBuilderUtilities.clearSpacing(layout);

    return layout;
  }

  private GridContainer createScrolledAreaGrid(Composite parent) {
    Composite columnArea = new Composite(parent, SWT.NONE);
    columnArea.setLayoutData(createScrolledAreaLayoutData());
    final int columnCount = getColumnCount();
    columnArea.setLayout(createScrolledAreaLayout(columnCount));

    return new GridContainer(columnArea, columnCount);
  }

  protected GridData createScrolledAreaLayoutData() {
    GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);

    return layoutData;
  }

  protected GridLayout createScrolledAreaLayout(int columnCount) {
    GridLayout layout = new GridLayout(columnCount, false);
//    GUIBuilderUtilities.clearMargins(layout);
//    GUIBuilderUtilities.clearSpacing(layout);

    return layout;
  }

  protected GridData createColumnLabelLayoutData() {
    GridData layoutData = new GridData(SWT.CENTER, SWT.CENTER, false, false);

    return layoutData;
  }

  protected GridData createComponentLayoutData() {
    GridData layoutData = new GridData(SWT.FILL, SWT.TOP, true, false);

    return layoutData;
  }

  private static GridLayout createLayout() {
    GridLayout layout = new GridLayout(1, true);
    GUIBuilderUtilities.clearMargins(layout);
    GUIBuilderUtilities.clearSpacing(layout);

    return layout;
  }
}
TOP

Related Classes of org.cishell.utility.swt.ExpandableComponentWidget

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.