org.springsource.ide.eclipse.gradle.ui.JavaHomeSectionImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.springsource.ide.eclipse.gradle.ui.JavaHomeSectionImpl.java

Source

/*******************************************************************************
 * Copyright (c) 2012 Pivotal Software, Inc.
 * 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:
 * Pivotal Software, Inc. - initial API and implementation
 *******************************************************************************/
package org.springsource.ide.eclipse.gradle.ui;

import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.preference.IPreferenceNode;
import org.eclipse.jface.preference.IPreferencePage;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.preference.PreferenceManager;
import org.eclipse.jface.preference.PreferenceNode;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.springsource.ide.eclipse.gradle.core.preferences.IJavaHomePreferences;
import org.springsource.ide.eclipse.gradle.core.util.JavaRuntimeUtils;
import org.springsource.ide.eclipse.gradle.core.util.expression.LiveExpression;
import org.springsource.ide.eclipse.gradle.core.validators.JavaHomeValidator;
import org.springsource.ide.eclipse.gradle.core.validators.JavaHomeValidatorContext;
import org.springsource.ide.eclipse.gradle.core.validators.ValidationResult;

/**
 * Section on a preferences page that allows user to pick a specific Gradle distribution.
 * <p>
 * Here we implement/extend neither PageWithSection nor LaunchTabSection because we 
 * need to be able to use it in the implementation of either of these two.
 * <p>
 * Essentially, this implementation provides the widgets, validation logic and
 * methods to copy preferences from/to the widgets to/from a IJavaHomePreferences object.
 * 
 * @author Kris De Volder
 */
public class JavaHomeSectionImpl implements JavaHomeValidatorContext, IJavaHomePreferences {

    private static final String TITLE = "Java Home (requires Gradle 1.0.RC1 or later)";

    public interface IWidgetRefreshListener {

        void widgetsRefreshed();

    }

    private IPageWithSections owner;
    private IWidgetRefreshListener widgetListener; // Clients that need to be able to respond to any changes in the widgets
    // to update some state can attach an instance via the constructor.

    protected static final String JRE_PREF_PAGE_ID = "org.eclipse.jdt.debug.ui.preferences.VMPreferencePage";

    private LiveExpression<ValidationResult> validator;

    //////// alternative 1: Use wrapper default ///////////////////////
    private Button defaultButton;

    //////// alternative 2: Local JVM install folder ///////////////////////
    private Button customHomeButton;
    private Combo customJRECombo;
    private Button configureJREsButton;

    /////// alternative 3: Execution environment ///////////////////////////
    private Button customExecutionEnvButton;
    private Combo customExecutionEnvCombo;
    private Button configureExecEnvsButton;

    ////////////

    private JavaRuntimeUtils jres = new JavaRuntimeUtils();

    private boolean border = false;

    public JavaHomeSectionImpl(IPageWithSections owner, IWidgetRefreshListener widgetListener) {
        this.owner = owner;
        this.validator = new JavaHomeValidator(this);
        this.widgetListener = widgetListener;
    }

    private void doRefresh() {
        validator.refresh();
        if (widgetListener != null) {
            widgetListener.widgetsRefreshed();
        }
    }

    /**
     * If set to true, a border will be create around the widgets.
     * This method must be called before createWidgets.
     */
    public JavaHomeSectionImpl setBorder(boolean enable) {
        this.border = enable;
        return this;
    }

