Java tutorial
/******************************************************************************* * Copyright 2007 International Rice Research Institute (IRRI) and * Centro Internacional de Mejoramiento de Maiz y Trigo (CIMMYT). * Original author Guy Davenport (guy.davenport@cropinformatics.com) under contract by * CIMMYT. Additional modifications by Guy Davenport after 21 November 2010 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ package org.cropinformatics.ui.viewers.list; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.util.regex.Pattern; import org.apache.commons.collections.list.SetUniqueList; import org.cropinformatics.ui.Activator; import org.cropinformatics.ui.Images; import org.cropinformatics.ui.components.Component; import org.cropinformatics.ui.components.impl.ControlComponent; import org.cropinformatics.ui.components.impl.SimpleControlComponent; import org.cropinformatics.ui.components.impl.SimpleViewerComponent; import org.cropinformatics.ui.configuration.ComponentConfiguration; import org.cropinformatics.ui.configuration.ControlConfiguration; import org.cropinformatics.ui.configuration.DialogConfiguration; import org.cropinformatics.ui.configuration.ListViewerConfiguration; import org.cropinformatics.ui.configuration.utils.ConfigurationUtils; import org.cropinformatics.ui.dialogs.AbstractEditDialog; import org.cropinformatics.ui.utils.LabelUtils; import org.cropinformatics.ui.viewers.IdentificationLabelProvider; import org.cropinformatics.ui.viewers.SelectionChangedSupport; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ICheckable; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.Viewer; 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.events.SelectionListener; import org.eclipse.swt.graphics.Point; 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.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; /** * Super-class for all viewers that use a StructuredViewer to display the list * * @author Guy Davenport (guy.davenport@cropinformatics.com) * @version $Id$ * @see StructuredViewer * * @param <T> the type of the elements in the list */ public abstract class AbstractSingleListStructuredViewer<T extends Object> extends AbstractListViewer<T> implements AdvancedListViewer<T> { public static final String STRUCTURED_VIEWER_CONPONENT_ID = "structuredViewer"; public static final String VIEWER_COMPONENT_ID = "viewerComponent"; public static final String FILTER_COMPONENT_ID = "filterComponent"; public static final String STRING_FILTER_COMPONENT_ID = "stringFilterComponent"; public static final String REORDER_COMPONENT_ID = "reorderComponent"; public static final String CLEAR_SELECTION_COMPONENT_ID = "clearSelectionComponent"; public static final String CLEAR_CHECK_COMPONENT_ID = "clearCheckComponent"; public static final String CHECK_ALL_COMPONENT_ID = "checkAllComponent"; public static final String EDIT_ITEM_COMPONENT_ID = "editItemComponent"; public static final String ADD_ITEM_COMPONENT_ID = "addItemComponent"; public static final String REMOVE_ITEM_COMPONENT_ID = "removeItemComponent"; public static final String ALL_SELECTED_COMPONENT_ID = "allSelectComponent"; public static final String REGEX_COMPONENT_ID = "regexComponent"; public static final String EDIT_DIALOG_ID = "editDialog"; private static final String WILDCARD = "*"; private static final String RETRIEVE_ELEMENT_BEGIN_TASK_LABEL = AbstractSingleListStructuredViewer.class .getName() + ".retrieveElementsBeginTaskLabel"; private static final String RETRIEVE_ELEMENT_SUB_TASK_LABEL = AbstractSingleListStructuredViewer.class.getName() + ".retrieveElementsSubTaskLabel"; private static final String CLEAR_FILTERS_LABEL = AbstractSingleListStructuredViewer.class.getName() + ".clearFiltersLabel"; private static final String REGEX_FILTER_LABEL = AbstractSingleListStructuredViewer.class.getName() + ".regex"; private static final String NAME_FILTER = AbstractSingleListStructuredViewer.class.getName() + ".nameFilter"; private static final String FILTER_BY_LABEL = AbstractSingleListStructuredViewer.class.getName() + ".filterByLabel"; private static final String ADD_ITEM_BUTTON_LABEL = AbstractSingleListStructuredViewer.class.getName() + ".addItemButtonLabel"; private static final String REMOVE_ITEM_BUTTON_LABEL = AbstractSingleListStructuredViewer.class.getName() + ".removeItemButtonLabel"; private static final String EDIT_ITEM_BUTTON_LABEL = AbstractSingleListStructuredViewer.class.getName() + ".editItemButtonLabel"; private static final String ALL_SELECTED_LABEL = AbstractSingleListStructuredViewer.class.getName() + ".allSelectedLabel"; private static final String CLEAR_SELECTION_LABEL = AbstractSingleListStructuredViewer.class.getName() + ".clearSelectionLabel"; private static final String CLEAR_SELECTIONS_LABEL = AbstractSingleListStructuredViewer.class.getName() + ".clearSelectionsLabel"; private static final String CHECK_ALL_LABEL = AbstractSingleListStructuredViewer.class.getName() + ".checkAllLabel"; private static final String CLEAR_CHECK_LABEL = AbstractSingleListStructuredViewer.class.getName() + ".clearCheckLabel"; private static final String CLEAR_CHECKS_LABEL = AbstractSingleListStructuredViewer.class.getName() + ".clearChecksLabel"; private static final int DEFAULT_WIDGET_STYLES = SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION; public static final int MIN_STEP_SIZE = 1; public static final int MAX_STEP_SIZE = 1000; private StructuredViewer structuredViewer; private ControlComponent<ControlConfiguration, Text> filterText; private List<T> items; private List<T> selectedItems; private List<T> checkedItems; private ViewerListenerAndFilter viewerListenerAndFilter; private Button upButton; private Button downButton; private Button clearFiltersButton; private Button clearStringFilterButton; private ControlComponent<ControlConfiguration, Button> regexButton; private ControlComponent<ControlConfiguration, Button> addItemButton; private ControlComponent<ControlConfiguration, Button> removeItemButton; private ControlComponent<ControlConfiguration, Button> editItemButton; private List<ListViewerFilter> filters; private ComboViewer filterComboViewer; private ListViewerFilter currentFilter; private Label filterByLabel; private ControlComponent<ControlConfiguration, Button> clearSelectionButton; private ControlComponent<ControlConfiguration, Button> clearCheckButton; private ControlComponent<ControlConfiguration, Button> checkAllButton; private ControlComponent<ControlConfiguration, Button> allSelectedButton; private boolean allSelected; private boolean canceled; private SelectionChangedSupport selectionChangedSupport; public AbstractSingleListStructuredViewer(Composite parent, ListViewerConfiguration configuration) { this(parent, configuration, null, null); } public AbstractSingleListStructuredViewer(Composite parent, ListViewerConfiguration configuration, List<T> items) { this(parent, configuration, items, null); } public AbstractSingleListStructuredViewer(Composite parent, ListViewerConfiguration configuration, List<T> items, List<T> selectedItems) { super(parent, configuration); viewerListenerAndFilter = new ViewerListenerAndFilter(); selectionChangedSupport = new SelectionChangedSupport(this); filters = new LinkedList<ListViewerFilter>(); this.selectedItems = new LinkedList<T>(); this.checkedItems = new LinkedList<T>(); setItems(items); createInitialFilters(); if (!ConfigurationUtils.isMultipleSelectionInUse(getConfiguration()) && selectedItems != null && selectedItems.size() > 1) { Activator.getDefault().warn("Single selection in use only the first selected item will be used"); setSelectedItem(selectedItems.get(0)); } else { setSelectedItems(selectedItems); } } public final boolean isEmpty() { if (items != null) return items.isEmpty(); else return false; } public final int getItemCount() { if (items != null) return items.size(); else return 0; } public final List<T> getItems() { return items; } public final List<T> getFilteredItems() { if (structuredViewer != null && structuredViewer.getFilters() != null && structuredViewer.getFilters().length > 0) { ArrayList<T> filtered = new ArrayList<T>(items.size()); Iterator<T> iterator = items.iterator(); T element; while (iterator.hasNext()) { element = iterator.next(); if (viewerListenerAndFilter.select(element) && (currentFilter == null || currentFilter.select(element))) filtered.add(element); } return filtered; } else { return getItems(); } } @SuppressWarnings("unchecked") public final boolean setItems(List<T> items) { if (items != null && !items.isEmpty()) { if (ConfigurationUtils.isCopyItemsInUse(getConfiguration())) { if (!getConfiguration().isDuplicateAllowed()) this.items = SetUniqueList.decorate(new LinkedList<T>()); else this.items = new LinkedList<T>(); Iterator<T> iterator = items.iterator(); while (iterator.hasNext()) this.items.add(copyItem(iterator.next())); } else { //TODO not supported //if (!getListViewerProperties().isDuplicateAllowed()) // this.items = SetUniqueList.decorate(items); //else setItemsInternal(items); } } else { //TODO not supported //if (!getListViewerProperties().isDuplicateAllowed()) // this.items = SetUniqueList.decorate(items); //else this.items = new LinkedList<T>(); } // reset selected items if (ConfigurationUtils.isMantainingSelectionState(getConfiguration())) initialiseSelection(); else setSelectedItems((List<T>) null); if (ConfigurationUtils.isMantainingCheckedState(getConfiguration())) initialiseChecked(); else setCheckedItems((List<T>) null); updateButtons(); updateItemList(); return true; } @SuppressWarnings("unchecked") public final boolean addItems(List<T> items) { boolean success = true; if (items != null && !items.isEmpty()) { List<T> itemsToAdd; if (getConfiguration() != null && !getConfiguration().isDuplicateAllowed()) itemsToAdd = SetUniqueList.decorate(items); else itemsToAdd = items; if (getConfiguration() != null && getConfiguration().isCopyItemsInUse()) { Iterator<T> iterator = itemsToAdd.iterator(); while (success && iterator.hasNext()) success = this.items.add(copyItem(iterator.next())); } else { success = this.items.addAll(itemsToAdd); } updateButtons(); updateItemList(); } return success; } public final boolean removeAllItems() { this.items = new LinkedList<T>(); this.selectedItems = new LinkedList<T>(); this.checkedItems = new LinkedList<T>(); updateButtons(); updateItemList(); return true; } public boolean removeItems(List<T> items) { if (items != null && !items.isEmpty()) { if (this.items.removeAll(items)) { this.selectedItems.removeAll(items); this.checkedItems.removeAll(items); updateButtons(); updateItemList(); return true; } } return false; } public final boolean isAllSelected() { return getConfiguration() != null && hasChildComponent(ALL_SELECTED_COMPONENT_ID) && allSelected; } public final synchronized int getSelectedCount() { if (allSelected) if (items != null) return items.size(); else return 0; else if (selectedItems != null) return selectedItems.size(); else return 0; } public final T getSelectedItem() { if (allSelected) { if (getItems().size() > 0) { return getItems().get(0); } else { return null; } } else { if (selectedItems != null && selectedItems.size() > 0) { return selectedItems.get(0); } else { return null; } } } public final int getSelectedIndex() { if (items != null) return items.indexOf(getSelectedItem()); else return -1; } public abstract boolean setSelectedItem(T selectedItem); public boolean setSelectedItem(int index) { if (items != null) return setSelectedItem(items.get(index)); else return false; } public final List<T> getSelectedItems() { if (allSelected) { return getItems(); } else { return selectedItems; } } public final int[] getSelectedIndices() { int[] indices; if (items != null && selectedItems != null) { if (allSelected) { indices = new int[items.size()]; for (int i = 0; i < indices.length; ++i) { indices[i] = i; } } else { indices = new int[selectedItems.size()]; Iterator<T> iterator = selectedItems.iterator(); int i = 0; while (iterator.hasNext()) { indices[i] = items.indexOf(iterator.next()); ++i; } } } else { indices = new int[0]; } return indices; } public abstract boolean setSelectedItems(List<T> selectedItems); public boolean setSelectedItems(int[] indices) { if (indices != null) { if (items != null && !items.isEmpty()) { List<T> selectedItems = new LinkedList<T>(); for (int i = 0; i < indices.length; ++i) if (indices[i] >= 0 && indices[i] < items.size()) selectedItems.add(items.get(indices[i])); return setSelectedItems(selectedItems); } else { return false; } } else { return false; } } public synchronized final int getCheckedCount() { if (checkedItems != null) return checkedItems.size(); else return 0; } public final T getCheckedItem() { if (checkedItems != null && checkedItems.size() > 0) { return checkedItems.get(0); } else { return null; } } public final int getCheckedIndex() { if (items != null) return items.indexOf(getCheckedItem()); else return -1; } public abstract boolean setCheckedItem(T checkedItem); public boolean setCheckedItem(int index) { if (items != null) return setCheckedItem(items.get(index)); else return false; } public final List<T> getCheckedItems() { return checkedItems; } public final int[] getCheckedIndices() { int[] indices; if (items != null && !items.isEmpty() && checkedItems != null) { indices = new int[checkedItems.size()]; Iterator<T> iterator = checkedItems.iterator(); int i = 0; while (iterator.hasNext()) { indices[i] = items.indexOf(iterator.next()); ++i; } } else { indices = new int[0]; } return indices; } public abstract boolean setCheckedItems(List<T> checkedItems); public boolean setCheckedItems(int[] indices) { if (indices != null) { if (items != null && !items.isEmpty()) { List<T> checkedItems = new LinkedList<T>(); for (int i = 0; i < indices.length; ++i) if (indices[i] >= 0 && indices[i] < items.size()) checkedItems.add(items.get(indices[i])); return setCheckedItems(checkedItems); } else { return false; } } else { return true; } } @Override public final void updateComponent() { updateButtons(); updateItemList(); super.updateComponent(); } public final ISelection getSelection() { if (ConfigurationUtils.isCheckSelectionInUse(getConfiguration()) && getCheckedItem() != null) return new StructuredSelection(getCheckedItem()); else if (getSelectedItem() != null) return new StructuredSelection(getSelectedItem()); else return new StructuredSelection(); } @SuppressWarnings("unchecked") public final void setSelection(ISelection selection) { if (!selection.isEmpty() && selection instanceof IStructuredSelection) { if (ConfigurationUtils.isMultipleSelectionInUse(getConfiguration()) || ConfigurationUtils.isMultipleCheckInUse(getConfiguration())) { Object[] values = ((IStructuredSelection) selection).toArray(); List<T> list = new LinkedList<T>(); for (int i = 0; i < values.length; ++i) { try { list.add((T) values[i]); } catch (Exception e) { } } if (ConfigurationUtils.isCheckSelectionInUse(getConfiguration())) setCheckedItems(list); else setSelectedItems(list); } else { try { if (ConfigurationUtils.isCheckSelectionInUse(getConfiguration())) setCheckedItem((T) ((IStructuredSelection) selection).getFirstElement()); else setSelectedItem((T) ((IStructuredSelection) selection).getFirstElement()); } catch (Exception e) { } } } } public final Object convertElement(T element) { return element; } public final boolean addFilter(ListViewerFilter filter) { if (filters.add(filter)) { updateFilters(); return true; } else { return false; } } public final boolean removeFilter(ListViewerFilter filter) { boolean success = filters.remove(filter); if (success) { if (structuredViewer != null && currentFilter != null && currentFilter == filter) { currentFilter = null; structuredViewer.removeFilter(filter); } updateFilters(); } return success; } public final List<ListViewerFilter> getFilters() { return filters; } public final boolean setFilters(List<ListViewerFilter> filters) { boolean success = true; this.filters.clear(); success = this.filters.addAll(filters); if (structuredViewer != null && success && currentFilter != null && this.filters.contains(currentFilter)) { structuredViewer.removeFilter(currentFilter); currentFilter = null; } if (success) updateFilters(); return success; } public void performCancel() { canceled = true; // TODO perhaps should wait until cancel occurs } @Override public void addSelectionChangedListener(ISelectionChangedListener listener) { selectionChangedSupport.addSelectionChangedListener(listener); } @Override public void removeSelectionChangedListener(ISelectionChangedListener listener) { selectionChangedSupport.removeSelectionChangedListener(listener); } @Override protected void hookContextMenus() { if (structuredViewer != null) hookContextMenu(structuredViewer.getControl(), structuredViewer); } protected void setItemsInternal(List<T> items) { this.items = new LinkedList<T>(); this.items.addAll(items); } @Override protected void postInitialiseComponent() { super.postInitialiseComponent(); //if (ConfigurationUtils.isThreadingInUse(getConfiguration())) // createProgressBar(container, 1, 1) ; updateButtons(); updateItemList(); if (getStructuredViewer() != null) { initialiseSelection(); initialiseChecked(); } } protected abstract void initialiseSelection(); protected abstract void initialiseChecked(); @Override protected Component<? extends ComponentConfiguration> initialiseChildComponent(Composite parent, ComponentConfiguration configuration, String id) { ControlConfiguration controlConfiguration = null; if (configuration instanceof ControlConfiguration) controlConfiguration = (ControlConfiguration) configuration; if (VIEWER_COMPONENT_ID.equals(id)) return createSelectionListComponent(parent, controlConfiguration); else if (FILTER_COMPONENT_ID.equals(id)) return createFiltersComponent(parent, controlConfiguration); else if (STRING_FILTER_COMPONENT_ID.equals(id)) return createStringFilterComponent(parent, controlConfiguration); else if (REORDER_COMPONENT_ID.equals(id)) return createReorderListComponent(parent, controlConfiguration); else if (CLEAR_SELECTION_COMPONENT_ID.equals(id)) return createClearAllSelectionComponent(parent, controlConfiguration); else if (CLEAR_CHECK_COMPONENT_ID.equals(id)) return createClearAllCheckedComponent(parent, controlConfiguration); else if (CHECK_ALL_COMPONENT_ID.equals(id)) return createCheckAllComponent(parent, controlConfiguration); else if (ADD_ITEM_COMPONENT_ID.equals(id)) return createAddItemComponent(parent, controlConfiguration); else if (REMOVE_ITEM_COMPONENT_ID.equals(id)) return createRemoveItemComponent(parent, controlConfiguration); else if (EDIT_ITEM_COMPONENT_ID.equals(id)) return createEditItemComponent(parent, controlConfiguration); else if (ALL_SELECTED_COMPONENT_ID.equals(id)) return createAllSelectedComponent(parent, controlConfiguration); else if (REGEX_COMPONENT_ID.equals(id)) return createRegexComponent(parent, controlConfiguration); else return null; } @Override protected void registerChildComponentIDs() { super.registerChildComponentIDs(); registerChildComponentID(VIEWER_COMPONENT_ID); registerChildComponentID(FILTER_COMPONENT_ID); registerChildComponentID(STRING_FILTER_COMPONENT_ID); registerChildComponentID(REORDER_COMPONENT_ID); registerChildComponentID(CLEAR_SELECTION_COMPONENT_ID); registerChildComponentID(CLEAR_CHECK_COMPONENT_ID); registerChildComponentID(CHECK_ALL_COMPONENT_ID); registerChildComponentID(ADD_ITEM_COMPONENT_ID); registerChildComponentID(REMOVE_ITEM_COMPONENT_ID); registerChildComponentID(EDIT_ITEM_COMPONENT_ID); registerChildComponentID(ALL_SELECTED_COMPONENT_ID); registerChildComponentID(REGEX_COMPONENT_ID); } protected final Component<? extends ComponentConfiguration> createFiltersComponent(Composite parent, ControlConfiguration configuration) { Composite container = new Composite(parent, SWT.NULL); GridLayout layout = new GridLayout(3, false); layout.marginWidth = 5; layout.marginHeight = 5; container.setLayout(layout); GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); gridData.horizontalSpan = 1; gridData.verticalSpan = 1; container.setLayoutData(gridData); filterByLabel = new Label(container, SWT.NONE); filterByLabel.setText(Activator.getDefault().getString(FILTER_BY_LABEL)); filterByLabel.setEnabled(isEnabled() && !isAllSelected()); filterComboViewer = new ComboViewer(container); filterComboViewer.getCombo().setEnabled(isEnabled() && !isAllSelected()); filterComboViewer.setContentProvider(new ArrayContentProvider()); filterComboViewer.setLabelProvider(new IdentificationLabelProvider()); filterComboViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); clearFiltersButton = new Button(container, SWT.NONE); clearFiltersButton.setText(Activator.getDefault().getString(CLEAR_FILTERS_LABEL)); clearFiltersButton.setEnabled(false); updateFilters(); filterComboViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent e) { handleFilterComboSelection((StructuredSelection) e.getSelection()); } }); clearFiltersButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handleClearFilters(); } }); return new SimpleControlComponent<Composite>(container, configuration); } protected Component<? extends ComponentConfiguration> createStringFilterComponent(Composite parent, ControlConfiguration configuration) { filterText = createTextComponent(parent, configuration, SWT.BORDER | SWT.SINGLE | SWT.SEARCH | SWT.ICON_CANCEL); filterText.setEnabled(isEnabled() && !isAllSelected()); filterText.getInternalControl().addModifyListener(viewerListenerAndFilter); return filterText; } protected Component<? extends ComponentConfiguration> createRegexComponent(Composite parent, ControlConfiguration configuration) { regexButton = createButtonComponent(parent, configuration, SWT.CHECK); regexButton.getInternalControl().setText(Activator.getDefault().getString(REGEX_FILTER_LABEL)); regexButton.getInternalControl().setSelection(viewerListenerAndFilter.regexInUse); regexButton.getInternalControl().addSelectionListener(viewerListenerAndFilter); return regexButton; } protected final Component<? extends ComponentConfiguration> createReorderListComponent(Composite parent, ControlConfiguration configuration) { Composite container = new Composite(parent, SWT.NULL); GridLayout layout = new GridLayout(1, false); layout.marginWidth = 5; layout.marginHeight = 5; container.setLayout(layout); GridData gridData = new GridData(SWT.FILL, SWT.FILL, false, false); gridData.horizontalSpan = 1; gridData.verticalSpan = 1; gridData.verticalAlignment = SWT.CENTER; container.setLayoutData(gridData); upButton = new Button(container, SWT.PUSH); upButton.setEnabled(isEnabled()); upButton.setImage(Activator.getDefault().getImage(Images.UP_BUTTON_ICON)); upButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handleUp(); } }); downButton = new Button(container, SWT.PUSH); downButton.setEnabled(isEnabled()); downButton.setImage(Activator.getDefault().getImage(Images.DOWN_BUTTON_ICON)); downButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handleDown(); } }); return new SimpleControlComponent<Composite>(container, configuration); } protected final Component<? extends ComponentConfiguration> createSelectionListComponent(Composite parent, ControlConfiguration configuration) { structuredViewer = createStructuredViewer(parent); structuredViewer.setContentProvider(createContentProvider()); structuredViewer.setLabelProvider(createLabelProvider()); initialiseStructuredViewer(structuredViewer); return new SimpleViewerComponent<StructuredViewer>(structuredViewer, configuration); } @Override protected void addListeners() { super.addListeners(); if (structuredViewer != null) { structuredViewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent e) { handleDoubleClick((StructuredSelection) e.getSelection()); } }); if (ConfigurationUtils.isCheckSelectionInUse(getConfiguration()) && structuredViewer instanceof ICheckable) { ((ICheckable) structuredViewer).addCheckStateListener(new ICheckStateListener() { public void checkStateChanged(CheckStateChangedEvent event) { handleCheckStateChanged(event); } }); } structuredViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { handleStructuredSelection((StructuredSelection) event.getSelection()); } }); } } protected final Component<? extends ComponentConfiguration> createAllSelectedComponent(Composite parent, ControlConfiguration configuration) { allSelectedButton = createButtonComponent(parent, configuration, SWT.CHECK); allSelectedButton.getInternalControl().setText(Activator.getDefault().getString(ALL_SELECTED_LABEL)); allSelectedButton.getInternalControl().addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent arg0) { handleAllSelected(); } public void widgetSelected(SelectionEvent arg0) { handleAllSelected(); } }); return allSelectedButton; } protected final Component<? extends ComponentConfiguration> createClearAllSelectionComponent(Composite parent, ControlConfiguration configuration) { clearSelectionButton = createButtonComponent(parent, configuration, SWT.PUSH); if (ConfigurationUtils.isMultipleSelectionInUse(getConfiguration())) clearSelectionButton.getInternalControl() .setText(Activator.getDefault().getString(CLEAR_SELECTIONS_LABEL)); else clearSelectionButton.getInternalControl() .setText(Activator.getDefault().getString(CLEAR_SELECTION_LABEL)); clearSelectionButton.getInternalControl().addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent arg0) { handleClearSelection(); } public void widgetSelected(SelectionEvent arg0) { handleClearSelection(); } }); return clearSelectionButton; } protected final Component<? extends ComponentConfiguration> createClearAllCheckedComponent(Composite parent, ControlConfiguration configuration) { clearCheckButton = createButtonComponent(parent, configuration, SWT.PUSH); if (ConfigurationUtils.isMultipleCheckInUse(getConfiguration())) clearCheckButton.getInternalControl().setText(Activator.getDefault().getString(CLEAR_CHECKS_LABEL)); else clearCheckButton.getInternalControl().setText(Activator.getDefault().getString(CLEAR_CHECK_LABEL)); clearCheckButton.getInternalControl().addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent arg0) { handleClearChecked(); } public void widgetSelected(SelectionEvent arg0) { handleClearChecked(); } }); return clearCheckButton; } protected final Component<? extends ComponentConfiguration> createCheckAllComponent(Composite parent, ControlConfiguration configuration) { checkAllButton = createButtonComponent(parent, configuration, SWT.PUSH); checkAllButton.getInternalControl().setText(Activator.getDefault().getString(CHECK_ALL_LABEL)); checkAllButton.getInternalControl().addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent arg0) { handleCheckAll(); } public void widgetSelected(SelectionEvent arg0) { handleCheckAll(); } }); return checkAllButton; } protected final Component<? extends ComponentConfiguration> createAddItemComponent(Composite parent, ControlConfiguration configuration) { addItemButton = createButtonComponent(parent, configuration, SWT.PUSH); addItemButton.getInternalControl().setText(Activator.getDefault().getString(ADD_ITEM_BUTTON_LABEL)); addItemButton.getInternalControl().addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent arg0) { handleAddItem(); } public void widgetSelected(SelectionEvent arg0) { handleAddItem(); } }); return addItemButton; } protected final Component<? extends ComponentConfiguration> createRemoveItemComponent(Composite parent, ControlConfiguration configuration) { removeItemButton = createButtonComponent(parent, configuration, SWT.PUSH); removeItemButton.getInternalControl().setText(Activator.getDefault().getString(REMOVE_ITEM_BUTTON_LABEL)); removeItemButton.getInternalControl().addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent arg0) { handleRemoveItems(); } public void widgetSelected(SelectionEvent arg0) { handleRemoveItems(); } }); return removeItemButton; } protected final Component<? extends ComponentConfiguration> createEditItemComponent(Composite parent, ControlConfiguration configuration) { editItemButton = createButtonComponent(parent, configuration, SWT.PUSH); editItemButton.getInternalControl().setText(Activator.getDefault().getString(EDIT_ITEM_BUTTON_LABEL)); editItemButton.getInternalControl().addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent arg0) { handleEditItem(); } public void widgetSelected(SelectionEvent arg0) { handleEditItem(); } }); return editItemButton; } protected final void createProgressBar(Composite parent, int horizontalSpan, int verticalSpan) { Composite container = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(1, false); layout.marginWidth = 5; layout.marginHeight = 5; container.setLayout(layout); GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); gridData.horizontalSpan = horizontalSpan; gridData.verticalSpan = verticalSpan; container.setLayoutData(gridData); } protected Point getInitialStructuredViewerSize() { return new Point(300, 200); } protected ICellModifier createCellModifier() { return new ViewerCellModifier(); } protected final void createInitialFilters() { } protected abstract StructuredViewer createStructuredViewer(Composite parent); protected int createWidgetStyle() { int style = DEFAULT_WIDGET_STYLES; if (ConfigurationUtils.isMultipleSelectionInUse(getConfiguration())) style = style | SWT.MULTI; else style = style | SWT.SINGLE; if (ConfigurationUtils.isVirtualInUse(getConfiguration())) style = style | SWT.VIRTUAL; if (ConfigurationUtils.isCheckSelectionInUse(getConfiguration())) style = style | SWT.CHECK; // TODO not available in RCP //if (ConfigurationUtils.isCheckSelectionInUse(getConfiguration())) // style = style | SWT.HIDE_SELECTION ; return style; } public final boolean addItem(T item) { boolean success = items.add(item); if (success) { updateButtons(); updateItemList(); } return success; } public final boolean removeItem(T item) { boolean success = items.remove(item); if (success) { selectedItems.remove(item); checkedItems.remove(item); updateButtons(); updateItemList(); } return success; } public final boolean replaceItem(T oldItem, T newItem) { boolean success = false; if (oldItem != null && newItem != null) { int index = items.indexOf(oldItem); success = index >= 0; if (success) { int selected = selectedItems.indexOf(oldItem); int checked = checkedItems.indexOf(oldItem); if (selected >= 0) success = selectedItems.set(selected, newItem) == oldItem; if (success && checked >= 0) success = checkedItems.set(checked, newItem) == oldItem; success = items.set(index, newItem) == oldItem; if (!success) //roll back { items.set(index, oldItem); if (selected >= 0) selectedItems.set(selected, oldItem); if (checked >= 0) checkedItems.set(checked, oldItem); } else { updateButtons(); updateItemList(); } } } return success; } protected void handleDoubleClick(StructuredSelection selection) { } @SuppressWarnings("unchecked") protected final void handleStructuredSelection(StructuredSelection structuredSelection) { if (ConfigurationUtils.isMultipleSelectionInUse(getConfiguration())) { // for large selections it may be necessary just to trap what is de-selected and what is selected List<T> oldValue = selectedItems; selectedItems = new LinkedList<T>(); if (!structuredSelection.isEmpty()) { @SuppressWarnings("rawtypes") Iterator iterator = structuredSelection.iterator(); while (iterator.hasNext()) selectedItems.add((T) iterator.next()); } handleInternalPropertyChange(SELECTION_PROPERTY, oldValue, getSelectedItems()); } else { selectedItems.clear(); T oldValue = getSelectedItem(); if (!structuredSelection.isEmpty()) selectedItems.add((T) structuredSelection.getFirstElement()); handleInternalPropertyChange(SELECTION_PROPERTY, oldValue, getSelectedItem()); } updateButtons(); } @SuppressWarnings("unchecked") protected final void handleCheckStateChanged(CheckStateChangedEvent event) { if (ConfigurationUtils.isMultipleCheckInUse(getConfiguration())) { if (event.getChecked()) { checkedItems.add((T) event.getElement()); handleInternalPropertyChange(CHECKED_ITEM_ADDED_PROPERTY, null, event.getElement()); } else { checkedItems.remove((T) event.getElement()); handleInternalPropertyChange(CHECKED_ITEM_REMOVED_PROPERTY, null, event.getElement()); } } else { T oldValue = getCheckedItem(); if (getCheckedCount() > 0) event.getCheckable().setChecked(getCheckedItem(), false); checkedItems.clear(); if (event.getChecked()) checkedItems.add((T) event.getElement()); handleInternalPropertyChange(CHECKED_PROPERTY, oldValue, getCheckedItem()); } updateButtons(); } protected final void handleAllSelected() { allSelected = allSelectedButton.getInternalControl().getSelection(); if (filterText != null) filterText.setEnabled(isEnabled() && !allSelected); if (filterByLabel != null) filterByLabel.setEnabled(isEnabled() && !allSelected); if (filterComboViewer != null) filterComboViewer.getCombo().setEnabled(isEnabled() && !allSelected); if (getInternalViewer() != null) getInternalViewer().getControl().setEnabled(isEnabled() && !allSelected); updateButtons(); updateItemList(); if (allSelected) handleInternalPropertyChange(SELECTION_PROPERTY, selectedItems, getSelectedItems()); else handleInternalPropertyChange(SELECTION_PROPERTY, items, getSelectedItems()); } protected void handleClearSelection() { List<T> selectedItems = new LinkedList<T>(); if (allSelected) { selectedItems.addAll(items); } else { selectedItems.addAll(this.selectedItems); } deselectAll(); handleInternalPropertyChange(SELECTION_CLEARED_PROPERTY, selectedItems, this.selectedItems); } protected void handleClearChecked() { List<T> checkedItems = new LinkedList<T>(); checkedItems.addAll(this.checkedItems); decheckAll(); handleInternalPropertyChange(SELECTION_CLEARED_PROPERTY, checkedItems, this.checkedItems); } protected void handleCheckAll() { List<T> checkedItems = new LinkedList<T>(); checkedItems.addAll(this.checkedItems); checkAll(); handleInternalPropertyChange(SELECTION_CLEARED_PROPERTY, checkedItems, this.checkedItems); } protected void handleInternalPropertyChange(String selectionProperty, Object oldValue, Object newValue) { getPropertyChangeSupport().firePropertyChange(selectionProperty, oldValue, newValue); selectionChangedSupport.fireSelectionChangedEvent(getSelection()); } protected final void handleAddItem() { DialogConfiguration dialogConfiguration = ConfigurationUtils.getChildDialogConfiguration(getConfiguration(), EDIT_DIALOG_ID); AbstractEditDialog<? extends ComponentConfiguration, T> editDialog = createEditComponentDialog( getParent().getShell(), dialogConfiguration, getSelectedItem()); if (editDialog != null && editDialog.open() == Dialog.OK) { addItem(editDialog.getValue()); } } protected boolean canAddItem() { return false; } protected final void handleRemoveItems() { removeItems(getSelectedItems()); } protected boolean canRemoveItems() { return getSelectedCount() > 0; } protected final void handleEditItem() { DialogConfiguration dialogConfiguration = ConfigurationUtils.getChildDialogConfiguration(getConfiguration(), EDIT_DIALOG_ID); T oldItem = getSelectedItem(); AbstractEditDialog<? extends ComponentConfiguration, T> editDialog = createEditComponentDialog( getParent().getShell(), dialogConfiguration, getSelectedItem()); if (editDialog != null && editDialog.open() == Dialog.OK) { T newItem = getSelectedItem(); if (oldItem != newItem) copyDifferences(oldItem, newItem); } } protected AbstractEditDialog<? extends ComponentConfiguration, T> createEditComponentDialog(Shell shell, DialogConfiguration dialogConfiguration, T value) { return null; } protected boolean canEditItem() { return getSelectedCount() == 1; } protected final void handleFilterComboSelection(StructuredSelection selection) { if (structuredViewer != null && currentFilter != null) structuredViewer.removeFilter(currentFilter); currentFilter = (ListViewerFilter) selection.getFirstElement(); clearFiltersButton.setEnabled(currentFilter != null); if (currentFilter != null) structuredViewer.addFilter(currentFilter); } protected final void handleClearFilters() { if (structuredViewer != null && currentFilter != null) structuredViewer.removeFilter(currentFilter); filterComboViewer.getCombo().deselectAll(); currentFilter = null; clearFiltersButton.setEnabled(false); } protected void updateButtons() { if (this.isEnabled()) { if (structuredViewer != null) { if (upButton != null) upButton.setEnabled(getSelectedCount() == 1 && getSelectedIndex() > 0); if (downButton != null) downButton.setEnabled(getSelectedCount() == 1 && getSelectedIndex() >= 0 && getSelectedIndex() < items.size() - 1); } if (removeItemButton != null) removeItemButton.setEnabled(canRemoveItems()); if (editItemButton != null) editItemButton.setEnabled(canEditItem()); if (addItemButton != null) addItemButton.setEnabled(canAddItem()); if (clearStringFilterButton != null) clearStringFilterButton.setEnabled( !items.isEmpty() && filterText != null && filterText.getInternalControl().getText() != null && !"".equals(filterText.getInternalControl().getText())); if (regexButton != null) regexButton.setEnabled( !items.isEmpty() && filterText != null && filterText.getInternalControl().getText() != null && !"".equals(filterText.getInternalControl().getText())); if (clearSelectionButton != null) clearSelectionButton.setEnabled(getItems().size() > 0 && getSelectedCount() > 0 && !allSelected); if (clearCheckButton != null) clearCheckButton.setEnabled(getItems().size() > 0 && getCheckedCount() > 0); if (checkAllButton != null) checkAllButton.setEnabled(getItems().size() > 0); if (getClearStringFilterButton() != null) getClearStringFilterButton().setEnabled(getClearStringFilterButton().isEnabled() && !allSelected); if (getClearFiltersButton() != null) getClearFiltersButton().setEnabled(getClearFiltersButton().isEnabled() && !allSelected); if (getRegexComponent() != null) getRegexComponent().setEnabled(getRegexComponent().isEnabled() && !allSelected); } else { if (upButton != null) upButton.setEnabled(false); if (downButton != null) downButton.setEnabled(false); if (clearFiltersButton != null) clearFiltersButton.setEnabled(false); if (clearStringFilterButton != null) clearStringFilterButton.setEnabled(false); if (regexButton != null) regexButton.setEnabled(false); if (addItemButton != null) addItemButton.setEnabled(false); if (removeItemButton != null) removeItemButton.setEnabled(false); if (editItemButton != null) editItemButton.setEnabled(false); if (filterComboViewer != null) filterComboViewer.getControl().setEnabled(false); if (filterByLabel != null) filterByLabel.setEnabled(false); if (clearSelectionButton != null) clearSelectionButton.setEnabled(false); if (clearCheckButton != null) clearCheckButton.setEnabled(false); if (checkAllButton != null) checkAllButton.setEnabled(false); if (allSelectedButton != null) allSelectedButton.setEnabled(false); } } protected boolean isFiltersInUse() { return structuredViewer != null && structuredViewer.getFilters() != null && structuredViewer.getFilters().length > 0; } protected void updateFilters() { if (filterComboViewer != null) { filterByLabel.setEnabled(!filters.isEmpty()); filterComboViewer.getCombo().setEnabled(!filters.isEmpty()); clearFiltersButton.setEnabled(!filters.isEmpty() && currentFilter != null); filterComboViewer.setInput(filters); } } protected final ControlComponent<ControlConfiguration, Text> getFilterTextComponent() { return filterText; } protected final Button getClearStringFilterButton() { return clearStringFilterButton; } protected final ControlComponent<ControlConfiguration, Button> getRegexComponent() { return regexButton; } protected final Button getClearFiltersButton() { return clearFiltersButton; } protected final ComboViewer getFilterComboViewer() { return filterComboViewer; } protected final Label getFilterByLabel() { return filterByLabel; } /** * @return the addItemButton */ protected final ControlComponent<ControlConfiguration, Button> getAddItemComponent() { return addItemButton; } /** * @return the removeItemButton */ protected final ControlComponent<ControlConfiguration, Button> getRemoveItemComponent() { return removeItemButton; } /** * @return the editItemButton */ protected final ControlComponent<ControlConfiguration, Button> getEditItemComponent() { return editItemButton; } protected IContentProvider createContentProvider() { return new ArrayContentProvider(); } protected String getFilterableLabel(T element) { return LabelUtils.getLabel(element); } protected final Viewer getInternalViewer() { return structuredViewer; } protected final StructuredViewer getStructuredViewer() { return structuredViewer; } protected T copyItem(T item) { return item; } protected final void swapItems(T itemA, T itemB) { swapItems(itemA, itemB, items.indexOf(itemA), items.indexOf(itemB)); } protected final void swapItems(T itemA, T itemB, int indexA, int indexB) { items.set(indexB, itemA); items.set(indexA, itemB); updateItemList(); // TODO perhaps over kill updateButtons(); } protected void copyDifferences(T oldItem, T newItem) { } protected final List<T> getItemsInternal() { return items; } protected final boolean setSelectedItemInternal(T selectedItem) { boolean success = true; selectedItems.clear(); if (selectedItem != null) success = selectedItems.add(selectedItem); if (success && !ConfigurationUtils.isCheckSelectionInUse(getConfiguration())) selectionChangedSupport.fireSelectionChangedEvent(getSelection()); return success; } protected final boolean setSelectedItemsInternal(List<T> selectedItems) { boolean success = true; this.selectedItems.clear(); if (selectedItems != null) success = this.selectedItems.addAll(selectedItems); if (success && !ConfigurationUtils.isCheckSelectionInUse(getConfiguration())) selectionChangedSupport.fireSelectionChangedEvent(getSelection()); return success; } protected final void deselectAllInternal() { selectedItems.clear(); } protected final void decheckAllInternal() { checkedItems.clear(); } protected final void checkAllInternal() { checkedItems.clear(); checkedItems.addAll(items); } protected final boolean setCheckedItemInternal(T checkedItem) { boolean success = true; checkedItems.clear(); if (checkedItem != null) success = checkedItems.add(checkedItem); if (success && ConfigurationUtils.isCheckSelectionInUse(getConfiguration())) selectionChangedSupport.fireSelectionChangedEvent(getSelection()); return success; } protected final boolean setCheckedItemsInternal(List<T> checkedItems) { boolean success = true; // TODO check for null elements in list and exclude from addAll this.checkedItems.clear(); if (checkedItems != null) success = this.checkedItems.addAll(checkedItems); if (success && ConfigurationUtils.isCheckSelectionInUse(getConfiguration())) selectionChangedSupport.fireSelectionChangedEvent(getSelection()); return success; } protected final void decheckedAllInternal() { checkedItems.clear(); } protected abstract void initialiseStructuredViewer(StructuredViewer structuredViewer); protected ILabelProvider createLabelProvider() { return new LabelProvider(); } protected void updateItemList() { if (getStructuredViewer() != null) { if (getItemsInternal() != null && !getItemsInternal().isEmpty() && !isAllSelected()) { if (ConfigurationUtils.isThreadingInUse(getConfiguration())) { try { if (getRunnableContext() != null) getRunnableContext().run(true, true, new ListIterationProgress()); else PlatformUI.getWorkbench().getProgressService() .busyCursorWhile(new ListIterationProgress()); } catch (Exception e) { Activator.getDefault().error(e); } } else { getStructuredViewer().setInput(getItemsInternal()); } } else { getStructuredViewer().setInput(null); } getStructuredViewer().getControl().setEnabled(isEnabled() && !isAllSelected()); } } protected void handleDown() { throw new UnsupportedOperationException("handleDown not supported"); } protected void handleUp() { throw new UnsupportedOperationException("handleUp not supported"); } protected void deselectAll() { throw new UnsupportedOperationException("deselectAll not supported"); } protected void checkAll() { throw new UnsupportedOperationException("checkAll not supported"); } protected void decheckAll() { throw new UnsupportedOperationException("decheckAll not supported"); } protected class ViewerListenerAndFilter extends ListViewerFilter implements ModifyListener, SelectionListener { private String stringPattern; private Pattern pattern; private boolean regexInUse; public ViewerListenerAndFilter() { super(Activator.getDefault().getString(NAME_FILTER)); regexInUse = hasChildComponent(REORDER_COMPONENT_ID); } public void modifyText(ModifyEvent e) { update(); } public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } public void widgetSelected(SelectionEvent e) { if (regexButton != null && e.widget == regexButton.getInternalControl()) { regexInUse = ((Button) e.widget).getSelection(); update(); } else { if (e.widget == clearStringFilterButton) clear(); } } @SuppressWarnings("unchecked") @Override public boolean select(Object element) { if (regexInUse) { if (pattern != null) return pattern.matcher(AbstractSingleListStructuredViewer.this.getFilterableLabel((T) element)) .matches(); else return true; } else { if (stringPattern != null && stringPattern.length() > 0) if (stringPattern.startsWith(WILDCARD)) return AbstractSingleListStructuredViewer.this.getFilterableLabel((T) element) .endsWith(stringPattern.substring(WILDCARD.length())); else return AbstractSingleListStructuredViewer.this.getFilterableLabel((T) element) .startsWith(stringPattern); else return true; } } private void update() { if (structuredViewer != null) { if (setPattern(filterText.getInternalControl().getText())) { structuredViewer.addFilter(this); } else { structuredViewer.removeFilter(this); } } updateButtons(); } private void clear() { filterText.getInternalControl().setText(""); } private boolean setPattern(String textString) { stringPattern = textString; if (stringPattern != null && stringPattern.length() > 0) { if (regexInUse) { try { pattern = Pattern.compile(filterText.getInternalControl().getText()); } catch (RuntimeException e) { pattern = null; } return pattern != null; } else { pattern = null; return true; } } else { if (pattern != null) pattern = null; return false; } } } protected class ViewerCellModifier implements ICellModifier { public boolean canModify(Object element, String property) { return false; } public Object getValue(Object element, String property) { return null; } public void modify(Object element, String property, Object value) { } } private class ListIterationProgress implements IRunnableWithProgress { private Object[] elements; public ListIterationProgress() { super(); elements = null; } public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask(Activator.getDefault().getString(RETRIEVE_ELEMENT_BEGIN_TASK_LABEL, items.size()), items.size()); monitor.subTask(Activator.getDefault().getString(RETRIEVE_ELEMENT_SUB_TASK_LABEL, new int[] { 0, items.size() })); elements = new Object[items.size()]; Iterator<T> iterator = items.iterator(); int i = 0; int stepSize = items.size() / 100; if (stepSize < MIN_STEP_SIZE) stepSize = MIN_STEP_SIZE; if (stepSize > MAX_STEP_SIZE) stepSize = MAX_STEP_SIZE; canceled = false; while (!canceled && !monitor.isCanceled() && i < elements.length && iterator.hasNext()) { elements[i] = convertElement(iterator.next()); ++i; if (i % stepSize == 0) { monitor.subTask(Activator.getDefault().getString(RETRIEVE_ELEMENT_SUB_TASK_LABEL, new int[] { i, items.size() })); monitor.worked(stepSize); } } monitor.done(); if (!canceled && !monitor.isCanceled() && structuredViewer != null) { TimerTask task = new TimerTask() { public void run() { getParent().getDisplay().syncExec(new Runnable() { public void run() { structuredViewer.setInput(elements); } }); } }; Timer timer = new Timer(true); timer.schedule(task, 0); } } } }