Java tutorial
/******************************************************************************* * Copyright (c) 2012, 2013 University of Illinois and others. * 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: * Jeff Overbey (Illinois) - initial API and implementation * Chris Navarro (Illinois) - fix for Bug 394121 *******************************************************************************/ package org.eclipse.ptp.ems.ui; import java.net.URI; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.ptp.ems.core.EnvManagerConfigString; import org.eclipse.ptp.ems.core.IEnvManager; import org.eclipse.ptp.ems.core.IEnvManagerConfig; import org.eclipse.ptp.internal.ems.ui.EnvManagerChecklist; import org.eclipse.ptp.internal.ems.ui.messages.Messages; import org.eclipse.remote.core.IRemoteConnection; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.TraverseEvent; import org.eclipse.swt.events.TraverseListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; /** * Instances of this class represent a user interface element which provides the following: * <ul> * <li>a checkbox: "Use an environment management system to customize the remote build environment"; * <li>a checkbox: "Manually specify environment configuration commands"; and * <li>either a checklist, a multi-line text box, or a blank area, depending on the state of the checkboxes above. * </ul> * <p> * Typically, clients will use this control as follows. * <ol> * <li>Invoke the constructor, setting the {@link IRemoteConnection} that will provide access to the remote machine. * <li>Invoke {@link #setErrorListener(IErrorListener)} in order to display error messages to the user. * <li>As needed, invoke {@link #configurationChanged(URI, IRemoteConnection, List)} or #setCheckbox(boolean)} to change the * appearance of the control. * <li>Finally, invoke {@link #isUseEMSChecked()}, {@link #isManualConfigChecked()}, {@link #getSelectedElements()}, and * {@link #getConnectionName()} to retrieve the contents of the control, or use {@link #saveConfiguration(IEnvManagerConfig)} to * persist all of its settings in a single operation. * </ol> * * @author Jeff Overbey * * @since 6.0 */ public final class EnvManagerConfigWidget extends Composite { private Button useEMSCheckbox; private Button manualConfigCheckbox; private Composite stack; private StackLayout stackLayout; private Label noEnvConfigLabel; private Text envConfigTextbox; private EnvManagerChecklist envConfigChecklist; /** * Constructor. * * @param parent * parent {@link Composite} (non-<code>null</code>) * @param style * the style of widget to construct * @since 2.0 */ public EnvManagerConfigWidget(Composite parent, int style) { super(parent, style); GridLayout g = new GridLayout(1, false); g.marginHeight = 0; g.marginWidth = 0; setLayout(g); createCheckbox(this); createManualOverrideCheckbox(this); createStack(this); createNoEnvConfigLabel(); createEnvConfigTextbox(); createEnvConfigChecklist(); setTopControl(); } /** * Set the remote connection to use when querying for the remote environment * * @param connection * {@link IRemoteConnection} used to access files and execute shell commands on the remote machine (non- * <code>null</code>) * @since 3.0 */ public void setConnection(IRemoteConnection connection) { if (envConfigChecklist != null) { envConfigChecklist.setConnection(connection); } } private void createCheckbox(Composite composite) { useEMSCheckbox = new Button(composite, SWT.CHECK | SWT.WRAP); useEMSCheckbox.setText(Messages.EnvConfigurationControl_UseEMS); useEMSCheckbox.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); useEMSCheckbox.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { onSelectLoadModules(); } }); } private void onSelectLoadModules() { final boolean isChecked = useEMSCheckbox.getSelection(); manualConfigCheckbox.setVisible(isChecked); setTopControl(); } private void setTopControl() { if (useEMSCheckbox.getSelection()) { if (manualConfigCheckbox.getSelection()) { if (stackLayout.topControl == envConfigChecklist && isChecklistEnabled()) { setTextFromChecklist(); } stackLayout.topControl = envConfigTextbox; } else { stackLayout.topControl = envConfigChecklist; stack.setSize(envConfigChecklist.computeSize(SWT.DEFAULT, SWT.DEFAULT)); } } else { stackLayout.topControl = noEnvConfigLabel; } stack.getParent().layout(); stack.layout(); } private void setTextFromChecklist() { final IEnvManager envManager = envConfigChecklist.getEnvManager(); final EnvManagerConfigString config = new EnvManagerConfigString(); config.setEnvMgmtEnabled(true); config.setManualConfig(false); config.setConnectionName(getConnectionName()); config.setConfigElements(getSelectedElements()); final String bashCommands = envManager.getBashConcatenation("\n", false, config, null); //$NON-NLS-1$ envConfigTextbox.setText(bashCommands); } private void createManualOverrideCheckbox(Composite composite) { manualConfigCheckbox = new Button(composite, SWT.CHECK); manualConfigCheckbox.setText(Messages.EnvConfigurationControl_ManualOverride); manualConfigCheckbox.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); manualConfigCheckbox.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { onSelectManualConfig(); } }); } private void onSelectManualConfig() { setTopControl(); } private void createStack(Composite composite) { stack = new Composite(composite, SWT.NONE); stack.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); stackLayout = new StackLayout(); stack.setLayout(stackLayout); } private void createNoEnvConfigLabel() { noEnvConfigLabel = new Label(stack, SWT.NONE); noEnvConfigLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); noEnvConfigLabel.setText(""); //$NON-NLS-1$ } private void createEnvConfigTextbox() { envConfigTextbox = new Text(stack, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); envConfigTextbox.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); envConfigTextbox.setText(""); //$NON-NLS-1$ allowEnterAndTabInTextbox(envConfigTextbox); envConfigTextbox.setFont(JFaceResources.getTextFont()); } /** * Allows the Enter and Tab keys to insert text into the text box, even if it's in a dialog box where these keys would usually * press the default button and traverse to the next control, respectively. * <p> * The user must press Ctrl+Enter or Ctrl+Tab (on Mac OS X, Command+Enter or Command+Tab) to traverse dialog controls. */ private static void allowEnterAndTabInTextbox(final Text envConfigTextbox) { envConfigTextbox.addTraverseListener(new TraverseListener() { @Override public void keyTraversed(TraverseEvent e) { final boolean modifierPressed = (e.stateMask & SWT.MOD1) != 0; if (!modifierPressed) { switch (e.detail) { case SWT.TRAVERSE_RETURN: envConfigTextbox.insert("\n"); //$NON-NLS-1$ e.doit = false; break; case SWT.TRAVERSE_TAB_NEXT: envConfigTextbox.insert("\t"); //$NON-NLS-1$ e.doit = false; break; case SWT.TRAVERSE_TAB_PREVIOUS: e.doit = false; break; } } } }); } private void createEnvConfigChecklist() { envConfigChecklist = new EnvManagerChecklist(stack, SWT.NONE); envConfigChecklist.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); } /** * Sets the (unique) {@link IErrorListener} which will be used to display error messages to the user. * * @param listener * {@link IErrorListener} used to display error messages to the user, or <code>null</code> */ public void setErrorListener(IErrorListener listener) { envConfigChecklist.setErrorListener(listener); } /** * Re-populates this control to reflect a change in the project's remote location or a change in the selected items. * <p> * If the given URI is <code>null</code>, or if it differs from the URI supplied in the previous call to * {@link #configurationChanged(URI, IRemoteConnection, List)}, then the elements in the checklist are re-loaded from the remote * machine (using {@link IEnvManager#determineAvailableElements(IProgressMonitor)}). Otherwise, the items present in the * checklist remain the same, but the checked/unchecked state of the items may be changed. * * @param uri * a URI representing the remote location of this project (possibly <code>null</code>) * @param remoteConnection * {@link IRemoteConnection} providing access to the remote machine (non-<code>null</code>) * @param selectedItems * the items which should be selected in the checklist (non-<code>null</code>) * @since 3.0 */ public void configurationChanged(URI uri, IRemoteConnection remoteConnection, List<String> selectedItems) { envConfigChecklist.reset(uri, remoteConnection, selectedItems); setTopControl(); } /** * @return true iff the "Use an environment management system to customize the remote build environment" checkbox is * checked * * @see #setUseEMSCheckbox(boolean) */ public boolean isUseEMSChecked() { return useEMSCheckbox.getSelection(); } /** * @return true iff the "Manually specify environment configuration commands" checkbox is checked */ public boolean isManualConfigChecked() { return manualConfigCheckbox.getSelection(); } /** * @return the contents of the text box which allows the user to enter a custom sequence of environment management commands. * This set may be empty but is never <code>null</code>. */ public String getManualConfigText() { return envConfigTextbox.getText(); } /** * Sets the contents of the text box which allows the user to enter a custom sequence of environment management commands. * * @param text * non-<code>null</code>. */ public void setManualConfigText(String text) { envConfigTextbox.setText(text); } /** * Get the text of the elements which are checked in the checklist. This list may be empty but is never <code>null</code>. * It is, in theory, a subset of the strings returned by {@link IEnvManager#determineAvailableElements(IProgressMonitor)}. * * @return list of checked elements * * @since 2.0 */ public List<String> getSelectedElements() { return envConfigChecklist.getSelectedElements(); } /** * Test if the checklist is properly configured. The contents of the checklist is only valid when this is true. * * TODO: Should probably be public, but this would require an API change * * @return true if checklist is valid */ private boolean isValid() { return envConfigChecklist.isValid(); } /** * @return true iff the checklist is visible and enabled for modification by the user */ private boolean isChecklistEnabled() { return envConfigChecklist.isChecklistEnabled(); } /** * Sets the state of the "Use an environment management system to customize the remote build environment" checkbox. * * @param checked * true iff the "Use an environment management system to customize the remote build environment" checkbox * should be checked * * @see #isUseEMSChecked() */ public void setUseEMSCheckbox(boolean checked) { useEMSCheckbox.setSelection(checked); onSelectLoadModules(); } /** * Sets the state of the "Manually specify environment configuration commands" checkbox. * * @param checked * true iff the "Manually specify environment configuration commands" checkbox should be checked * * @see #isManualConfigChecked() */ public void setManualConfigCheckbox(boolean checked) { manualConfigCheckbox.setSelection(checked); onSelectManualConfig(); } /** * @return the name of the remote environment (possibly <code>null</code>). The remote environment is determined by the * {@link IRemoteConnection} provided to the constructor or {@link #configurationChanged(URI, IRemoteConnection, List)}, * whichever was * invoked most recently. */ public String getConnectionName() { return envConfigChecklist.getConnectionName(); } /** * Stores the current state of this {@link EnvManagerConfigWidget} in the given configuration object. * * @param config * non-<code>null</code> */ public void saveConfiguration(IEnvManagerConfig config) { config.setEnvMgmtEnabled(isUseEMSChecked()); if (isUseEMSChecked()) { config.setManualConfig(isManualConfigChecked()); if (isManualConfigChecked()) { config.setManualConfigText(getManualConfigText()); } else { // Only overwrite the module list if the checklist was available for editing; // this allows old values to be resurrected if environment management support was temporarily disabled if (isChecklistEnabled() && isValid()) { config.setConnectionName(getConnectionName()); config.setConfigElements(getSelectedElements()); } } } } }