Add SWT UI
In order to add a new UI the core functionality of the calculator is
separated from the UI code.
Change-Id: I855a7554471ac45f62a7ce98d7cc6d07652f1d80
Signed-off-by: Stefan Lay <stefan.lay@sap.com>
diff --git a/org.eclipse.example.calc/META-INF/MANIFEST.MF b/org.eclipse.example.calc/META-INF/MANIFEST.MF
index f371248..d89f64e 100644
--- a/org.eclipse.example.calc/META-INF/MANIFEST.MF
+++ b/org.eclipse.example.calc/META-INF/MANIFEST.MF
@@ -6,7 +6,9 @@
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.6
Require-Bundle: org.junit4;bundle-version="[4.3.0,5.0.0)",
- org.hamcrest;bundle-version="[1.1.0,2.0.0)"
+ org.hamcrest;bundle-version="[1.1.0,2.0.0)",
+ org.eclipse.swt;bundle-version="[3.5.0,4.0.0)"
Export-Package: org.eclipse.example.calc;version="0.1.0",
org.eclipse.example.calc.internal.operations;version="0.1.0";x-internal:=true,
- org.eclipse.example.calc.internal.ui;version="0.1.0";x-internal:=true
+ org.eclipse.example.calc.internal.ui.swing;version="0.1.0";x-internal:=true,
+ org.eclipse.example.calc.internal.ui.swt;version="0.1.0";x-internal:=true
diff --git a/org.eclipse.example.calc/Calculator.launch b/org.eclipse.example.calc/SWTCalculatorUI.launch
similarity index 78%
copy from org.eclipse.example.calc/Calculator.launch
copy to org.eclipse.example.calc/SWTCalculatorUI.launch
index 00bf1b2..66e7080 100644
--- a/org.eclipse.example.calc/Calculator.launch
+++ b/org.eclipse.example.calc/SWTCalculatorUI.launch
@@ -1,15 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/ui/Calculator.java"/>
+<listEntry value="/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/ui/swt/CalculatorUI.java"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="1"/>
</listAttribute>
<mapAttribute key="org.eclipse.debug.core.preferred_launchers">
-<mapEntry key="[debug]" value="org.eclipse.jdt.launching.localJavaApplication"/>
<mapEntry key="[run]" value="org.eclipse.jdt.launching.localJavaApplication"/>
</mapAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.example.calc.internal.ui.Calculator"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.example.calc.internal.ui.swt.CalculatorUI"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.example.calc"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XstartOnFirstThread"/>
</launchConfiguration>
diff --git a/org.eclipse.example.calc/Calculator.launch b/org.eclipse.example.calc/SwingCalculatorUI.launch
similarity index 87%
rename from org.eclipse.example.calc/Calculator.launch
rename to org.eclipse.example.calc/SwingCalculatorUI.launch
index 00bf1b2..76ff670 100644
--- a/org.eclipse.example.calc/Calculator.launch
+++ b/org.eclipse.example.calc/SwingCalculatorUI.launch
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/ui/Calculator.java"/>
+<listEntry value="/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/ui/swing/CalculatorUI.java"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="1"/>
@@ -10,6 +10,6 @@
<mapEntry key="[debug]" value="org.eclipse.jdt.launching.localJavaApplication"/>
<mapEntry key="[run]" value="org.eclipse.jdt.launching.localJavaApplication"/>
</mapAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.example.calc.internal.ui.Calculator"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.example.calc.internal.ui.swing.CalculatorUI"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.example.calc"/>
</launchConfiguration>
diff --git a/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/Calculator.java b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/Calculator.java
new file mode 100644
index 0000000..8d1725b
--- /dev/null
+++ b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/Calculator.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Matthias Sohn <matthias.sohn@sap.com>
+ * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
+ *
+ * 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
+ *******************************************************************************/
+package org.eclipse.example.calc.internal;
+
+import org.eclipse.example.calc.BinaryOperation;
+import org.eclipse.example.calc.Operation;
+import org.eclipse.example.calc.Operations;
+import org.eclipse.example.calc.UnaryOperation;
+import org.eclipse.example.calc.internal.operations.Equals;
+import org.eclipse.example.calc.internal.operations.Minus;
+import org.eclipse.example.calc.internal.operations.Plus;
+import org.eclipse.example.calc.internal.operations.Square;
+
+public class Calculator {
+
+ private TextProvider textProvider;
+
+ private String cmd;
+
+ private boolean clearText;
+
+ private float value;
+
+ public static String NAME = "Simple Calculator";
+
+ public Calculator(TextProvider textProvider) {
+ this.textProvider = textProvider;
+ setupDefaultOperations();
+ }
+
+ private void setupDefaultOperations() {
+ new Equals();
+ new Minus();
+ new Plus();
+ new Square();
+ }
+
+ private void calculate(String cmdName) {
+ float curValue;
+ float newValue = 0;
+
+ // get current value of display
+ curValue = Float.parseFloat(textProvider.getDisplayText());
+
+ Operation currentOp = Operations.INSTANCE.getOperation(cmdName);
+ if ((currentOp instanceof BinaryOperation) && (cmd == null)) {
+ // if last clicked operation was binary and there is no saved
+ // operation, store it
+ cmd = cmdName;
+ setClearText(true);
+ } else {
+ // if saved command is binary perform it
+ Operation savedOp = Operations.INSTANCE.getOperation(cmd);
+ if (savedOp instanceof BinaryOperation) {
+ BinaryOperation bop = (BinaryOperation) savedOp;
+ newValue = bop.perform(value, curValue);
+ } // if current operation is unary perform it
+ else if (currentOp instanceof UnaryOperation) {
+ UnaryOperation uop = (UnaryOperation) currentOp;
+ newValue = uop.perform(curValue);
+ }
+
+ // display the result and prepare clear on next button
+ textProvider.setDisplayText("" + newValue);
+ setClearText(true);
+ if (currentOp instanceof Equals) {
+ // do not save "=" command
+ cmd = null;
+ } else if (currentOp instanceof BinaryOperation) {
+ // save binary commands as they are executed on next operation
+ cmd = cmdName;
+ } else {
+ // clear saved command
+ cmd = null;
+ }
+ }
+
+ }
+
+ private boolean isCommand(String name) {
+ return (Operations.INSTANCE.getOperation(name) != null);
+ }
+
+ public void handleButtonClick(String str) {
+ if (isCommand(str)) {
+ calculate(str);
+ } else {
+ char digit = (str.toCharArray())[0];
+ if (Character.isDigit(digit) || digit == '.') {
+ if (clearText) {
+ // save current value and clear the display
+ value = Float.parseFloat(textProvider.getDisplayText());
+ textProvider.setDisplayText("");
+ setClearText(false);
+ }
+
+ // add new digit to display
+ textProvider.setDisplayText(textProvider.getDisplayText() + digit);
+ }
+ }
+ }
+
+ public void setClearText(boolean clearText) {
+ this.clearText = clearText;
+ }
+}
diff --git a/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/TextProvider.java b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/TextProvider.java
new file mode 100644
index 0000000..4a1993d
--- /dev/null
+++ b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/TextProvider.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
+ *
+ * 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
+ *******************************************************************************/
+package org.eclipse.example.calc.internal;
+
+/**
+ * Display abstraction for {@link Calculator}
+ */
+public interface TextProvider {
+
+ /**
+ * @param text the text to display on the {@link Calculator}
+ */
+ public void setDisplayText(String text);
+
+ /**
+ * @return the text on the display of the {@link Calculator}
+ */
+ public String getDisplayText();
+
+}
diff --git a/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/ui/Calculator.java b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/ui/Calculator.java
deleted file mode 100644
index 0e2a35d..0000000
--- a/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/ui/Calculator.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Matthias Sohn <matthias.sohn@sap.com>
- *
- * 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
- *******************************************************************************/
-package org.eclipse.example.calc.internal.ui;
-
-import java.awt.BorderLayout;
-import java.awt.Container;
-import java.awt.GridLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-import javax.swing.BorderFactory;
-import javax.swing.JButton;
-import javax.swing.JFrame;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-import javax.swing.border.TitledBorder;
-
-import org.eclipse.example.calc.BinaryOperation;
-import org.eclipse.example.calc.Operation;
-import org.eclipse.example.calc.Operations;
-import org.eclipse.example.calc.UnaryOperation;
-import org.eclipse.example.calc.internal.operations.Equals;
-import org.eclipse.example.calc.internal.operations.Minus;
-import org.eclipse.example.calc.internal.operations.Plus;
-import org.eclipse.example.calc.internal.operations.Square;
-
-/*
- * A simple calculator featuring a Swing UI.
- */
-public class Calculator extends JFrame implements ActionListener {
- private static final long serialVersionUID = 1L;
-
- private String cmd;
-
- private boolean clearDisplay;
-
- private float value;
-
- private JTextField display;
-
- private JPanel buttonsPanel;
-
- private JPanel numberButtonsPanel;
-
- private JPanel cmdButtonsPanel;
-
- private JButton numberButtons[];
-
- private JButton cmdButtons[];
-
- public static void main(String args[]) {
- new Calculator().setVisible(true);
- }
-
- public Calculator() {
- setupOperations();
- setupGUI();
- }
-
- private void setupOperations() {
- new Equals();
- new Minus();
- new Plus();
- new Square();
- }
-
- private void setupGUI() {
- setTitle("Simple Calculator");
- Container c = getContentPane();
- c.setLayout(new BorderLayout());
- setLocationByPlatform(true);
-
- setupDisplay(c);
- setupButtonsPanel(c);
- setupNumberButtons();
- setupCommandButtons();
-
- pack();
- }
-
- private void setupDisplay(Container c) {
- display = new JTextField("0");
- display.setHorizontalAlignment(JTextField.TRAILING);
- c.add(display, BorderLayout.NORTH);
- // initially clear the display
- clearDisplay = true;
- }
-
- private void setupButtonsPanel(Container c) {
- buttonsPanel = new JPanel();
- buttonsPanel.setLayout(new GridLayout(2, 1));
- c.add(buttonsPanel);
- }
-
- private void setupNumberButtons() {
- numberButtonsPanel = new JPanel();
- numberButtonsPanel.setLayout(new GridLayout(3, 4));
- buttonsPanel.add(numberButtonsPanel, BorderLayout.CENTER);
- numberButtons = new JButton[11];
-
- for (int i = 0; i < numberButtons.length - 1; i++) {
- addNumberButton(i, Integer.valueOf(i).toString());
- }
- addNumberButton(10, ".");
- }
-
- private void addNumberButton(int i, String name) {
- numberButtons[i] = new JButton();
- numberButtons[i].setText(name);
- numberButtons[i].addActionListener(this);
- numberButtonsPanel.add(numberButtons[i]);
- }
-
- private void setupCommandButtons() {
- // command buttons
- cmdButtonsPanel = new JPanel();
- cmdButtonsPanel.setLayout(new GridLayout(1, 0));
- buttonsPanel.add(cmdButtonsPanel, BorderLayout.CENTER);
- TitledBorder title = BorderFactory.createTitledBorder("Operations");
- cmdButtonsPanel.setBorder(title);
- cmdButtons = new JButton[Operations.INSTANCE.size()];
-
- // make the buttons, set ActionListener and add to panel
- for (int i = 0; i < cmdButtons.length; i++) {
- addCommandButton(i);
- }
- }
-
- private void addCommandButton(int i) {
- cmdButtons[i] = new JButton();
- cmdButtons[i].setText(Operations.INSTANCE.getOperationName(i));
- cmdButtons[i].addActionListener(this);
- cmdButtonsPanel.add(cmdButtons[i]);
- }
-
- public void actionPerformed(ActionEvent e) {
- String str = e.getActionCommand();
- if (isCommand(str)) {
- calculate(str);
- } else {
- char digit = (str.toCharArray())[0];
- if (Character.isDigit(digit) || digit == '.') {
- if (clearDisplay) {
- // save current value and clear the display
- value = Float.parseFloat(display.getText());
- display.setText("");
- clearDisplay = false;
- }
-
- // add new digit to display
- display.setText(display.getText() + digit);
- }
- }
- }
-
- private boolean isCommand(String name) {
- return (Operations.INSTANCE.getOperation(name) != null);
- }
-
- private void calculate(String cmdName) {
- float curValue;
- float newValue = 0;
-
- // get current value of display
- curValue = Float.parseFloat(display.getText());
-
- Operation currentOp = Operations.INSTANCE.getOperation(cmdName);
- if ((currentOp instanceof BinaryOperation) && (cmd == null)) {
- // if last clicked operation was binary and there is no saved
- // operation, store it
- cmd = cmdName;
- clearDisplay = true;
- } else {
- // if saved command is binary perform it
- Operation savedOp = Operations.INSTANCE.getOperation(cmd);
- if (savedOp instanceof BinaryOperation) {
- BinaryOperation bop = (BinaryOperation) savedOp;
- newValue = bop.perform(value, curValue);
- } // if current operation is unary perform it
- else if (currentOp instanceof UnaryOperation) {
- UnaryOperation uop = (UnaryOperation) currentOp;
- newValue = uop.perform(curValue);
- }
-
- // display the result and prepare clear on next button
- display.setText("" + newValue);
- clearDisplay = true;
- if (currentOp instanceof Equals) {
- // do not save "=" command
- cmd = null;
- } else if (currentOp instanceof BinaryOperation) {
- // save binary commands as they are executed on next operation
- cmd = cmdName;
- } else {
- // clear saved command
- cmd = null;
- }
- }
-
- }
-}
diff --git a/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/ui/swing/CalculatorUI.java b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/ui/swing/CalculatorUI.java
new file mode 100644
index 0000000..128a27f
--- /dev/null
+++ b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/ui/swing/CalculatorUI.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Matthias Sohn <matthias.sohn@sap.com>
+ *
+ * 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
+ *******************************************************************************/
+package org.eclipse.example.calc.internal.ui.swing;
+
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.WindowConstants;
+import javax.swing.border.TitledBorder;
+
+import org.eclipse.example.calc.Operations;
+import org.eclipse.example.calc.internal.Calculator;
+import org.eclipse.example.calc.internal.TextProvider;
+
+/*
+ * A simple calculator featuring a Swing UI.
+ */
+public class CalculatorUI extends JFrame implements TextProvider,
+ ActionListener {
+ private static final long serialVersionUID = 1L;
+
+ private Calculator calculator;
+
+ private JTextField display;
+
+ private JPanel buttonsPanel;
+
+ private JPanel numberButtonsPanel;
+
+ private JPanel cmdButtonsPanel;
+
+ private JButton numberButtons[];
+
+ private JButton cmdButtons[];
+
+ public static void main(String args[]) {
+ new CalculatorUI().setVisible(true);
+ }
+
+ public CalculatorUI() {
+ calculator = new Calculator(this);
+ setupGUI();
+ setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+ }
+
+ private void setupGUI() {
+ setTitle(Calculator.NAME);
+ Container c = getContentPane();
+ c.setLayout(new BorderLayout());
+ setLocationByPlatform(true);
+
+ setupDisplay(c);
+ setupButtonsPanel(c);
+ setupNumberButtons();
+ setupCommandButtons();
+
+ pack();
+ }
+
+ private void setupDisplay(Container c) {
+ display = new JTextField("0");
+ display.setHorizontalAlignment(JTextField.TRAILING);
+ c.add(display, BorderLayout.NORTH);
+ // initially clear the display
+ calculator.setClearText(true);
+ }
+
+ private void setupButtonsPanel(Container c) {
+ buttonsPanel = new JPanel();
+ buttonsPanel.setLayout(new GridLayout(2, 1));
+ c.add(buttonsPanel);
+ }
+
+ private void setupNumberButtons() {
+ numberButtonsPanel = new JPanel();
+ numberButtonsPanel.setLayout(new GridLayout(3, 4));
+ buttonsPanel.add(numberButtonsPanel, BorderLayout.CENTER);
+ numberButtons = new JButton[11];
+
+ for (int i = 0; i < numberButtons.length - 1; i++) {
+ addNumberButton(i, Integer.valueOf(i).toString());
+ }
+ addNumberButton(10, ".");
+ }
+
+ private void addNumberButton(int i, String name) {
+ numberButtons[i] = new JButton();
+ numberButtons[i].setText(name);
+ numberButtons[i].addActionListener(this);
+ numberButtonsPanel.add(numberButtons[i]);
+ }
+
+ private void setupCommandButtons() {
+ // command buttons
+ cmdButtonsPanel = new JPanel();
+ cmdButtonsPanel.setLayout(new GridLayout(1, 0));
+ buttonsPanel.add(cmdButtonsPanel, BorderLayout.CENTER);
+ TitledBorder title = BorderFactory.createTitledBorder("Operations");
+ cmdButtonsPanel.setBorder(title);
+ cmdButtons = new JButton[Operations.INSTANCE.size()];
+
+ // make the buttons, set ActionListener and add to panel
+ for (int i = 0; i < cmdButtons.length; i++) {
+ addCommandButton(i);
+ }
+ }
+
+ private void addCommandButton(int i) {
+ cmdButtons[i] = new JButton();
+ cmdButtons[i].setText(Operations.INSTANCE.getOperationName(i));
+ cmdButtons[i].addActionListener(this);
+ cmdButtonsPanel.add(cmdButtons[i]);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ String str = e.getActionCommand();
+ calculator.handleButtonClick(str);
+ }
+
+ @Override
+ public void setDisplayText(String text) {
+ display.setText(text);
+ }
+
+ @Override
+ public String getDisplayText() {
+ return display.getText();
+ }
+
+}
diff --git a/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/ui/swt/CalculatorUI.java b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/ui/swt/CalculatorUI.java
new file mode 100644
index 0000000..2961499
--- /dev/null
+++ b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/ui/swt/CalculatorUI.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
+ *
+ * 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
+ *******************************************************************************/
+package org.eclipse.example.calc.internal.ui.swt;
+
+import org.eclipse.example.calc.Operations;
+import org.eclipse.example.calc.internal.Calculator;
+import org.eclipse.example.calc.internal.TextProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+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.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/*
+ * A simple calculator featuring a SWT
+ * UI.
+ */
+public class CalculatorUI implements TextProvider, SelectionListener {
+
+ private static final long serialVersionUID = 1L;
+
+ private Calculator calculator;
+
+ private Shell shell;
+
+ private Text display;
+
+ private Button[] numberButtons;
+
+ private Button[] cmdButtons;
+
+ public static void main(String[] args) {
+ Display display = new Display();
+ Shell shell = new CalculatorUI().open(display);
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+ }
+
+ private Shell open(Display display) {
+ shell = new Shell(display);
+ setupGUI();
+
+ shell.pack();
+ shell.open();
+ return shell;
+ }
+
+ public CalculatorUI() {
+ calculator = new Calculator(this);
+ }
+
+ private void setupGUI() {
+ shell.setText(Calculator.NAME);
+ GridLayout gridLayout = new GridLayout();
+ gridLayout.numColumns = 1;
+ gridLayout.marginHeight = gridLayout.marginWidth = 0;
+ shell.setLayout(gridLayout);
+
+ setupDisplay();
+ setupNumberButtons();
+ setupCommandButtons();
+
+ }
+
+ private void setupDisplay() {
+ GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+ display = new Text(shell, SWT.BORDER_SOLID | SWT.RIGHT);
+ display.setLayoutData(gridData);
+ display.setText("0");
+ calculator.setClearText(true);
+ }
+
+ private void setupNumberButtons() {
+ Composite numberButtonsPanel = new Composite(shell, SWT.NONE);
+ numberButtonsPanel.setLayout(new GridLayout(4, true));
+ numberButtons = new Button[11];
+
+ for (int i = 0; i < numberButtons.length - 1; i++) {
+ addNumberButton(numberButtonsPanel, i, Integer.valueOf(i)
+ .toString());
+ }
+ addNumberButton(numberButtonsPanel, 10, ".");
+ }
+
+ private void addNumberButton(Composite parent, int i, String name) {
+ numberButtons[i] = new Button(parent, SWT.PUSH);
+ numberButtons[i].setText(name);
+ numberButtons[i].addSelectionListener(this);
+ }
+
+ private void setupCommandButtons() {
+ // command buttons
+ Group cmdButtonsPanel = new Group(shell, SWT.NONE);
+ cmdButtonsPanel.setText("Operations");
+ cmdButtonsPanel.setLayout(new GridLayout(4, true));
+
+ cmdButtons = new Button[Operations.INSTANCE.size()];
+
+ // make the buttons, set ActionListener and add to panel
+ for (int i = 0; i < cmdButtons.length; i++) {
+ addCommandButton(cmdButtonsPanel, i);
+ }
+ }
+
+ private void addCommandButton(Composite parent, int i) {
+ cmdButtons[i] = new Button(parent, SWT.NONE);
+ cmdButtons[i].setText(Operations.INSTANCE.getOperationName(i));
+ cmdButtons[i].addSelectionListener(this);
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent arg0) {
+ // empty
+ }
+
+ @Override
+ public void widgetSelected(SelectionEvent event) {
+ String str = ((Button) event.getSource()).getText();
+ calculator.handleButtonClick(str);
+ }
+
+ @Override
+ public void setDisplayText(String text) {
+ display.setText(text);
+ }
+
+ @Override
+ public String getDisplayText() {
+ return display.getText();
+ }
+
+}
diff --git a/org.eclipse.example.calc/tst/org/eclipse/example/calc/internal/CalculatorTest.java b/org.eclipse.example.calc/tst/org/eclipse/example/calc/internal/CalculatorTest.java
new file mode 100644
index 0000000..3741c1c
--- /dev/null
+++ b/org.eclipse.example.calc/tst/org/eclipse/example/calc/internal/CalculatorTest.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Matthias Sohn <matthias.sohn@sap.com>
+ * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
+ *
+ * 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
+ *******************************************************************************/
+package org.eclipse.example.calc.internal;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.example.calc.Operations;
+import org.junit.After;
+import org.junit.Test;
+
+public class CalculatorTest {
+
+ @After
+ public void tearDown() throws Exception {
+ Operations.INSTANCE.reset();
+ }
+
+ @Test
+ public void testPlus() {
+ TestTextProvider textProvider = new TestTextProvider();
+ Calculator calculator = new Calculator(textProvider);
+
+ calculator.handleButtonClick("1");
+ calculator.handleButtonClick("+");
+ calculator.handleButtonClick("2");
+ calculator.handleButtonClick("=");
+
+ assertEquals("3.0", textProvider.getDisplayText());
+ }
+
+ @Test
+ public void testTwoTimesPlus() {
+ TestTextProvider textProvider = new TestTextProvider();
+ Calculator calculator = new Calculator(textProvider);
+
+ calculator.handleButtonClick("1");
+ calculator.handleButtonClick("+");
+ calculator.handleButtonClick("2");
+ calculator.handleButtonClick("+");
+ calculator.handleButtonClick("3");
+ calculator.handleButtonClick("=");
+
+ assertEquals("6.0", textProvider.getDisplayText());
+ }
+
+ @Test
+ public void testPlusWithFraction() {
+ TestTextProvider textProvider = new TestTextProvider();
+ Calculator calculator = new Calculator(textProvider);
+
+ calculator.handleButtonClick("1");
+ calculator.handleButtonClick("+");
+ calculator.handleButtonClick("2");
+ calculator.handleButtonClick(".");
+ calculator.handleButtonClick("1");
+ calculator.handleButtonClick("=");
+
+ assertEquals("3.1", textProvider.getDisplayText());
+ }
+
+ @Test
+ public void testSquare() {
+ TestTextProvider textProvider = new TestTextProvider();
+ Calculator calculator = new Calculator(textProvider);
+
+ calculator.handleButtonClick("2");
+ calculator.handleButtonClick("x²");
+
+ assertEquals("4.0", textProvider.getDisplayText());
+ }
+
+ private static final class TestTextProvider implements TextProvider {
+
+ private String text = "0";
+
+ @Override
+ public void setDisplayText(String text) {
+ this.text = text;
+
+ }
+
+ @Override
+ public String getDisplayText() {
+ return text;
+ }
+
+ }
+}