Java tutorial
/******************************************************************************* * Copyright (c) 6 dec. 2012 NetXForge. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> * * Contributors: Christophe Bouhier - initial API and implementation and/or * initial documentation *******************************************************************************/ package com.netxforge.screens.editing.base.tables; import org.eclipse.jface.viewers.ColumnViewer; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.TreeViewerRow; import org.eclipse.jface.viewers.ViewerCell; import org.eclipse.jface.viewers.ViewerRow; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Item; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; /** * A Focus block Manager for a tree viewer. * * @author Christophe Bouhier */ public class TreeViewerFocusBlockManager extends SWTFocusBlockManager { private static final CellNavigationStrategyExposed TREE_NAVIGATE = new CellNavigationStrategyExposed() { public void collapse(ColumnViewer viewer, ViewerCell cellToCollapse, Event event) { if (cellToCollapse != null) { ((TreeItem) cellToCollapse.getItem()).setExpanded(false); } } public void expand(ColumnViewer viewer, ViewerCell cellToExpand, Event event) { if (cellToExpand != null) { OpenTreeViewer v = (OpenTreeViewer) viewer; v.setExpandedState(v.getTreePathFromItemExposed((Item) cellToExpand.getItem()), true); } } public boolean isCollapseEvent(ColumnViewer viewer, ViewerCell cellToCollapse, Event event) { if (cellToCollapse == null) { return false; } return cellToCollapse != null && ((TreeItem) cellToCollapse.getItem()).getExpanded() && event.keyCode == SWT.ARROW_LEFT && isFirstColumnCell(cellToCollapse); } public boolean isExpandEvent(ColumnViewer viewer, ViewerCell cellToExpand, Event event) { if (cellToExpand == null) { return false; } return cellToExpand != null && ((TreeItem) cellToExpand.getItem()).getItemCount() > 0 && !((TreeItem) cellToExpand.getItem()).getExpanded() && event.keyCode == SWT.ARROW_RIGHT && isFirstColumnCell(cellToExpand); } private boolean isFirstColumnCell(ViewerCell cell) { // CB VisualIndex is not exposed through API, so look for it the TreeViewerRow impl. TreeViewerRow viewerRow = (TreeViewerRow) cell.getViewerRow(); return viewerRow.getVisualIndex(cell.getColumnIndex()) == 0; } }; /** * Create a new manager using a default navigation strategy: * <ul> * <li><code>SWT.ARROW_UP</code>: navigate to cell above</li> * <li><code>SWT.ARROW_DOWN</code>: navigate to cell below</li> * <li><code>SWT.ARROW_RIGHT</code>: on first column (collapses if item is * expanded) else navigate to next visible cell on the right</li> * <li><code>SWT.ARROW_LEFT</code>: on first column (expands if item is * collapsed) else navigate to next visible cell on the left</li> * </ul> * * @param viewer * the viewer the manager is bound to * @param focusDrawingDelegate * the delegate responsible to highlight selected cell */ public TreeViewerFocusBlockManager(TreeViewer viewer, FocusBlockHighlighter focusDrawingDelegate) { this(viewer, focusDrawingDelegate, TREE_NAVIGATE); } /** * Create a new manager with a custom navigation strategy * * @param viewer * the viewer the manager is bound to * @param focusDrawingDelegate * the delegate responsible to highlight selected cell * @param navigationStrategy * the strategy used to navigate the cells * @since 3.4 */ public TreeViewerFocusBlockManager(TreeViewer viewer, FocusBlockHighlighter focusDrawingDelegate, CellNavigationStrategyExposed navigationStrategy) { super(viewer, focusDrawingDelegate, navigationStrategy); } ViewerCell getInitialFocusCell() { Tree tree = (Tree) getViewer().getControl(); if (!tree.isDisposed() && tree.getItemCount() > 0 && !tree.getTopItem().isDisposed()) { OpenTreeViewer v = (OpenTreeViewer) getViewer(); ViewerRow aViewerRow = v.getViewerRowFromItemExposed(tree.getTopItem()); if (tree.getColumnCount() == 0) { return aViewerRow.getCell(0); } Rectangle clientArea = tree.getClientArea(); for (int i = 0; i < tree.getColumnCount(); i++) { // CB, getWidth() is not available through the API. int width = aViewerRow.getBounds(i).width; if (width > 0 && columnInVisibleArea(clientArea, aViewerRow, i)) return aViewerRow.getCell(i); } } return null; } private boolean columnInVisibleArea(Rectangle clientArea, ViewerRow row, int colIndex) { return row.getBounds(colIndex).x >= clientArea.x; } public ViewerCell getFocusCell() { ViewerCell cell = super.getFocusCell(); Tree t = (Tree) getViewer().getControl(); // It is possible that the selection has changed under the hood if (cell != null) { if (t.getSelection().length == 1 && t.getSelection()[0] != cell.getItem()) { OpenTreeViewer v = (OpenTreeViewer) this.getViewer(); setFocusCell(v.getViewerRowFromItemExposed(t.getSelection()[0]).getCell(cell.getColumnIndex())); } } return super.getFocusCell(); } }