| /******************************************************************************* |
| * Copyright (c) 2011 Laurent CARON |
| * 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: |
| * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation |
| *******************************************************************************/ |
| package org.mihalis.opal.itemSelector; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.SWTException; |
| import org.eclipse.swt.events.MouseAdapter; |
| import org.eclipse.swt.events.MouseEvent; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.SelectionListener; |
| import org.eclipse.swt.graphics.Image; |
| 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.Event; |
| import org.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.TableItem; |
| import org.mihalis.opal.itemSelector.DLItem.LAST_ACTION; |
| import org.mihalis.opal.utils.SWTGraphicUtil; |
| import org.mihalis.opal.utils.SimpleSelectionAdapter; |
| |
| /** |
| * Instances of this class are controls that allow the user to select multiple |
| * elements. |
| * <dl> |
| * <dt><b>Styles:</b></dt> |
| * <dd>(none)</dd> |
| * <dt><b>Events:</b></dt> |
| * <dd>Selection</dd> |
| * </dl> |
| */ |
| |
| public class DualList extends Composite { |
| |
| /** The Constant DOUBLE_DOWN_IMAGE. */ |
| private static final String DOUBLE_DOWN_IMAGE = "double_down.png"; |
| |
| /** The Constant DOUBLE_UP_IMAGE. */ |
| private static final String DOUBLE_UP_IMAGE = "double_up.png"; |
| |
| /** The Constant DOUBLE_LEFT_IMAGE. */ |
| private static final String DOUBLE_LEFT_IMAGE = "double_left.png"; |
| |
| /** The Constant DOUBLE_RIGHT_IMAGE. */ |
| private static final String DOUBLE_RIGHT_IMAGE = "double_right.png"; |
| |
| /** The Constant ARROW_DOWN_IMAGE. */ |
| private static final String ARROW_DOWN_IMAGE = "arrow_down.png"; |
| |
| /** The Constant ARROW_LEFT_IMAGE. */ |
| private static final String ARROW_LEFT_IMAGE = "arrow_left.png"; |
| |
| /** The Constant ARROW_UP_IMAGE. */ |
| private static final String ARROW_UP_IMAGE = "arrow_up.png"; |
| |
| /** The Constant ARROW_RIGHT_IMAGE. */ |
| private static final String ARROW_RIGHT_IMAGE = "arrow_right.png"; |
| |
| /** The items. */ |
| private final List<DLItem> items; |
| |
| /** The selection. */ |
| private final List<DLItem> selection; |
| |
| /** The items table. */ |
| private Table itemsTable; |
| |
| /** The selection table. */ |
| private Table selectionTable; |
| |
| /** The selection listeners. */ |
| private List<SelectionListener> selectionListeners; |
| |
| /** The selection change listeners. */ |
| private List<SelectionChangeListener> selectionChangeListeners; |
| |
| /** |
| * Constructs a new instance of this class given its parent and a style |
| * value describing its behavior and appearance. |
| * <p> |
| * The style value is either one of the style constants defined in class |
| * <code>SWT</code> which is applicable to instances of this class, or must |
| * be built by <em>bitwise OR</em>'ing together (that is, using the |
| * <code>int</code> "|" operator) two or more of those <code>SWT</code> |
| * style constants. The class description lists the style constants that are |
| * applicable to the class. Style bits are also inherited from superclasses. |
| * </p> |
| * |
| * @param parent a composite control which will be the parent of the new |
| * instance (cannot be null) |
| * @param style the style of control to construct |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the parent</li> |
| * </ul> |
| * |
| */ |
| public DualList(final Composite parent, final int style) { |
| super(parent, style); |
| items = new ArrayList<DLItem>(); |
| selection = new ArrayList<DLItem>(); |
| |
| setLayout(new GridLayout(4, false)); |
| createItemsTable(); |
| createButtonSelectAll(); |
| createSelectionTable(); |
| createButtonMoveFirst(); |
| createButtonSelect(); |
| createButtonMoveUp(); |
| createButtonDeselect(); |
| createButtonMoveDown(); |
| createButtonDeselectAll(); |
| createButtonMoveLast(); |
| } |
| |
| /** |
| * Creates the items table. |
| */ |
| private void createItemsTable() { |
| itemsTable = createTable(); |
| itemsTable.addMouseListener(new MouseAdapter() { |
| /** |
| * @see org.eclipse.swt.events.MouseAdapter#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) |
| */ |
| @Override |
| public void mouseDoubleClick(final MouseEvent event) { |
| DualList.this.selectItem(); |
| } |
| }); |
| } |
| |
| /** |
| * Creates the table. |
| * |
| * @return a table that will contain data |
| */ |
| private Table createTable() { |
| final Table table = new Table(this, SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION); |
| table.setLinesVisible(false); |
| table.setHeaderVisible(false); |
| final GridData gd = new GridData(GridData.FILL, GridData.FILL, true, true, 1, 4); |
| gd.widthHint = 200; |
| table.setLayoutData(gd); |
| // new TableColumn(table, SWT.CENTER); |
| // new TableColumn(table, SWT.LEFT); |
| table.setData(-1); |
| return table; |
| } |
| |
| /** |
| * Creates the button select all. |
| */ |
| private void createButtonSelectAll() { |
| final Button buttonSelectAll = createButton(DOUBLE_RIGHT_IMAGE, true, GridData.END); |
| buttonSelectAll.addSelectionListener(new SimpleSelectionAdapter() { |
| /** |
| * @see org.mihalis.opal.utils.SimpleSelectionAdapter#handle(org.eclipse.swt.events.SelectionEvent) |
| */ |
| @Override |
| public void handle(final SelectionEvent e) { |
| DualList.this.selectAll(); |
| } |
| }); |
| } |
| |
| /** |
| * Creates the selection table. |
| */ |
| private void createSelectionTable() { |
| selectionTable = createTable(); |
| selectionTable.addMouseListener(new MouseAdapter() { |
| /** |
| * @see org.eclipse.swt.events.MouseAdapter#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) |
| */ |
| @Override |
| public void mouseDoubleClick(final MouseEvent event) { |
| DualList.this.deselectItem(); |
| } |
| }); |
| } |
| |
| /** |
| * Creates the button move first. |
| */ |
| private void createButtonMoveFirst() { |
| final Button buttonMoveFirst = createButton(DOUBLE_UP_IMAGE, true, GridData.END); |
| buttonMoveFirst.addSelectionListener(new SimpleSelectionAdapter() { |
| /** |
| * @see org.mihalis.opal.utils.SimpleSelectionAdapter#handle(org.eclipse.swt.events.SelectionEvent) |
| */ |
| @Override |
| public void handle(final SelectionEvent e) { |
| DualList.this.moveSelectionToFirstPosition(); |
| } |
| }); |
| } |
| |
| /** |
| * Creates the button select. |
| */ |
| private void createButtonSelect() { |
| final Button buttonSelect = createButton(ARROW_RIGHT_IMAGE, false, GridData.CENTER); |
| buttonSelect.addSelectionListener(new SimpleSelectionAdapter() { |
| /** |
| * @see org.mihalis.opal.utils.SimpleSelectionAdapter#handle(org.eclipse.swt.events.SelectionEvent) |
| */ |
| @Override |
| public void handle(final SelectionEvent e) { |
| DualList.this.selectItem(); |
| } |
| }); |
| } |
| |
| /** |
| * Creates the button move up. |
| */ |
| private void createButtonMoveUp() { |
| final Button buttonMoveUp = createButton(ARROW_UP_IMAGE, false, GridData.CENTER); |
| buttonMoveUp.addSelectionListener(new SimpleSelectionAdapter() { |
| /** |
| * @see org.mihalis.opal.utils.SimpleSelectionAdapter#handle(org.eclipse.swt.events.SelectionEvent) |
| */ |
| @Override |
| public void handle(final SelectionEvent e) { |
| DualList.this.moveUpItem(); |
| } |
| }); |
| } |
| |
| /** |
| * Creates the button deselect. |
| */ |
| private void createButtonDeselect() { |
| final Button buttonDeselect = createButton(ARROW_LEFT_IMAGE, false, GridData.CENTER); |
| buttonDeselect.addSelectionListener(new SimpleSelectionAdapter() { |
| /** |
| * @see org.mihalis.opal.utils.SimpleSelectionAdapter#handle(org.eclipse.swt.events.SelectionEvent) |
| */ |
| @Override |
| public void handle(final SelectionEvent e) { |
| DualList.this.deselectItem(); |
| } |
| }); |
| } |
| |
| /** |
| * Creates the button move down. |
| */ |
| private void createButtonMoveDown() { |
| final Button buttonMoveDown = createButton(ARROW_DOWN_IMAGE, false, GridData.CENTER); |
| buttonMoveDown.addSelectionListener(new SimpleSelectionAdapter() { |
| /** |
| * @see org.mihalis.opal.utils.SimpleSelectionAdapter#handle(org.eclipse.swt.events.SelectionEvent) |
| */ |
| @Override |
| public void handle(final SelectionEvent e) { |
| DualList.this.moveDownItem(); |
| } |
| }); |
| } |
| |
| /** |
| * Creates the button deselect all. |
| */ |
| private void createButtonDeselectAll() { |
| final Button buttonDeselectAll = createButton(DOUBLE_LEFT_IMAGE, false, GridData.BEGINNING); |
| buttonDeselectAll.addSelectionListener(new SimpleSelectionAdapter() { |
| /** |
| * @see org.mihalis.opal.utils.SimpleSelectionAdapter#handle(org.eclipse.swt.events.SelectionEvent) |
| */ |
| @Override |
| public void handle(final SelectionEvent e) { |
| DualList.this.deselectAll(); |
| } |
| }); |
| } |
| |
| /** |
| * Creates the button move last. |
| */ |
| private void createButtonMoveLast() { |
| final Button buttonMoveLast = createButton(DOUBLE_DOWN_IMAGE, true, GridData.BEGINNING); |
| buttonMoveLast.addSelectionListener(new SimpleSelectionAdapter() { |
| /** |
| * @see org.mihalis.opal.utils.SimpleSelectionAdapter#handle(org.eclipse.swt.events.SelectionEvent) |
| */ |
| @Override |
| public void handle(final SelectionEvent e) { |
| DualList.this.moveSelectionToLastPosition(); |
| } |
| }); |
| } |
| |
| /** |
| * Create a button. |
| * |
| * @param fileName file name of the icon |
| * @param verticalExpand if <code>true</code>, the button will take all the |
| * available space vertically |
| * @param alignment button alignment |
| * @return a new button |
| */ |
| private Button createButton(final String fileName, final boolean verticalExpand, final int alignment) { |
| final Button button = new Button(this, SWT.PUSH); |
| final ClassLoader loader = org.mihalis.opal.itemSelector.DualList.class.getClassLoader(); |
| final Image image = new Image(getDisplay(), loader.getResourceAsStream("images/" + fileName)); |
| button.setImage(image); |
| button.setLayoutData(new GridData(GridData.CENTER, alignment, false, verticalExpand)); |
| SWTGraphicUtil.addDisposer(button, image); |
| return button; |
| } |
| |
| /** |
| * Adds the argument to the end of the receiver's list. |
| * |
| * @param item the new item |
| * @see #add(DLItem,int) |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the item is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void add(final DLItem item) { |
| checkWidget(); |
| if (item == null) { |
| SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| } |
| items.add(item); |
| redrawTables(); |
| } |
| |
| /** |
| * Adds the argument to the receiver's list at the given zero-relative |
| * index. |
| * <p> |
| * Note: To add an item at the end of the list, use the result of calling |
| * <code>getItemCount()</code> as the index or use <code>add(DLItem)</code>. |
| * </p> |
| * |
| * @param item the new item |
| * @param index the index for the item |
| * @see #add(String) |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the item is null</li> |
| * <li>ERROR_INVALID_RANGE - if the index is not between 0 |
| * and the number of elements in the list (inclusive)</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void add(final DLItem item, final int index) { |
| checkWidget(); |
| if (item == null) { |
| SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| } |
| if (index < 0 || index >= items.size()) { |
| SWT.error(SWT.ERROR_INVALID_ARGUMENT); |
| } |
| items.add(index, item); |
| redrawTables(); |
| } |
| |
| /** |
| * Adds the listener to the collection of listeners who will be notified |
| * when the user changes the receiver's selection, by sending it one of the |
| * messages defined in the <code>SelectionListener</code> interface. |
| * |
| * @param listener the listener which should be notified |
| * @see SelectionListener |
| * @see #removeSelectionListener |
| * @see SelectionEvent |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void addSelectionListener(final SelectionListener listener) { |
| checkWidget(); |
| if (listener == null) { |
| SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| } |
| if (selectionListeners == null) { |
| selectionListeners = new ArrayList<SelectionListener>(); |
| } |
| selectionListeners.add(listener); |
| } |
| |
| /** |
| * Removes the listener from the collection of listeners who will be |
| * notified when the user changes the receiver's selection. |
| * |
| * @param listener the listener which should no longer be notified |
| * @see SelectionListener |
| * @see #addSelectionListener |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void removeSelectionListener(final SelectionListener listener) { |
| checkWidget(); |
| if (listener == null) { |
| SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| } |
| if (selectionListeners == null) { |
| return; |
| } |
| selectionListeners.remove(listener); |
| } |
| |
| /** |
| * Adds the listener to the collection of listeners who will be notified |
| * when the user changes the receiver's selection, by sending it one of the |
| * messages defined in the <code>SelectionChangeListener</code> interface. |
| * |
| * @param listener the listener which should be notified |
| * @see SelectionChangeListener |
| * @see #removeSelectionChangeListener |
| * @see SelectionChangeEvent |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void addSelectionChangeListener(final SelectionChangeListener listener) { |
| checkWidget(); |
| if (listener == null) { |
| SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| } |
| if (selectionChangeListeners == null) { |
| selectionChangeListeners = new ArrayList<SelectionChangeListener>(); |
| } |
| selectionChangeListeners.add(listener); |
| } |
| |
| /** |
| * Removes the listener from the collection of listeners who will be |
| * notified when the user changes the receiver's selection. |
| * |
| * @param listener the listener which should no longer be notified |
| * @see SelectionChangeListener |
| * @see #addSelectionChangeListener |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void removeSelectionChangeListener(final SelectionChangeListener listener) { |
| checkWidget(); |
| if (listener == null) { |
| SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| } |
| if (selectionChangeListeners == null) { |
| return; |
| } |
| selectionChangeListeners.remove(listener); |
| } |
| |
| /** |
| * Deselects the item at the given zero-relative index in the receiver. If |
| * the item at the index was already deselected, it remains deselected. |
| * Indices that are out of range are ignored. |
| * |
| * @param index the index of the item to deselect |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void deselect(final int index) { |
| deselect(index, true); |
| } |
| |
| /** |
| * Deselects the item at the given zero-relative index in the receiver. If |
| * the item at the index was already deselected, it remains deselected. |
| * Indices that are out of range are ignored. |
| * |
| * @param index the index of the item to deselect |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void deselectDoNotFireEvent(final int index) { |
| deselect(index, false); |
| } |
| |
| /** |
| * Deselects the item at the given zero-relative index in the receiver. If |
| * the item at the index was already deselected, it remains deselected. |
| * Indices that are out of range are ignored. |
| * |
| * @param index the index of the item to deselect |
| * @param shouldFireEvents the should fire events |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| private void deselect(final int index, final boolean shouldFireEvents) { |
| checkWidget(); |
| if (index < 0 || index >= items.size()) { |
| return; |
| } |
| final DLItem item = selection.remove(index); |
| if (shouldFireEvents) { |
| fireSelectionEvent(item); |
| } |
| |
| final List<DLItem> deselectedItems = new ArrayList<DLItem>(); |
| item.setLastAction(LAST_ACTION.DESELECTION); |
| deselectedItems.add(item); |
| if (shouldFireEvents) { |
| fireSelectionChangeEvent(deselectedItems); |
| } |
| redrawTables(); |
| } |
| |
| /** |
| * Deselects the items at the given zero-relative indices in the receiver. |
| * If the item at the given zero-relative index in the receiver is selected, |
| * it is deselected. If the item at the index was not selected, it remains |
| * deselected. Indices that are out of range and duplicate indices are |
| * ignored. |
| * |
| * @param indices the array of indices for the items to deselect |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the set of indices is null |
| * </li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void deselect(final int[] indices) { |
| deselect(indices, true); |
| } |
| |
| /** |
| * Deselects the items at the given zero-relative indices in the receiver. |
| * If the item at the given zero-relative index in the receiver is selected, |
| * it is deselected. If the item at the index was not selected, it remains |
| * deselected. Indices that are out of range and duplicate indices are |
| * ignored. |
| * |
| * @param indices the array of indices for the items to deselect |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the set of indices is null |
| * </li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void deselectDoNotFireEvent(final int[] indices) { |
| deselect(indices, false); |
| } |
| |
| /** |
| * Deselects the items at the given zero-relative indices in the receiver. |
| * If the item at the given zero-relative index in the receiver is selected, |
| * it is deselected. If the item at the index was not selected, it remains |
| * deselected. Indices that are out of range and duplicate indices are |
| * ignored. |
| * |
| * @param indices the array of indices for the items to deselect |
| * @param shouldFireEvents the should fire events |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the set of indices is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| private void deselect(final int[] indices, final boolean shouldFireEvents) { |
| checkWidget(); |
| if (indices == null) { |
| SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| } |
| |
| final List<DLItem> toBeRemoved = new ArrayList<DLItem>(); |
| |
| for (final int index : indices) { |
| if (index < 0 || index >= items.size()) { |
| continue; |
| } |
| toBeRemoved.add(selection.get(index)); |
| } |
| |
| for (final DLItem item : toBeRemoved) { |
| selection.remove(item); |
| if (shouldFireEvents) { |
| fireSelectionEvent(item); |
| } |
| } |
| if (shouldFireEvents) { |
| fireSelectionChangeEvent(toBeRemoved); |
| } |
| |
| toBeRemoved.clear(); |
| redrawTables(); |
| } |
| |
| /** |
| * Deselects the items at the given zero-relative indices in the receiver. |
| * If the item at the given zero-relative index in the receiver is selected, |
| * it is deselected. If the item at the index was not selected, it remains |
| * deselected. The range of the indices is inclusive. Indices that are out |
| * of range are ignored. |
| * |
| * @param start the start index of the items to deselect |
| * @param end the end index of the items to deselect |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_INVALID_RANGE - if start is greater than end |
| * </li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void deselect(final int start, final int end) { |
| deselect(start, end, true); |
| } |
| |
| /** |
| * Deselects the items at the given zero-relative indices in the receiver. |
| * If the item at the given zero-relative index in the receiver is selected, |
| * it is deselected. If the item at the index was not selected, it remains |
| * deselected. The range of the indices is inclusive. Indices that are out |
| * of range are ignored. |
| * |
| * @param start the start index of the items to deselect |
| * @param end the end index of the items to deselect |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_INVALID_RANGE - if start is greater than end |
| * </li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void deselectDoNotFireEvent(final int start, final int end) { |
| deselect(start, end, false); |
| } |
| |
| /** |
| * Deselect. |
| * |
| * @param start the start |
| * @param end the end |
| * @param shouldFireEvents the should fire events |
| */ |
| private void deselect(final int start, final int end, final boolean shouldFireEvents) { |
| checkWidget(); |
| if (start > end) { |
| SWT.error(SWT.ERROR_INVALID_RANGE); |
| } |
| final List<DLItem> toBeRemoved = new ArrayList<DLItem>(); |
| |
| for (int index = start; index <= end; index++) { |
| if (index < 0 || index >= items.size()) { |
| continue; |
| } |
| toBeRemoved.add(selection.get(index)); |
| } |
| |
| for (final DLItem item : toBeRemoved) { |
| selection.remove(item); |
| if (shouldFireEvents) { |
| fireSelectionEvent(item); |
| } |
| } |
| if (shouldFireEvents) { |
| fireSelectionChangeEvent(toBeRemoved); |
| } |
| toBeRemoved.clear(); |
| redrawTables(); |
| } |
| |
| /** |
| * Deselects all selected items in the receiver. |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void deselectAll() { |
| deselectAll(true); |
| } |
| |
| /** |
| * Deselects all selected items in the receiver. |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void deselectAllDoNotFireEvent() { |
| deselectAll(false); |
| } |
| |
| /** |
| * Deselects all selected items in the receiver. |
| * |
| * @param shouldFireEvents the should fire events |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void deselectAll(final boolean shouldFireEvents) { |
| checkWidget(); |
| items.addAll(selection); |
| |
| final List<DLItem> deselectedItems = new ArrayList<DLItem>(); |
| for (final DLItem item : selection) { |
| item.setLastAction(LAST_ACTION.DESELECTION); |
| deselectedItems.add(item); |
| if (shouldFireEvents) { |
| fireSelectionEvent(item); |
| } |
| } |
| fireSelectionChangeEvent(deselectedItems); |
| |
| selection.clear(); |
| redrawTables(); |
| } |
| |
| /** |
| * Returns the item at the given, zero-relative index in the receiver. |
| * Throws an exception if the index is out of range. |
| * |
| * @param index the index of the item to return |
| * @return the item at the given index |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_INVALID_RANGE - if the index is not between 0 |
| * and the number of elements in the list minus 1 (inclusive) |
| * </li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| |
| public DLItem getItem(final int index) { |
| checkWidget(); |
| if (index < 0 || index >= items.size()) { |
| SWT.error(SWT.ERROR_INVALID_ARGUMENT); |
| } |
| return items.get(index); |
| } |
| |
| /** |
| * Returns the number of items contained in the receiver. |
| * |
| * @return the number of items |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public int getItemCount() { |
| checkWidget(); |
| return items.size(); |
| } |
| |
| /** |
| * Returns a (possibly empty) array of <code>DLItem</code>s which are the |
| * items in the receiver. |
| * <p> |
| * Note: This is not the actual structure used by the receiver to maintain |
| * its list of items, so modifying the array will not affect the receiver. |
| * </p> |
| * |
| * @return the items in the receiver's list |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public DLItem[] getItems() { |
| checkWidget(); |
| return items.toArray(new DLItem[items.size()]); |
| } |
| |
| /** |
| * Returns a (possibly empty) list of <code>DLItem</code>s which are the |
| * items in the receiver. |
| * <p> |
| * Note: This is not the actual structure used by the receiver to maintain |
| * its list of items, so modifying the array will not affect the receiver. |
| * </p> |
| * |
| * @return the items in the receiver's list |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public List<DLItem> getItemsAsList() { |
| checkWidget(); |
| return new ArrayList<DLItem>(items); |
| } |
| |
| /** |
| * Returns an array of <code>DLItem</code>s that are currently selected in |
| * the receiver. An empty array indicates that no items are selected. |
| * <p> |
| * Note: This is not the actual structure used by the receiver to maintain |
| * its selection, so modifying the array will not affect the receiver. |
| * </p> |
| * |
| * @return an array representing the selection |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public DLItem[] getSelection() { |
| checkWidget(); |
| return selection.toArray(new DLItem[items.size()]); |
| } |
| |
| /** |
| * Returns a list of <code>DLItem</code>s that are currently selected in the |
| * receiver. An empty array indicates that no items are selected. |
| * <p> |
| * Note: This is not the actual structure used by the receiver to maintain |
| * its selection, so modifying the array will not affect the receiver. |
| * </p> |
| * |
| * @return an array representing the selection |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public List<DLItem> getSelectionAsList() { |
| checkWidget(); |
| return new ArrayList<DLItem>(selection); |
| } |
| |
| /** |
| * Returns the number of selected items contained in the receiver. |
| * |
| * @return the number of selected items |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public int getSelectionCount() { |
| checkWidget(); |
| return selection.size(); |
| } |
| |
| /** |
| * Removes the item from the receiver at the given zero-relative index. |
| * |
| * @param index the index for the item |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_INVALID_RANGE - if the index is not between 0 |
| * and the number of elements in the list minus 1 (inclusive) |
| * </li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void remove(final int index) { |
| checkWidget(); |
| if (index < 0 || index >= items.size()) { |
| SWT.error(SWT.ERROR_INVALID_ARGUMENT); |
| } |
| items.remove(index); |
| redrawTables(); |
| } |
| |
| /** |
| * Removes the items from the receiver at the given zero-relative indices. |
| * |
| * @param indices the array of indices of the items |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_INVALID_RANGE - if the index is not between 0 |
| * and the number of elements in the list minus 1 (inclusive) |
| * </li> |
| * <li>ERROR_NULL_ARGUMENT - if the indices array is null |
| * </li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void remove(final int[] indices) { |
| checkWidget(); |
| for (final int index : indices) { |
| if (index < 0 || index >= items.size()) { |
| SWT.error(SWT.ERROR_INVALID_ARGUMENT); |
| } |
| items.remove(index); |
| } |
| redrawTables(); |
| } |
| |
| /** |
| * Removes the items from the receiver which are between the given |
| * zero-relative start and end indices (inclusive). |
| * |
| * @param start the start of the range |
| * @param end the end of the range |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_INVALID_RANGE - if either the start or end are |
| * not between 0 and the number of elements in the list minus |
| * 1 (inclusive) or if start>end</li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void remove(final int start, final int end) { |
| checkWidget(); |
| if (start > end) { |
| SWT.error(SWT.ERROR_INVALID_ARGUMENT); |
| } |
| for (int index = start; index < end; index++) { |
| if (index < 0 || index >= items.size()) { |
| SWT.error(SWT.ERROR_INVALID_ARGUMENT); |
| } |
| items.remove(index); |
| } |
| redrawTables(); |
| } |
| |
| /** |
| * Searches the receiver's list starting at the first item until an item is |
| * found that is equal to the argument, and removes that item from the list. |
| * |
| * @param item the item to remove |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the item is null</li> |
| * <li>ERROR_INVALID_ARGUMENT - if the item is not found in |
| * the list</li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void remove(final DLItem item) { |
| checkWidget(); |
| if (item == null) { |
| SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| } |
| if (!items.contains(item)) { |
| SWT.error(SWT.ERROR_INVALID_ARGUMENT); |
| } |
| items.remove(item); |
| redrawTables(); |
| } |
| |
| /** |
| * Removes all of the items from the receiver. |
| * <p> |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void removeAll() { |
| checkWidget(); |
| items.clear(); |
| redrawTables(); |
| } |
| |
| /** |
| * Selects the item at the given zero-relative index in the receiver's list. |
| * If the item at the index was already selected, it remains selected. |
| * Indices that are out of range are ignored. |
| * |
| * @param index the index of the item to select |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void select(final int index) { |
| select(index, true); |
| } |
| |
| /** |
| * Selects the item at the given zero-relative index in the receiver's list. |
| * If the item at the index was already selected, it remains selected. |
| * Indices that are out of range are ignored. |
| * |
| * @param index the index of the item to select |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void selectDoNotFireEvent(final int index) { |
| select(index, false); |
| } |
| |
| /** |
| * Select. |
| * |
| * @param index the index |
| * @param shouldFireEvents the should fire events |
| */ |
| private void select(final int index, final boolean shouldFireEvents) { |
| checkWidget(); |
| if (index < 0 || index >= items.size()) { |
| return; |
| } |
| final List<DLItem> selectedItems = new ArrayList<DLItem>(); |
| final DLItem item = items.get(index); |
| item.setLastAction(LAST_ACTION.SELECTION); |
| selectedItems.add(item); |
| selection.add(item); |
| |
| if (shouldFireEvents) { |
| fireSelectionEvent(item); |
| fireSelectionChangeEvent(selectedItems); |
| } |
| |
| redrawTables(); |
| } |
| |
| /** |
| * Selects the items at the given zero-relative indices in the receiver. The |
| * current selection is not cleared before the new items are selected. |
| * <p> |
| * If the item at a given index is not selected, it is selected. If the item |
| * at a given index was already selected, it remains selected. Indices that |
| * are out of range and duplicate indices are ignored. If the receiver is |
| * single-select and multiple indices are specified, then all indices are |
| * ignored. |
| * |
| * @param indices the array of indices for the items to select |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the array of indices is null |
| * </li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void select(final int[] indices) { |
| select(indices, true); |
| } |
| |
| /** |
| * Selects the items at the given zero-relative indices in the receiver. The |
| * current selection is not cleared before the new items are selected. |
| * <p> |
| * If the item at a given index is not selected, it is selected. If the item |
| * at a given index was already selected, it remains selected. Indices that |
| * are out of range and duplicate indices are ignored. If the receiver is |
| * single-select and multiple indices are specified, then all indices are |
| * ignored. |
| * |
| * @param indices the array of indices for the items to select |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the array of indices is null |
| * </li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void selectDoNotFireEvent(final int[] indices) { |
| select(indices, false); |
| } |
| |
| /** |
| * Select. |
| * |
| * @param indices the indices |
| * @param shouldFireEvents the should fire events |
| */ |
| private void select(final int[] indices, final boolean shouldFireEvents) { |
| checkWidget(); |
| if (indices == null) { |
| SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| } |
| |
| final List<DLItem> selectedItems = new ArrayList<DLItem>(); |
| for (final int index : indices) { |
| if (index < 0 || index >= items.size()) { |
| continue; |
| } |
| final DLItem item = items.get(index); |
| item.setLastAction(LAST_ACTION.SELECTION); |
| selectedItems.add(item); |
| |
| selection.add(item); |
| if (shouldFireEvents) { |
| fireSelectionEvent(item); |
| } |
| } |
| if (shouldFireEvents) { |
| fireSelectionChangeEvent(selectedItems); |
| } |
| redrawTables(); |
| } |
| |
| /** |
| * Selects the items in the range specified by the given zero-relative |
| * indices in the receiver. The range of indices is inclusive. The current |
| * selection is not cleared before the new items are selected. |
| * <p> |
| * If an item in the given range is not selected, it is selected. If an item |
| * in the given range was already selected, it remains selected. Indices |
| * that are out of range are ignored and no items will be selected if start |
| * is greater than end. If the receiver is single-select and there is more |
| * than one item in the given range, then all indices are ignored. |
| * |
| * @param start the start of the range |
| * @param end the end of the range |
| * @see List#setSelection(int,int) |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if not |
| * called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void select(final int start, final int end) { |
| select(start, end, true); |
| } |
| |
| /** |
| * Selects the items in the range specified by the given zero-relative |
| * indices in the receiver. The range of indices is inclusive. The current |
| * selection is not cleared before the new items are selected. |
| * <p> |
| * If an item in the given range is not selected, it is selected. If an item |
| * in the given range was already selected, it remains selected. Indices |
| * that are out of range are ignored and no items will be selected if start |
| * is greater than end. If the receiver is single-select and there is more |
| * than one item in the given range, then all indices are ignored. |
| * |
| * @param start the start of the range |
| * @param end the end of the range |
| * @see List#setSelection(int,int) |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if not |
| * called from the thread that created the receiver</li> |
| * </ul> |
| */ |
| public void selectDoNotFireEvent(final int start, final int end) { |
| select(start, end, false); |
| } |
| |
| /** |
| * Select. |
| * |
| * @param start the start |
| * @param end the end |
| * @param shouldFireEvents the should fire events |
| */ |
| private void select(final int start, final int end, final boolean shouldFireEvents) { |
| checkWidget(); |
| if (start > end) { |
| SWT.error(SWT.ERROR_INVALID_RANGE); |
| } |
| final List<DLItem> selectedItems = new ArrayList<DLItem>(); |
| for (int index = start; index <= end; index++) { |
| if (index < 0 || index >= items.size()) { |
| continue; |
| } |
| final DLItem item = items.get(index); |
| item.setLastAction(LAST_ACTION.SELECTION); |
| selectedItems.add(item); |
| selection.add(item); |
| if (shouldFireEvents) { |
| fireSelectionEvent(item); |
| } |
| } |
| if (shouldFireEvents) { |
| fireSelectionChangeEvent(selectedItems); |
| } |
| redrawTables(); |
| } |
| |
| /** |
| * Selects all of the items in the receiver. |
| * <p> |
| * If the receiver is single-select, do nothing. |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void selectAll() { |
| selectAll(true); |
| } |
| |
| /** |
| * Selects all of the items in the receiver. |
| * <p> |
| * If the receiver is single-select, do nothing. |
| * |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void selectAllDoNotFireEvent() { |
| selectAll(false); |
| } |
| |
| /** |
| * Select all. |
| * |
| * @param shouldFireEvents the should fire events |
| */ |
| private void selectAll(final boolean shouldFireEvents) { |
| checkWidget(); |
| selection.addAll(items); |
| if (shouldFireEvents) { |
| for (final DLItem item : items) { |
| fireSelectionEvent(item); |
| } |
| } |
| |
| if (shouldFireEvents) { |
| final List<DLItem> selectedItems = new ArrayList<DLItem>(); |
| for (final DLItem item : items) { |
| item.setLastAction(LAST_ACTION.SELECTION); |
| selectedItems.add(item); |
| } |
| fireSelectionChangeEvent(selectedItems); |
| } |
| items.clear(); |
| redrawTables(); |
| } |
| |
| /** |
| * Sets the bounds. |
| * |
| * @param x the x |
| * @param y the y |
| * @param width the width |
| * @param height the height |
| * @see org.eclipse.swt.widgets.Control#setBounds(int, int, int, int) |
| */ |
| @Override |
| public void setBounds(final int x, final int y, final int width, final int height) { |
| super.setBounds(x, y, width, height); |
| final boolean itemsContainImage = itemsContainImage(); |
| final Point itemsTableDefaultSize = itemsTable.computeSize(SWT.DEFAULT, SWT.DEFAULT); |
| final Point selectionTableDefaultSize = selectionTable.computeSize(SWT.DEFAULT, SWT.DEFAULT); |
| |
| int itemsTableSize = itemsTable.getSize().x; |
| if (itemsTableDefaultSize.y > itemsTable.getSize().y) { |
| itemsTableSize -= itemsTable.getVerticalBar().getSize().x; |
| } |
| |
| int selectionTableSize = selectionTable.getSize().x; |
| if (selectionTableDefaultSize.y > selectionTable.getSize().y) { |
| selectionTableSize -= selectionTable.getVerticalBar().getSize().x; |
| } |
| |
| if (itemsContainImage) { |
| itemsTable.getColumn(0).pack(); |
| itemsTable.getColumn(1).setWidth(itemsTableSize - itemsTable.getColumn(0).getWidth()); |
| |
| selectionTable.getColumn(0).pack(); |
| selectionTable.getColumn(1).setWidth(selectionTableSize - selectionTable.getColumn(0).getWidth()); |
| |
| } else { |
| itemsTable.getColumn(0).setWidth(itemsTableSize); |
| selectionTable.getColumn(0).setWidth(selectionTableSize); |
| } |
| |
| itemsTable.getColumn(0).pack(); |
| selectionTable.getColumn(0).pack(); |
| } |
| |
| /** |
| * Items contain image. |
| * |
| * @return <code>true</code> if any item contains an image |
| */ |
| private boolean itemsContainImage() { |
| for (final DLItem item : items) { |
| if (item.getImage() != null) { |
| return true; |
| } |
| } |
| |
| for (final DLItem item : selection) { |
| if (item.getImage() != null) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Sets the item in the receiver's list at the given zero-relative index to |
| * the item argument. |
| * |
| * @param index the index for the item |
| * @param item the new item |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_INVALID_RANGE - if the index is not between 0 |
| * and the number of elements in the list minus 1 (inclusive) |
| * </li> |
| * <li>ERROR_NULL_ARGUMENT - if the item is null</li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setItem(final int index, final DLItem item) { |
| checkWidget(); |
| if (item == null) { |
| SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| } |
| if (index < 0 || index >= items.size()) { |
| SWT.error(SWT.ERROR_INVALID_RANGE); |
| } |
| items.set(index, item); |
| redrawTables(); |
| } |
| |
| /** |
| * Sets the receiver's items to be the given array of items. |
| * |
| * @param items the array of items |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the items array is null</li> |
| * <li>ERROR_INVALID_ARGUMENT - if an item in the items array |
| * is null</li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setItems(final DLItem[] items) { |
| checkWidget(); |
| if (items == null) { |
| SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| } |
| |
| final List<DLItem> temp = new ArrayList<DLItem>(); |
| for (final DLItem item : items) { |
| if (item == null) { |
| SWT.error(SWT.ERROR_INVALID_ARGUMENT); |
| } |
| temp.add(item); |
| } |
| this.items.clear(); |
| this.items.addAll(temp); |
| redrawTables(); |
| } |
| |
| /** |
| * Sets the receiver's items to be the given list of items. |
| * |
| * @param items the list of items |
| * |
| * @exception IllegalArgumentException |
| * <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the items list is null</li> |
| * <li>ERROR_INVALID_ARGUMENT - if an item in the items list |
| * is null</li> |
| * </ul> |
| * @exception SWTException |
| * <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver has been |
| * disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the |
| * thread that created the receiver</li> |
| * </ul> |
| */ |
| public void setItems(final List<DLItem> items) { |
| checkWidget(); |
| checkWidget(); |
| if (items == null) { |
| SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| } |
| |
| final List<DLItem> temp = new ArrayList<DLItem>(); |
| for (final DLItem item : items) { |
| if (item == null) { |
| SWT.error(SWT.ERROR_INVALID_ARGUMENT); |
| } |
| temp.add(item); |
| } |
| this.items.clear(); |
| this.items.addAll(temp); |
| redrawTables(); |
| } |
| |
| /** |
| * Redraws all tables that compose this widget. |
| */ |
| private void redrawTables() { |
| setRedraw(false); |
| redrawTable(itemsTable, false); |
| redrawTable(selectionTable, true); |
| setRedraw(true); |
| this.setBounds(getBounds()); |
| } |
| |
| /** |
| * Redraw a given table. |
| * |
| * @param table table to be redrawned |
| * @param isSelected if <code>true</code>, fill the table with the |
| * selection. Otherwise, fill the table with the unselected |
| * items. |
| */ |
| private void redrawTable(final Table table, final boolean isSelected) { |
| clean(table); |
| fillData(table, isSelected ? selection : items); |
| } |
| |
| /** |
| * Cleans the content of a table. |
| * |
| * @param table table to be emptied |
| */ |
| private void clean(final Table table) { |
| if (table == null) { |
| return; |
| } |
| |
| for (final TableItem item : table.getItems()) { |
| item.dispose(); |
| } |
| } |
| |
| /** |
| * Fill a table with data. |
| * |
| * @param table table to be filled |
| * @param listOfData list of data |
| */ |
| private void fillData(final Table table, final List<DLItem> listOfData) { |
| final boolean itemsContainImage = itemsContainImage(); |
| for (final DLItem item : listOfData) { |
| final TableItem tableItem = new TableItem(table, SWT.NONE); |
| tableItem.setData(item); |
| |
| if (item.getBackground() != null) { |
| tableItem.setBackground(item.getBackground()); |
| } |
| |
| if (item.getForeground() != null) { |
| tableItem.setForeground(item.getForeground()); |
| } |
| |
| if (item.getImage() != null) { |
| tableItem.setImage(0, item.getImage()); |
| } |
| |
| if (item.getFont() != null) { |
| tableItem.setFont(item.getFont()); |
| } |
| final int textColumn = itemsContainImage ? 1 : 0; |
| tableItem.setText(textColumn, item.getText()); |
| } |
| } |
| |
| /** |
| * Move the selected item to the first position. |
| */ |
| protected void moveSelectionToFirstPosition() { |
| if (selectionTable.getSelectionCount() == 0) { |
| return; |
| } |
| |
| int index = 0; |
| for (final TableItem tableItem : selectionTable.getSelection()) { |
| final DLItem item = (DLItem) tableItem.getData(); |
| selection.remove(item); |
| selection.add(index++, item); |
| } |
| |
| redrawTables(); |
| selectionTable.select(0, index - 1); |
| selectionTable.forceFocus(); |
| } |
| |
| /** |
| * Select a given item. |
| */ |
| protected void selectItem() { |
| if (itemsTable.getSelectionCount() == 0) { |
| return; |
| } |
| final List<DLItem> selectedItems = new ArrayList<DLItem>(); |
| for (final TableItem tableItem : itemsTable.getSelection()) { |
| final DLItem item = (DLItem) tableItem.getData(); |
| item.setLastAction(LAST_ACTION.SELECTION); |
| selectedItems.add(item); |
| selection.add(item); |
| items.remove(item); |
| fireSelectionEvent(item); |
| } |
| fireSelectionChangeEvent(selectedItems); |
| |
| redrawTables(); |
| } |
| |
| /** |
| * Move the selected item up. |
| */ |
| protected void moveUpItem() { |
| if (selectionTable.getSelectionCount() == 0) { |
| return; |
| } |
| |
| for (final int index : selectionTable.getSelectionIndices()) { |
| if (index == 0) { |
| selectionTable.forceFocus(); |
| return; |
| } |
| } |
| |
| final int[] newSelection = new int[selectionTable.getSelectionCount()]; |
| int newSelectionIndex = 0; |
| for (final TableItem tableItem : selectionTable.getSelection()) { |
| final int position = selection.indexOf(tableItem.getData()); |
| swap(position, position - 1); |
| newSelection[newSelectionIndex++] = position - 1; |
| } |
| |
| redrawTables(); |
| selectionTable.select(newSelection); |
| selectionTable.forceFocus(); |
| } |
| |
| /** |
| * Deselect a given item. |
| */ |
| protected void deselectItem() { |
| if (selectionTable.getSelectionCount() == 0) { |
| return; |
| } |
| final List<DLItem> deselectedItems = new ArrayList<DLItem>(); |
| for (final TableItem tableItem : selectionTable.getSelection()) { |
| final DLItem item = (DLItem) tableItem.getData(); |
| item.setLastAction(LAST_ACTION.DESELECTION); |
| deselectedItems.add(item); |
| items.add(item); |
| selection.remove(item); |
| fireSelectionEvent(item); |
| } |
| fireSelectionChangeEvent(deselectedItems); |
| redrawTables(); |
| } |
| |
| /** |
| * Move the selected item down. |
| */ |
| protected void moveDownItem() { |
| if (selectionTable.getSelectionCount() == 0) { |
| return; |
| } |
| |
| for (final int index : selectionTable.getSelectionIndices()) { |
| if (index == selectionTable.getItemCount() - 1) { |
| selectionTable.forceFocus(); |
| return; |
| } |
| } |
| |
| final int[] newSelection = new int[selectionTable.getSelectionCount()]; |
| int newSelectionIndex = 0; |
| for (final TableItem tableItem : selectionTable.getSelection()) { |
| final int position = selection.indexOf(tableItem.getData()); |
| swap(position, position + 1); |
| newSelection[newSelectionIndex++] = position + 1; |
| } |
| |
| redrawTables(); |
| selectionTable.select(newSelection); |
| selectionTable.forceFocus(); |
| } |
| |
| /** |
| * Swap 2 items. |
| * |
| * @param first position of the first item to swap |
| * @param second position of the second item to swap |
| */ |
| private void swap(final int first, final int second) { |
| final DLItem temp = selection.get(first); |
| selection.set(first, selection.get(second)); |
| selection.set(second, temp); |
| } |
| |
| /** |
| * Move the selected item to the last position. |
| */ |
| protected void moveSelectionToLastPosition() { |
| if (selectionTable.getSelectionCount() == 0) { |
| return; |
| } |
| |
| final int numberOfSelectedElements = selectionTable.getSelectionCount(); |
| for (final TableItem tableItem : selectionTable.getSelection()) { |
| final DLItem item = (DLItem) tableItem.getData(); |
| selection.remove(item); |
| selection.add(item); |
| } |
| |
| redrawTables(); |
| final int numberOfElements = selectionTable.getItemCount(); |
| selectionTable.select(numberOfElements - numberOfSelectedElements, numberOfElements - 1); |
| selectionTable.forceFocus(); |
| } |
| |
| /** |
| * Call all selection listeners. |
| * |
| * @param item selected item |
| */ |
| private void fireSelectionEvent(final DLItem item) { |
| if (selectionListeners == null) { |
| return; |
| } |
| |
| final Event event = new Event(); |
| event.button = 1; |
| event.display = getDisplay(); |
| event.item = null; |
| event.widget = this; |
| event.data = item; |
| final SelectionEvent selectionEvent = new SelectionEvent(event); |
| |
| for (final SelectionListener listener : selectionListeners) { |
| listener.widgetSelected(selectionEvent); |
| } |
| } |
| |
| /** |
| * Fire selection change event. |
| * |
| * @param items the items |
| */ |
| private void fireSelectionChangeEvent(final List<DLItem> items) { |
| if (selectionChangeListeners == null) { |
| return; |
| } |
| |
| final Event event = new Event(); |
| event.button = 1; |
| event.display = getDisplay(); |
| event.item = null; |
| event.widget = this; |
| final SelectionChangeEvent selectionChangeEvent = new SelectionChangeEvent(event); |
| selectionChangeEvent.setItems(items); |
| |
| for (final SelectionChangeListener listener : selectionChangeListeners) { |
| listener.widgetSelected(selectionChangeEvent); |
| } |
| } |
| } |