    /**
     * This does more or less what a PageSection implementation of createContents should do (i.e. 
     * create the widgets on the page).
     * <p>
     * However, it does not fill the widget contents with the contents of the preferences because
     * this implementation may not yet be connected to a preferences store yet when the widgets
     * are being created. It is up to the caller/client to make sure a to call copyFrom method
     * to (re)initialise the widget contents at an appropriate time. 
     * 
     * @param page
     */
    public void createWidgets(Composite page) {
        GridDataFactory grabHor = GridDataFactory.fillDefaults().grab(true, false);
        Group group = null;
        if (!border) {
            Label label = new Label(page, SWT.NONE);
            label.setText(TITLE);
        } else {
            group = new Group(page, SWT.BORDER);
            group.setText(TITLE);
        }

        //Alternative 1

        Composite composite = border ? group : new Composite(page, SWT.NONE);
        GridLayout layout = new GridLayout(3, false);
        composite.setLayout(layout);
        grabHor.applyTo(composite);

        defaultButton = new Button(composite, SWT.RADIO);
        defaultButton.setText("Use Gradle wrapper's default");
        GridDataFactory span = GridDataFactory.fillDefaults().span(3, 1);
        span.applyTo(defaultButton);

        //Alternative 2: choose a workspace JRE

        customHomeButton = new Button(composite, SWT.RADIO);
        customHomeButton.setText("Workspace JRE: ");
        customHomeButton.setToolTipText("Use a specific Java installation configured in this workspace");
        customJRECombo = new Combo(composite, SWT.DROP_DOWN + SWT.READ_ONLY);
        configureJREsButton = new Button(composite, SWT.PUSH);
        configureJREsButton.setText("Configure JREs");

        grabHor.applyTo(configureJREsButton);
        grabHor.applyTo(customJRECombo);

        //Alternative 3: choose an execution environment
        customExecutionEnvButton = new Button(composite, SWT.RADIO);
        customExecutionEnvButton.setText("Execution Environment");
        customExecutionEnvButton.setToolTipText("Specify a JRE indirectly via an execution environment");
        customExecutionEnvCombo = new Combo(composite, SWT.DROP_DOWN + SWT.READ_ONLY);
        configureExecEnvsButton = new Button(composite, SWT.PUSH);
        configureExecEnvsButton.setText("Configure EEs");

        grabHor.applyTo(configureExecEnvsButton);
        grabHor.applyTo(customExecutionEnvCombo);

        refreshJREs();

        customHomeButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                enableDisableWidgets(customHomeButton, customJRECombo, configureJREsButton);
                doRefresh();
            }
        });
        customExecutionEnvButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                enableDisableWidgets(customExecutionEnvButton, customExecutionEnvCombo, configureExecEnvsButton);
                doRefresh();
            }
        });

        configureJREsButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                @SuppressWarnings("restriction")
                IPreferencePage page = new org.eclipse.jdt.internal.debug.ui.jres.JREsPreferencePage();
                PreferenceManager mgr = new PreferenceManager();
                IPreferenceNode node = new PreferenceNode("1", page);
                mgr.addToRoot(node);
                PreferenceDialog dialog = new PreferenceDialog(owner.getShell(), mgr);
                dialog.create();
                dialog.setMessage(page.getTitle());
                dialog.open();

                refreshJREs();
            }
        });

        configureExecEnvsButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                @SuppressWarnings("restriction")
                IPreferencePage page = new org.eclipse.jdt.internal.debug.ui.jres.ExecutionEnvironmentsPreferencePage();
                PreferenceManager mgr = new PreferenceManager();
                IPreferenceNode node = new PreferenceNode("1", page);
                mgr.addToRoot(node);
                PreferenceDialog dialog = new PreferenceDialog(owner.getShell(), mgr);
                dialog.create();
                dialog.setMessage(page.getTitle());
                dialog.open();

                refreshJREs();
            }

        });

        customJRECombo.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                doRefresh();
            }
        });

        customExecutionEnvCombo.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                doRefresh();
            }
        });

        grabHor.applyTo(customJRECombo);
    }

    private void refreshJREs() {
        jres = new JavaRuntimeUtils();
        setItems(customJRECombo, jres.getWorkspaceJVMNames());
        setItems(customExecutionEnvCombo, jres.getExecutionEnvNames());
    }

    private static void setItems(Combo combo, String[] items) {
        String oldSelection = combo.getText();
        combo.setItems(items);
        combo.setText(oldSelection); //Otherwise the selection gets cleared which is annoying.
    }

    /**
     * Enable/disable a number of controls depending on whether given radio button is enabled/disabled.
     */
    public void enableDisableWidgets(Button radio, Control... controlls) {
        boolean enable = radio.getSelection();
        for (Control control : controlls) {
            control.setEnabled(enable);
        }
    }

    public String getJavaHomeJRENameInPage() {
        if (customHomeButton.getSelection()) {
            String name = customJRECombo.getText();
            if (!"".equals(name)) {
                return name;
            }
        }
        return null;
    }

    public String getExecutionEnvNameInPage() {
        if (customExecutionEnvButton.getSelection()) {
            String name = customExecutionEnvCombo.getText();
            if (!"".equals(name)) {
                return name;
            }
        }
        return null;
    }

    public LiveExpression<ValidationResult> getValidator() {
        return validator;
    }

    public JavaRuntimeUtils getJREUtils() {
        return jres;
    }

    /////////////////////////////////////////////////////////////////////////////////////
    // The methods below are here so that JavaHomeSection instance can be more easily
    // adapted to be usable as a LaunchTabSection

    // Important: setter methods which directly put contents into widgets need to
    // call 'doRefresh' because the SWT widgets only seem to fire off listeners
    // when the changes are triggered by users, not when they are directly set by
    // calling methods on the widgets.

    /**
     * Copy widget contents into some place where the preferences can be stored.
     */
    public void copyTo(IJavaHomePreferences preferences) {
        if (defaultButton.getSelection()) {
            preferences.unsetJavaHome();
        } else if (customHomeButton.getSelection()) {
            preferences.setJavaHomeJREName(getText(customJRECombo));
        } else if (customExecutionEnvButton.getSelection()) {
            preferences.setJavaHomeEEName(getText(customExecutionEnvCombo));
        }
    }

    public void setDefaults(IJavaHomePreferences preferences) {
        preferences.unsetJavaHome();
    }

    /**
     * Fill the widget contents based on GradlePreferences. This should only be called after
     * the widgets have been created.
     */
    public void copyFrom(IJavaHomePreferences preferences) {
        Button enable = defaultButton;
        String jreName = preferences.getJavaHomeJREName();
        if (jreName != null) {
            customJRECombo.setText(jreName);
            if (customJRECombo.getText().equals(jreName)) {
                enable = customHomeButton;
            }
        }
        String eeName = preferences.getJavaHomeEEName();
        if (eeName != null) {
            customExecutionEnvCombo.setText(eeName);
            if (customExecutionEnvCombo.getText().equals(eeName)) {
                enable = customExecutionEnvButton;
            }
        }
        radioEnable(enable);
        doRefresh();
    }

    /**
     * Enable one of the three radio buttons and also update all the corresponding other widgets
     * enablement state accordingly.
     */
    private void radioEnable(Button enable) {
        for (Button b : new Button[] { defaultButton, customHomeButton, customExecutionEnvButton }) {
            b.setSelection(b == enable);
        }
        enableDisableWidgets();
    }

    ///////////////////////////////////////////////////////////////////////////////////
    // implement IJavaHomePreferences /////////////////////////////////
    //
    // This implementation treats the widgets themselves as a place where we can 
    // store the preferences (this is used by 'setDefaults' in the context of a preferences page)

    public String getJavaHomeJREName() {
        return getText(customJRECombo);
    }

    private static String getText(Combo combo) {
        if (combo != null) {
            String txt = combo.getText();
            if (!"".equals(txt)) {
                return txt;
            }
        }
        return null;
    }

    public String getJavaHomeEEName() {
        return getText(customExecutionEnvCombo);
    }

    public void setJavaHomeJREName(String name) {
        radioEnable(customHomeButton);
        customJRECombo.setText(name);
        doRefresh();
    }

    public void setJavaHomeEEName(String name) {
        radioEnable(customExecutionEnvButton);
        customExecutionEnvCombo.setText(name);
        doRefresh();
    }

    public void unsetJavaHome() {
        radioEnable(defaultButton);
        doRefresh();
    }

    private void enableDisableWidgets() {
        enableDisableWidgets(customHomeButton, customJRECombo, configureJREsButton);
        enableDisableWidgets(customExecutionEnvButton, customExecutionEnvCombo, configureExecEnvsButton);
    }

}