| /******************************************************************************* |
| * Copyright (c) 2000, 2004 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.debug.ui.jres; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.debug.internal.ui.SWTUtil; |
| import org.eclipse.jdt.internal.debug.ui.actions.ControlAccessibleListener; |
| import org.eclipse.jdt.internal.debug.ui.launcher.DefineSystemLibraryQuickFix; |
| import org.eclipse.jdt.launching.IVMInstall; |
| import org.eclipse.jdt.launching.IVMInstallType; |
| import org.eclipse.jdt.launching.JavaRuntime; |
| import org.eclipse.jdt.launching.VMStandin; |
| import org.eclipse.jface.util.ListenerList; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.ISelectionProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.layout.GridData; |
| 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.Event; |
| import org.eclipse.swt.widgets.Group; |
| import org.eclipse.swt.widgets.Listener; |
| import org.eclipse.swt.widgets.Shell; |
| |
| /** |
| * A composite that displays installed JRE's in a combo box, with a 'manage...' |
| * button to modify installed JREs. |
| * <p> |
| * This block implements ISelectionProvider - it sends selection change events |
| * when the checked JRE in the table changes, or when the "use default" button |
| * check state changes. |
| * </p> |
| */ |
| public class JREsComboBlock implements ISelectionProvider { |
| |
| /** |
| * This block's control |
| */ |
| private Composite fControl; |
| |
| /** |
| * VMs being displayed |
| */ |
| private List fVMs = new ArrayList(); |
| |
| /** |
| * The main control |
| */ |
| private Combo fCombo; |
| |
| // Action buttons |
| private Button fManageButton; |
| |
| /** |
| * Selection listeners (checked JRE changes) |
| */ |
| private ListenerList fSelectionListeners = new ListenerList(); |
| |
| /** |
| * Previous selection |
| */ |
| private ISelection fPrevSelection = new StructuredSelection(); |
| |
| /** |
| * Default JRE descriptor or <code>null</code> if none. |
| */ |
| private JREDescriptor fDefaultDescriptor = null; |
| |
| /** |
| * Specific JRE descriptor or <code>null</code> if none. |
| */ |
| private JREDescriptor fSpecificDescriptor = null; |
| |
| /** |
| * Default JRE radio button or <code>null</code> if none |
| */ |
| private Button fDefaultButton = null; |
| |
| /** |
| * Selected JRE radio button |
| */ |
| private Button fSpecificButton = null; |
| |
| /** |
| * The title used for the JRE block |
| */ |
| private String fTitle = null; |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) |
| */ |
| public void addSelectionChangedListener(ISelectionChangedListener listener) { |
| fSelectionListeners.add(listener); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection() |
| */ |
| public ISelection getSelection() { |
| IVMInstall vm = getJRE(); |
| if (vm == null) { |
| return new StructuredSelection(); |
| } |
| return new StructuredSelection(vm); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) |
| */ |
| public void removeSelectionChangedListener(ISelectionChangedListener listener) { |
| fSelectionListeners.remove(listener); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection) |
| */ |
| public void setSelection(ISelection selection) { |
| if (selection instanceof IStructuredSelection) { |
| if (!selection.equals(fPrevSelection)) { |
| fPrevSelection = selection; |
| if (selection.isEmpty()) { |
| fCombo.setText(""); //$NON-NLS-1$ |
| fCombo.select(-1); |
| // need to do this to clear the old text |
| fCombo.setItems(new String[]{}); |
| fillWithWorkspaceJREs(); |
| } else { |
| Object jre = ((IStructuredSelection)selection).getFirstElement(); |
| int index = fVMs.indexOf(jre); |
| if (index >= 0) { |
| fCombo.select(index); |
| } |
| } |
| fireSelectionChanged(); |
| } |
| } |
| } |
| |
| /** |
| * Creates this block's control in the given control. |
| * |
| * @param anscestor containing control |
| */ |
| public void createControl(Composite ancestor) { |
| Font font = ancestor.getFont(); |
| Composite comp = new Composite(ancestor, SWT.NONE); |
| GridLayout layout= new GridLayout(); |
| comp.setLayout(new GridLayout()); |
| comp.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| fControl = comp; |
| comp.setFont(font); |
| |
| Group group= new Group(comp, SWT.NULL); |
| layout= new GridLayout(); |
| layout.numColumns= 3; |
| group.setLayout(layout); |
| group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| group.setFont(font); |
| |
| GridData data; |
| |
| if (fTitle == null) { |
| fTitle = JREMessages.getString("JREsComboBlock.3"); //$NON-NLS-1$ |
| } |
| group.setText(fTitle); |
| |
| // display a 'use default JRE' check box |
| if (fDefaultDescriptor != null) { |
| fDefaultButton = new Button(group, SWT.RADIO); |
| fDefaultButton.setText(fDefaultDescriptor.getDescription()); |
| fDefaultButton.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| if (fDefaultButton.getSelection()) { |
| setUseDefaultJRE(); |
| } |
| } |
| }); |
| data = new GridData(); |
| data.horizontalSpan = 3; |
| fDefaultButton.setLayoutData(data); |
| fDefaultButton.setFont(font); |
| } |
| |
| fSpecificButton = new Button(group, SWT.RADIO); |
| if (fSpecificDescriptor != null) { |
| fSpecificButton.setText(fSpecificDescriptor.getDescription()); |
| } else { |
| fSpecificButton.setText(JREMessages.getString("JREsComboBlock.1")); //$NON-NLS-1$ |
| } |
| fSpecificButton.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| if (fSpecificButton.getSelection()) { |
| fCombo.setEnabled(true); |
| fManageButton.setEnabled(true); |
| fireSelectionChanged(); |
| } |
| } |
| }); |
| fSpecificButton.setFont(font); |
| data = new GridData(GridData.BEGINNING); |
| fSpecificButton.setLayoutData(data); |
| |
| fCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY); |
| fCombo.setFont(font); |
| data= new GridData(GridData.FILL_HORIZONTAL); |
| data.horizontalSpan = 1; |
| fCombo.setLayoutData(data); |
| ControlAccessibleListener.addListener(fCombo, fSpecificButton.getText()); |
| |
| fCombo.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| setJRE(getJRE()); |
| } |
| }); |
| |
| fManageButton = createPushButton(group, JREMessages.getString("JREsComboBlock.2")); //$NON-NLS-1$ |
| fManageButton.addListener(SWT.Selection, new Listener() { |
| public void handleEvent(Event event) { |
| IVMInstall oldSelection = getJRE(); |
| int oldIndex = -1; |
| if (oldSelection != null) { |
| oldIndex = fVMs.indexOf(oldSelection); |
| } |
| DefineSystemLibraryQuickFix fix = new DefineSystemLibraryQuickFix(); |
| fix.run(null); |
| fillWithWorkspaceJREs(); |
| int newIndex = -1; |
| if (oldSelection != null) { |
| newIndex = fVMs.indexOf(oldSelection); |
| } |
| if (newIndex != oldIndex) { |
| // clear the old selection so that a selection changed is fired |
| fPrevSelection = null; |
| } |
| // update text |
| setDefaultJREDescriptor(fDefaultDescriptor); |
| if (isDefaultJRE()) { |
| // reset in case default has changed |
| setUseDefaultJRE(); |
| } else { |
| // restore selection |
| if (newIndex >= 0) { |
| fCombo.select(newIndex); |
| } else { |
| // select the first JRE |
| fCombo.select(0); |
| } |
| setJRE(getJRE()); |
| } |
| } |
| }); |
| |
| fillWithWorkspaceJREs(); |
| } |
| |
| /** |
| * Fire current selection |
| */ |
| private void fireSelectionChanged() { |
| SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection()); |
| Object[] listeners = fSelectionListeners.getListeners(); |
| for (int i = 0; i < listeners.length; i++) { |
| ISelectionChangedListener listener = (ISelectionChangedListener)listeners[i]; |
| listener.selectionChanged(event); |
| } |
| } |
| |
| protected Button createPushButton(Composite parent, String label) { |
| return SWTUtil.createPushButton(parent, label, null); |
| } |
| |
| /** |
| * Returns this block's control |
| * |
| * @return control |
| */ |
| public Control getControl() { |
| return fControl; |
| } |
| |
| /** |
| * Sets the JREs to be displayed in this block |
| * |
| * @param vms JREs to be displayed |
| */ |
| protected void setJREs(List jres) { |
| fVMs.clear(); |
| fVMs.addAll(jres); |
| // sort by name |
| Collections.sort(fVMs, new Comparator() { |
| public int compare(Object o1, Object o2) { |
| IVMInstall left = (IVMInstall)o1; |
| IVMInstall right = (IVMInstall)o2; |
| return left.getName().compareToIgnoreCase(right.getName()); |
| } |
| |
| public boolean equals(Object obj) { |
| return obj == this; |
| } |
| }); |
| // now make an array of names |
| String[] names = new String[fVMs.size()]; |
| Iterator iter = fVMs.iterator(); |
| int i = 0; |
| while (iter.hasNext()) { |
| IVMInstall vm = (IVMInstall)iter.next(); |
| names[i] = vm.getName(); |
| i++; |
| } |
| fCombo.setItems(names); |
| } |
| |
| /** |
| * Returns the JREs currently being displayed in this block |
| * |
| * @return JREs currently being displayed in this block |
| */ |
| public IVMInstall[] getJREs() { |
| return (IVMInstall[])fVMs.toArray(new IVMInstall[fVMs.size()]); |
| } |
| |
| protected Shell getShell() { |
| return getControl().getShell(); |
| } |
| |
| /** |
| * Sets the selected JRE, or <code>null</code> |
| * |
| * @param vm JRE or <code>null</code> |
| */ |
| public void setJRE(IVMInstall vm) { |
| fSpecificButton.setSelection(true); |
| fDefaultButton.setSelection(false); |
| fCombo.setEnabled(true); |
| fManageButton.setEnabled(true); |
| if (vm == null) { |
| setSelection(new StructuredSelection()); |
| } else { |
| setSelection(new StructuredSelection(vm)); |
| } |
| } |
| |
| /** |
| * Returns the selected JRE or <code>null</code> if none. |
| * |
| * @return the selected JRE or <code>null</code> if none |
| */ |
| public IVMInstall getJRE() { |
| int index = fCombo.getSelectionIndex(); |
| if (index >= 0) { |
| return (IVMInstall)fVMs.get(index); |
| } |
| return null; |
| } |
| |
| /** |
| * Populates the JRE table with existing JREs defined in the workspace. |
| */ |
| protected void fillWithWorkspaceJREs() { |
| // fill with JREs |
| List standins = new ArrayList(); |
| IVMInstallType[] types = JavaRuntime.getVMInstallTypes(); |
| for (int i = 0; i < types.length; i++) { |
| IVMInstallType type = types[i]; |
| IVMInstall[] installs = type.getVMInstalls(); |
| for (int j = 0; j < installs.length; j++) { |
| IVMInstall install = installs[j]; |
| standins.add(new VMStandin(install)); |
| } |
| } |
| setJREs(standins); |
| } |
| |
| /** |
| * Sets the Default JRE Descriptor for this block. |
| * |
| * @param descriptor default JRE descriptor |
| */ |
| public void setDefaultJREDescriptor(JREDescriptor descriptor) { |
| fDefaultDescriptor = descriptor; |
| setButtonTextFromDescriptor(fDefaultButton, descriptor); |
| } |
| |
| private void setButtonTextFromDescriptor(Button button, JREDescriptor descriptor) { |
| if (button != null) { |
| //update the description & JRE in case it has changed |
| String currentText = button.getText(); |
| String newText = descriptor.getDescription(); |
| if (!newText.equals(currentText)) { |
| button.setText(newText); |
| fControl.layout(); |
| } |
| } |
| } |
| |
| /** |
| * Sets the specific JRE Descriptor for this block. |
| * |
| * @param descriptor specific JRE descriptor |
| */ |
| public void setSpecificJREDescriptor(JREDescriptor descriptor) { |
| fSpecificDescriptor = descriptor; |
| setButtonTextFromDescriptor(fSpecificButton, descriptor); |
| } |
| |
| /** |
| * Returns whether the 'use default JRE' button is checked. |
| * |
| * @return whether the 'use default JRE' button is checked |
| */ |
| public boolean isDefaultJRE() { |
| if (fDefaultButton != null) { |
| return fDefaultButton.getSelection(); |
| } |
| return false; |
| } |
| |
| /** |
| * Sets this control to use the 'default' JRE. |
| */ |
| public void setUseDefaultJRE() { |
| if (fDefaultDescriptor != null) { |
| fDefaultButton.setSelection(true); |
| fSpecificButton.setSelection(false); |
| fCombo.setEnabled(false); |
| fManageButton.setEnabled(false); |
| fPrevSelection = null; |
| fireSelectionChanged(); |
| } |
| } |
| |
| /** |
| * Sets the title used for this JRE block |
| * |
| * @param title title for this JRE block |
| */ |
| public void setTitle(String title) { |
| fTitle = title; |
| } |
| |
| /** |
| * Refresh the default JRE description. |
| */ |
| public void refresh() { |
| setDefaultJREDescriptor(fDefaultDescriptor); |
| } |
| |
| } |