/******************************************************************************* * Copyright (c) 2000, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * compeople AG - created this example based on Snippet15 *******************************************************************************/ package org.eclipse.riena.navigation.ui.swt.views; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; /** * Create a tree with non-selectable items. */ public class SnippetNonSelectableTreeItems { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setLayout(new FillLayout()); final Tree tree = new Tree(shell, SWT.BORDER | SWT.SINGLE); for (int i = 0; i < 4; i++) { TreeItem iItem = new TreeItem(tree, 0); iItem.setText("TreeItem (0) -" + i); if (i % 2 == 1) { markNonSelectable(iItem); iItem.setText("not selectable"); } for (int j = 0; j < 4; j++) { TreeItem jItem = new TreeItem(iItem, 0); jItem.setText("TreeItem (1) -" + j); if (j % 2 == 0) { markNonSelectable(jItem); jItem.setText("not selectable"); } for (int k = 0; k < 4; k++) { TreeItem kItem = new TreeItem(jItem, 0); kItem.setText("TreeItem (2) -" + k); for (int l = 0; l < 4; l++) { TreeItem lItem = new TreeItem(kItem, 0); lItem.setText("TreeItem (3) -" + l); } } } } new TreeListener(tree); shell.setSize(200, 200); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } /** * Prevent selection of certain items. Find a matching alternative is * possible. */ private static final class TreeListener extends KeyAdapter implements SelectionListener, MouseListener { private int lastKey; private int lastButton; private TreeItem lastItem; public TreeListener(Tree tree) { tree.addKeyListener(this); tree.addSelectionListener(this); tree.addMouseListener(this); } @Override public void keyPressed(KeyEvent e) { if (e.stateMask == 0) { lastKey = e.keyCode; } } @Override public void keyReleased(KeyEvent e) { lastKey = 0; } public void mouseDown(MouseEvent e) { lastButton = e.button; } public void mouseUp(MouseEvent e) { lastButton = 0; } public void widgetSelected(SelectionEvent e) { System.out.println(e); Tree tree = (Tree) e.widget; TreeItem[] sel = tree.getSelection(); if (sel.length > 0) { TreeItem item = sel[0]; if (!isSelectable(item)) { if (lastKey == SWT.ARROW_UP || lastKey == SWT.ARROW_LEFT) { item = findPrevious(item); } else if (lastKey == SWT.ARROW_DOWN || lastKey == SWT.ARROW_RIGHT || lastButton != 0) { item = findNext(item); } if (item != null) { item.getParent().select(item); } else { lastItem.getParent().setSelection(lastItem); } } if (item != null) { lastItem = item; } } } public void widgetDefaultSelected(SelectionEvent e) { // unused } public void mouseDoubleClick(MouseEvent e) { // unused } }; private static boolean isSelectable(TreeItem item) { return item == null ? true : !Boolean.FALSE.equals(item.getData("s")); } /** * Mark this item as 'non-selectable'. */ private static void markNonSelectable(TreeItem item) { item.setData("s", Boolean.FALSE); } private static TreeItem findPrevious(TreeItem item) { List siblings = sequentialize(item.getParent().getItems()); int index = siblings.indexOf(item); TreeItem result = index > 0 ? siblings.get(index - 1) : null; if (!isSelectable(result)) { result = findPrevious(result); } return result; } private static TreeItem findNext(TreeItem item) { List siblings = sequentialize(item.getParent().getItems()); int index = siblings.indexOf(item); TreeItem result = index != -1 && index < siblings.size() - 1 ? siblings.get(index + 1) : null; if (!isSelectable(result)) { result = findNext(result); } return result; } /** * Do a DFS traversal and return all reachable nodes starting from root * (excluded). */ private static List sequentialize(TreeItem[] siblings) { List stack = new ArrayList(Arrays.asList(siblings)); List result = new ArrayList(); while (!stack.isEmpty()) { TreeItem item = stack.remove(0); result.add(item); if (item.getExpanded()) { stack.addAll(0, Arrays.asList(item.getItems())); } } return result; } }