org.eclipse.buildship.ui.wizard.project.AbstractWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.buildship.ui.wizard.project.AbstractWizardPage.java

Source

/*
 * Copyright (c) 2015 the original author or authors.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Etienne Studer & Dont Csiks (Gradle Inc.) - initial API and implementation and initial documentation
 */

package org.eclipse.buildship.ui.wizard.project;

import java.util.List;

import com.gradleware.tooling.toolingutils.binding.Property;
import com.gradleware.tooling.toolingutils.binding.ValidationListener;

import com.google.common.base.Optional;
import com.google.common.base.Strings;

import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.PlatformUI;

import org.eclipse.buildship.core.projectimport.ProjectImportConfiguration;
import org.eclipse.buildship.ui.util.font.FontUtils;
import org.eclipse.buildship.ui.util.widget.UiBuilder;

/**
 * Common base class for all pages in the {@link ProjectImportWizard}.
 */
public abstract class AbstractWizardPage extends WizardPage {

    private final ProjectImportConfiguration configuration;
    private final List<Property<?>> observedProperties;
    private final String defaultMessage;

    private final Font defaultFont;
    private final UiBuilder.UiBuilderFactory builderFactory;

    /**
     * Constructor setting up the main messages and the validation facility for this wizard page.
     *
     * @param name the name of the page
     * @param title the page title
     * @param defaultMessage the default message to show when there is no validation error
     * @param configuration the data model of the wizard
     * @param observedProperties the subset of the properties from the data model that are managed
     *            on this page
     */
    protected AbstractWizardPage(String name, String title, String defaultMessage,
            ProjectImportConfiguration configuration, final List<Property<?>> observedProperties) {
        super(name);

        this.configuration = configuration;
        this.observedProperties = observedProperties;
        this.defaultMessage = defaultMessage;

        // set the basic message and the attached image
        setTitle(title);
        setMessage(defaultMessage);
        setImageDescriptor(
                ImageDescriptor.createFromFile(GradleProjectWizardPage.class, "/icons/full/wizban/wizard.png")); //$NON-NLS-1$

        // set up the UI builder
        this.defaultFont = FontUtils.getDefaultDialogFont();
        this.builderFactory = new UiBuilder.UiBuilderFactory(this.defaultFont);

        // create a listener that updates the state and the message if an observed property in the
        // model changes
        ValidationListener listener = new ValidationListener() {

            @Override
            public void validationTriggered(Property<?> source, Optional<String> validationErrorMessage) {
                // if the modified property is invalid, show its error message, otherwise check if
                // any of the other properties of this page is invalid and if so, display the first
                // found error message
                if (validationErrorMessage.isPresent()) {
                    setMessage(validationErrorMessage.get(), IMessageProvider.ERROR);
                } else {
                    Optional<String> otherErrorMessage = validateAllObservedProperties();
                    if (!otherErrorMessage.isPresent()) {
                        setMessage(AbstractWizardPage.this.defaultMessage);
                    } else {
                        setMessage(otherErrorMessage.get(), IMessageProvider.ERROR);
                    }
                }

                // we set the page to completed if all its properties are valid
                setPageComplete(isPageComplete());
            }

            private Optional<String> validateAllObservedProperties() {
                for (Property<?> property : observedProperties) {
                    Optional<String> errorMessage = property.validate();
                    if (errorMessage.isPresent()) {
                        return errorMessage;
                    }
                }
                return Optional.absent();
            }
        };

        // attach the listener to all of the observed properties
        for (Property<?> property : observedProperties) {
            property.addValidationListener(listener);
        }
    }

    protected ProjectImportConfiguration getConfiguration() {
        return this.configuration;
    }

    protected UiBuilder.UiBuilderFactory getUiBuilderFactory() {
        return this.builderFactory;
    }

