Simple calculator example, initial version
A simple calculator example with a Swing user interface.
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
diff --git a/org.eclipse.example.calc/.classpath b/org.eclipse.example.calc/.classpath
new file mode 100644
index 0000000..18d70f0
--- /dev/null
+++ b/org.eclipse.example.calc/.classpath
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.example.calc/.gitignore b/org.eclipse.example.calc/.gitignore
new file mode 100644
index 0000000..934e0e0
--- /dev/null
+++ b/org.eclipse.example.calc/.gitignore
@@ -0,0 +1,2 @@
+/bin
+/target
diff --git a/org.eclipse.example.calc/.project b/org.eclipse.example.calc/.project
new file mode 100644
index 0000000..05f7dc5
--- /dev/null
+++ b/org.eclipse.example.calc/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.example.calc</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.example.calc/.settings/org.eclipse.core.resources.prefs b/org.eclipse.example.calc/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..3f5bf67
--- /dev/null
+++ b/org.eclipse.example.calc/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Fri Feb 25 01:31:16 CET 2011
+eclipse.preferences.version=1
+encoding//src/org/eclipse/example/calc/internal/operations/Square.java=UTF-8
diff --git a/org.eclipse.example.calc/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.example.calc/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..e0d7ca8
--- /dev/null
+++ b/org.eclipse.example.calc/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Thu Feb 24 22:46:12 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/org.eclipse.example.calc/Calculator.launch b/org.eclipse.example.calc/Calculator.launch
new file mode 100644
index 0000000..d3f8131
--- /dev/null
+++ b/org.eclipse.example.calc/Calculator.launch
@@ -0,0 +1,14 @@
+<?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"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="1"/>
+</listAttribute>
+<mapAttribute key="org.eclipse.debug.core.preferred_launchers">
+<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.PROJECT_ATTR" value="org.eclipse.example.calc"/>
+</launchConfiguration>
diff --git a/org.eclipse.example.calc/src/org/eclipse/example/calc/BinaryOperation.java b/org.eclipse.example.calc/src/org/eclipse/example/calc/BinaryOperation.java
new file mode 100644
index 0000000..5e0348e
--- /dev/null
+++ b/org.eclipse.example.calc/src/org/eclipse/example/calc/BinaryOperation.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * 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;
+
+/**
+ * Binary operation interface
+ */
+public interface BinaryOperation extends Operation {
+ /**
+ * @param arg1 first parameter
+ * @param arg2 second parameter
+ * @return result of binary operation
+ */
+ public float perform(float arg1, float arg2);
+}
diff --git a/org.eclipse.example.calc/src/org/eclipse/example/calc/Operation.java b/org.eclipse.example.calc/src/org/eclipse/example/calc/Operation.java
new file mode 100644
index 0000000..68cb046
--- /dev/null
+++ b/org.eclipse.example.calc/src/org/eclipse/example/calc/Operation.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * 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;
+
+public interface Operation {
+ /**
+ * @return name of the operation
+ */
+ public String getName();
+}
diff --git a/org.eclipse.example.calc/src/org/eclipse/example/calc/Operations.java b/org.eclipse.example.calc/src/org/eclipse/example/calc/Operations.java
new file mode 100644
index 0000000..af57361
--- /dev/null
+++ b/org.eclipse.example.calc/src/org/eclipse/example/calc/Operations.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Class to register operations
+ */
+public class Operations {
+ public static final Operations INSTANCE = new Operations();
+
+ private final Map<String, Operation> commands = new HashMap<String, Operation>();
+
+ public void register(Operation op) {
+ assert (commands.get(op.getName()) == null);
+ commands.put(op.getName(), op);
+ }
+
+ public void reset() {
+ commands.clear();
+ }
+
+ public Operation getOperation(String name) {
+ return commands.get(name);
+ }
+
+ public int size() {
+ return commands.size();
+ }
+
+ public String getOperationName(int i) {
+ String keys[] = new String[commands.keySet().size()];
+ (commands.keySet()).toArray(keys);
+ Arrays.sort(keys);
+ return keys[i];
+ }
+}
diff --git a/org.eclipse.example.calc/src/org/eclipse/example/calc/UnaryOperation.java b/org.eclipse.example.calc/src/org/eclipse/example/calc/UnaryOperation.java
new file mode 100644
index 0000000..04db3fe
--- /dev/null
+++ b/org.eclipse.example.calc/src/org/eclipse/example/calc/UnaryOperation.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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;
+
+/**
+ * Unary operation
+ */
+public interface UnaryOperation extends Operation {
+ /**
+ * @param arg1 parameter
+ * @return result of binary operation
+ */
+ public float perform(float arg1);
+}
diff --git a/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/AbstractOperation.java b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/AbstractOperation.java
new file mode 100644
index 0000000..9fa00c3
--- /dev/null
+++ b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/AbstractOperation.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * 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.operations;
+
+import org.eclipse.example.calc.Operation;
+import org.eclipse.example.calc.Operations;
+
+/**
+ * Abstract operation caring for book-keeping
+ */
+public abstract class AbstractOperation implements Operation {
+ AbstractOperation() {
+ Operations.INSTANCE.register(this);
+ }
+}
diff --git a/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/Equals.java b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/Equals.java
new file mode 100644
index 0000000..4907684
--- /dev/null
+++ b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/Equals.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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.operations;
+
+import org.eclipse.example.calc.Operation;
+
+/**
+ * Equals operation to trigger binary operations
+ */
+public class Equals extends AbstractOperation implements Operation {
+
+ @Override
+ public String getName() {
+ return "=";
+ }
+
+}
diff --git a/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/Minus.java b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/Minus.java
new file mode 100644
index 0000000..5eec406
--- /dev/null
+++ b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/Minus.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * 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.operations;
+
+import org.eclipse.example.calc.BinaryOperation;
+
+/**
+ * Binary minus operation
+ */
+public class Minus extends AbstractOperation implements BinaryOperation {
+
+ @Override
+ public float perform(float arg1, float arg2) {
+ return arg1 - arg2;
+ }
+
+ @Override
+ public String getName() {
+ return "-";
+ }
+
+}
diff --git a/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/Plus.java b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/Plus.java
new file mode 100644
index 0000000..3ea65d5
--- /dev/null
+++ b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/Plus.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * 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.operations;
+
+import org.eclipse.example.calc.BinaryOperation;
+
+/**
+ * Binary plus operation
+ */
+public class Plus extends AbstractOperation implements BinaryOperation {
+
+ @Override
+ public float perform(float arg1, float arg2) {
+ return arg1 + arg2;
+ }
+
+ @Override
+ public String getName() {
+ return "+";
+ }
+
+}
diff --git a/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/Square.java b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/Square.java
new file mode 100644
index 0000000..53d45fe
--- /dev/null
+++ b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/operations/Square.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * 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.operations;
+
+import org.eclipse.example.calc.UnaryOperation;
+
+/**
+ * Square operation
+ */
+public class Square extends AbstractOperation implements UnaryOperation {
+
+ @Override
+ public String getName() {
+ return "x²";
+ }
+
+ @Override
+ public float perform(float arg1) {
+ return arg1 * arg1;
+ }
+
+}
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
new file mode 100644
index 0000000..db032da
--- /dev/null
+++ b/org.eclipse.example.calc/src/org/eclipse/example/calc/internal/ui/Calculator.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * 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());
+
+ 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());
+
+ if (cmd == null || cmd.equals("")) {
+ // if no command was saved previously, save this one and clear
+ cmd = cmdName;
+ clearDisplay = true;
+ } else {
+ // perform the saved command
+ Operation op = Operations.INSTANCE.getOperation(cmd);
+ assert (op != null);
+ if (op instanceof BinaryOperation) {
+ BinaryOperation bop = (BinaryOperation) op;
+ newValue = bop.perform(value, curValue);
+ } else if (op instanceof UnaryOperation) {
+ UnaryOperation uop = (UnaryOperation) op;
+ newValue = uop.perform(curValue);
+ }
+
+ // display the result and order to clear
+ display.setText("" + newValue);
+ clearDisplay = true;
+
+ if (cmdName.equals("=")) {
+ // do not save = command
+ cmd = null;
+ } else {
+ // save other commands
+ cmd = cmdName;
+ }
+ }
+
+ }
+}