Mercurial > projects > dwt2
diff org.eclipse.jface.examples.databinding/src/org/eclipse/jface/examples/databinding/snippets/Snippet006Spreadsheet.d @ 90:6086085e153d
Added databinding snippets. unmodified java sources.
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 19 Apr 2009 11:33:55 +0200 |
parents | |
children | 5d5bd660917f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/org.eclipse.jface.examples.databinding/src/org/eclipse/jface/examples/databinding/snippets/Snippet006Spreadsheet.d Sun Apr 19 11:33:55 2009 +0200 @@ -0,0 +1,315 @@ +/******************************************************************************* + * Copyright (c) 2006, 2007 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 + * Brad Reynolds - bug 116920 + *******************************************************************************/ + +package org.eclipse.jface.examples.databinding.snippets; + +import java.text.NumberFormat; +import java.text.ParseException; + +import org.eclipse.core.databinding.observable.Realm; +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.core.databinding.observable.value.ComputedValue; +import org.eclipse.core.databinding.observable.value.IObservableValue; +import org.eclipse.core.databinding.observable.value.WritableValue; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.jface.internal.databinding.provisional.swt.TableUpdater; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ControlEditor; +import org.eclipse.swt.custom.TableCursor; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +/** + * @since 1.1 + * + */ +public class Snippet006Spreadsheet { + + private static final int COUNTER_UPDATE_DELAY = 1000; + + private static final int NUM_COLUMNS = 6; + + private static final int NUM_ROWS = 16; + + /** + * 0 for no output, 1 for some, 2 for more + */ + private static int DEBUG_LEVEL = 0; + + /** + * If true, there will be a automatic counter at B1. + */ + private static boolean FUNKY_COUNTER = false; + + /** + * // * If true, all formulas (except for row 1 and column A) will be the + * sum of the values of their left and top neighbouring cells. + */ + private static boolean FUNKY_FORMULAS = true; + + static WritableValue[][] cellFormulas = new WritableValue[NUM_ROWS][NUM_COLUMNS]; + + static ComputedValue[][] cellValues = new ComputedValue[NUM_ROWS][NUM_COLUMNS]; + + static class ComputedCellValue extends ComputedValue { + private final IObservableValue cellFormula; + + private boolean calculating; + + ComputedCellValue(IObservableValue cellFormula) { + this.cellFormula = cellFormula; + } + + protected Object calculate() { + if (calculating) { + return "#cycle"; + } + try { + calculating = true; + return evaluate(cellFormula.getValue()); + } finally { + calculating = false; + } + } + + private Object evaluate(Object value) { + if (DEBUG_LEVEL >= 2) { + System.out.println("evaluating " + this + " ..."); + } + if (value == null) { + return ""; + } + try { + String s = (String) value; + if (!s.startsWith("=")) { + return s; + } + String addition = s.substring(1); + int indexOfPlus = addition.indexOf('+'); + String operand1 = addition.substring(0, indexOfPlus); + double value1 = eval(operand1); + String operand2 = addition.substring(indexOfPlus + 1); + double value2 = eval(operand2); + return NumberFormat.getNumberInstance().format(value1 + value2); + } catch (Exception ex) { + return ex.getMessage(); + } + } + + /** + * @param s + * @return + * @throws ParseException + */ + private double eval(String s) throws ParseException { + if (s.length() == 0) { + return 0; + } + char character = s.charAt(0); + if (Character.isLetter(character)) { + character = Character.toLowerCase(character); + // reference to other cell + int columnIndex = character - 'a'; + int rowIndex = 0; + rowIndex = NumberFormat.getNumberInstance().parse( + s.substring(1)).intValue() - 1; + String value = (String) cellValues[rowIndex][columnIndex] + .getValue(); + return value.length() == 0 ? 0 : NumberFormat + .getNumberInstance().parse(value).doubleValue(); + } + return NumberFormat.getNumberInstance().parse(s).doubleValue(); + } + } + + protected static int counter; + + public static void main(String[] args) { + + final Display display = new Display(); + Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() { + public void run() { + Shell shell = new Shell(display); + shell.setText("Data Binding Snippet 006"); + + final Table table = new Table(shell, SWT.BORDER | SWT.MULTI + | SWT.FULL_SELECTION | SWT.VIRTUAL); + table.setLinesVisible(true); + table.setHeaderVisible(true); + + for (int i = 0; i < NUM_COLUMNS; i++) { + TableColumn tableColumn = new TableColumn(table, SWT.NONE); + tableColumn.setText(Character.toString((char) ('A' + i))); + tableColumn.setWidth(60); + } + WritableList list = new WritableList(); + for (int i = 0; i < NUM_ROWS; i++) { + list.add(new Object()); + for (int j = 0; j < NUM_COLUMNS; j++) { + cellFormulas[i][j] = new WritableValue(); + cellValues[i][j] = new ComputedCellValue( + cellFormulas[i][j]); + if (!FUNKY_FORMULAS || i == 0 || j == 0) { + cellFormulas[i][j].setValue(""); + } else { + cellFormulas[i][j].setValue("=" + + cellReference(i - 1, j) + "+" + + cellReference(i, j - 1)); + } + } + } + + new TableUpdater(table, list) { + protected void updateItem(int rowIndex, TableItem item, Object element) { + if (DEBUG_LEVEL >= 1) { + System.out.println("updating row " + rowIndex); + } + for (int j = 0; j < NUM_COLUMNS; j++) { + item.setText(j, (String) cellValues[rowIndex][j] + .getValue()); + } + } + }; + + if (FUNKY_COUNTER) { + // counter in A1 + display.asyncExec(new Runnable() { + public void run() { + cellFormulas[0][1].setValue("" + counter++); + display.timerExec(COUNTER_UPDATE_DELAY, this); + } + }); + } + + // create a TableCursor to navigate around the table + final TableCursor cursor = new TableCursor(table, SWT.NONE); + // create an editor to edit the cell when the user hits "ENTER" + // while over a cell in the table + final ControlEditor editor = new ControlEditor(cursor); + editor.grabHorizontal = true; + editor.grabVertical = true; + + cursor.addSelectionListener(new SelectionAdapter() { + // when the TableEditor is over a cell, select the + // corresponding row + // in + // the table + public void widgetSelected(SelectionEvent e) { + table.setSelection(new TableItem[] { cursor.getRow() }); + } + + // when the user hits "ENTER" in the TableCursor, pop up a + // text + // editor so that + // they can change the text of the cell + public void widgetDefaultSelected(SelectionEvent e) { + final Text text = new Text(cursor, SWT.NONE); + TableItem row = cursor.getRow(); + int rowIndex = table.indexOf(row); + int columnIndex = cursor.getColumn(); + text + .setText((String) cellFormulas[rowIndex][columnIndex] + .getValue()); + text.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + // close the text editor and copy the data over + // when the user hits "ENTER" + if (e.character == SWT.CR) { + TableItem row = cursor.getRow(); + int rowIndex = table.indexOf(row); + int columnIndex = cursor.getColumn(); + cellFormulas[rowIndex][columnIndex] + .setValue(text.getText()); + text.dispose(); + } + // close the text editor when the user hits + // "ESC" + if (e.character == SWT.ESC) { + text.dispose(); + } + } + }); + editor.setEditor(text); + text.setFocus(); + } + }); + // Hide the TableCursor when the user hits the "MOD1" or "MOD2" + // key. + // This alows the user to select multiple items in the table. + cursor.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (e.keyCode == SWT.MOD1 || e.keyCode == SWT.MOD2 + || (e.stateMask & SWT.MOD1) != 0 + || (e.stateMask & SWT.MOD2) != 0) { + cursor.setVisible(false); + } + } + }); + // Show the TableCursor when the user releases the "MOD2" or + // "MOD1" key. + // This signals the end of the multiple selection task. + table.addKeyListener(new KeyAdapter() { + public void keyReleased(KeyEvent e) { + if (e.keyCode == SWT.MOD1 + && (e.stateMask & SWT.MOD2) != 0) + return; + if (e.keyCode == SWT.MOD2 + && (e.stateMask & SWT.MOD1) != 0) + return; + if (e.keyCode != SWT.MOD1 + && (e.stateMask & SWT.MOD1) != 0) + return; + if (e.keyCode != SWT.MOD2 + && (e.stateMask & SWT.MOD2) != 0) + return; + + TableItem[] selection = table.getSelection(); + TableItem row = (selection.length == 0) ? table + .getItem(table.getTopIndex()) : selection[0]; + table.showItem(row); + cursor.setSelection(row, 0); + cursor.setVisible(true); + cursor.setFocus(); + } + }); + + GridLayoutFactory.fillDefaults().generateLayout(shell); + shell.setSize(400, 300); + shell.open(); + + // The SWT event loop + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + } + }); + display.dispose(); + } + + private static String cellReference(int rowIndex, int columnIndex) { + String cellReference = "" + ((char) ('A' + columnIndex)) + + (rowIndex + 1); + return cellReference; + } + +}