    @Override
    public final void createControl(Composite parent) {
        // align dialog units to the current resolution
        initializeDialogUnits(parent);

        // create the container control
        Composite pageControl = createWizardPageContent(parent);

        // assign the created control to the wizard page
        setControl(pageControl);
    }

    private Composite createWizardPageContent(Composite parent) {
        // create a scrollable root to handle resizing
        ScrolledComposite externalRoot = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
        externalRoot.setExpandHorizontal(true);
        externalRoot.setExpandVertical(true);
        externalRoot.setMinSize(new Point(230, 380));

        // add the controls inside the root composite
        Composite container = new Composite(externalRoot, SWT.NONE);
        createWidgets(container);

        // add context information to the bottom of the page if the page defines it
        String contextInformation = Strings.emptyToNull(getPageContextInformation());
        if (contextInformation != null) {
            createWidgetsForContextInformation(container, contextInformation);
        }

        // also compute the size of the container, otherwise the ScrolledComposite's content is not
        // rendered properly
        Point containerSize = container.computeSize(SWT.DEFAULT, SWT.DEFAULT);
        container.setSize(containerSize);

        // set the root's content and return it
        externalRoot.setContent(container);
        return externalRoot;
    }

    /**
     * Populates the widgets in the wizard page.
     */
    protected abstract void createWidgets(Composite root);

    private void createWidgetsForContextInformation(Composite root, String contextInformation) {
        // create a container box occupying all horizontal space and has a 1-column row layout and a
        // 30 pixel margin to not stretch the separator widgets to the edge of the wizard page
        Composite contextInformationContainer = new Composite(root, SWT.NONE);
        GridLayout contextInformationContainerLayout = new GridLayout(1, false);
        contextInformationContainerLayout.marginLeft = contextInformationContainerLayout.marginRight = contextInformationContainerLayout.marginTop = 30;
        contextInformationContainerLayout.verticalSpacing = 15;
        contextInformationContainer.setLayout(contextInformationContainerLayout);
        contextInformationContainer.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1));

        // separator widget
        Label separator = new Label(contextInformationContainer, SWT.HORIZONTAL | SWT.SEPARATOR);
        separator.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false));

        // internal container for flexible resize
        Composite textContainer = new Composite(contextInformationContainer, SWT.NONE);
        textContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
        GridLayout textContainerLayout = new GridLayout(1, false);
        textContainerLayout.marginLeft = textContainerLayout.marginRight = 50;
        textContainer.setLayout(textContainerLayout);

        // text widget aligned to the center having 400 pixels allocated for each line of content
        StyledText contextInformationText = new StyledText(textContainer, SWT.WRAP | SWT.MULTI | SWT.CENTER);
        contextInformationText.setText(contextInformation);
        contextInformationText.setBackground(contextInformationText.getParent().getBackground());
        contextInformationText.setEnabled(false);
        contextInformationText.setEditable(false);
        GridData contextInformationTextLayoutData = new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1);
        contextInformationTextLayoutData.widthHint = 400;
        contextInformationText.setLayoutData(contextInformationTextLayoutData);
    }

    /**
     * Returns text to display under the widgets. If {@code null} or empty then nothing is displayed.
     *
     * @return explanation text for for the wizard page
     */
    protected abstract String getPageContextInformation();

    @Override
    public void setVisible(boolean visible) {
        super.setVisible(visible);

        // every time the page becomes visible, set the proper help context, this is required since
        // the user could navigate back to the initial Eclipse import page which sets another help
        // context
        if (visible) {
            if (getWizard() instanceof HelpContextIdProvider) {
                String helpContextId = ((HelpContextIdProvider) getWizard()).getHelpContextId();
                PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), helpContextId);
            }
        }
    }

    @Override
    public boolean isPageComplete() {
        for (Property<?> property : this.observedProperties) {
            if (!property.isValid()) {
                return false;
            }
        }
        return true;
    }

    @Override
    public void dispose() {
        this.defaultFont.dispose();
        super.dispose();
    }

}