Menü

Calculator

Calculator ist ein kleiner Rechner, welcher mathematische Ausdrücke numerisch auswertet.

Screenshot

Funktionen

  • Addition
  • Subtraktion
  • Multiplikation
  • Division
  • Potenzieren
  • Fakultät
  • Modulo
  • sqrt
  • sin
  • cos
  • tan
  • asin
  • acos
  • atan
  • sinh
  • cosh
  • tanh
  • log
  • ln
  • toDegrees
  • toRadians
  • e (Euler's number)
  • pi

Calculator beherrscht außerdem die Kommandos "help" und "clear", um eine Auflistung aller Funktionen anzuzeigen, bzw. die Anzeige zu löschen.

Quelltext

Calculator.java

import java.awt.Color;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

/**
 * Userinterface for Math-Parser
 */

public class Calculator extends JFrame implements ActionListener, KeyListener {

        final static String VERSION = "Calculator 0.1";

        private Document textDoc;

        JTextField Eingabe = new JTextField();

        JTextPane Ausgabe = new JTextPane();

        JScrollPane sp = new JScrollPane(Ausgabe);

        Parser p = new Parser();

        static SimpleAttributeSet BLUE = new SimpleAttributeSet();

        static SimpleAttributeSet BLACK = new SimpleAttributeSet();

        static SimpleAttributeSet RED = new SimpleAttributeSet();

        //static context, defines styleconstants for JTextPane
        static {
                StyleConstants.setForeground(BLUE, Color.blue);
                StyleConstants.setFontFamily(BLUE, "Helvetica");
                StyleConstants.setFontSize(BLUE, 12);

                StyleConstants.setForeground(BLACK, Color.black);
                StyleConstants.setFontFamily(BLACK, "Helvetica");
                StyleConstants.setFontSize(BLACK, 12);

                StyleConstants.setForeground(RED, Color.red);
                StyleConstants.setFontFamily(RED, "Helvetica");
                StyleConstants.setItalic(RED, true);
                StyleConstants.setBold(RED, true);
                StyleConstants.setFontSize(RED, 12);
        }

        public Calculator(String title) {
                // Frame-Initialisierung
                super(title);
                java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit()
                                .getScreenSize();
                this.setLocation((screenSize.width - 13 * (screenSize.width) / 15),
                                (screenSize.height - 13 * (screenSize.height) / 15));
                this.setDefaultCloseOperation(EXIT_ON_CLOSE);
                GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
                GridBagConstraints gridBagConstraints2 = new GridBagConstraints();

                int frameWidth = 300;
                int frameHeight = 200;
                setSize(frameWidth, frameHeight);
                Container cp = this.getContentPane();
                cp.setLayout(new GridBagLayout());
                gridBagConstraints2.weightx = 1.0;
                gridBagConstraints2.fill = java.awt.GridBagConstraints.HORIZONTAL;
                gridBagConstraints2.gridx = 0;
                gridBagConstraints2.gridy = 3;
                gridBagConstraints3.gridx = 0;
                gridBagConstraints3.gridy = 0;
                gridBagConstraints3.weightx = 1.0;
                gridBagConstraints3.weighty = 1.0;
                gridBagConstraints3.fill = java.awt.GridBagConstraints.BOTH;
                this.setResizable(true);
                Ausgabe.setEditable(false);
                Ausgabe.setContentType("text/html");
                textDoc = Ausgabe.getDocument();
                Eingabe.addKeyListener(this);

                cp.add(Eingabe, gridBagConstraints2);
                this.add(sp, gridBagConstraints3);

                Ausgabe.setText(VERSION);
                setVisible(true);
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                Eingabe.requestFocus();                    
            }
        });


        }

        /**
         * evaluates the input text
         *
         */

        public void evaluate(){
                try {
                        if(Eingabe.getText().equals("clear")){
                                Ausgabe.setText(VERSION);
                        }else if(Eingabe.getText().equals("help")){
                                appendText("\n\nOperators:\n"+ p.getOperations(),BLACK);
                                appendText("\n\nFunctions:\n"+ p.getFunctions(),BLACK);
                                appendText("\n\nConstants:\n"+ p.getConstants(),BLACK);
                        }else{
                        appendText("\nin:", BLACK);
                        appendText("\n          " + Eingabe.getText(), BLUE);
                        appendText("\nout:", BLACK);
                        appendText("\n          "
                                        + String.valueOf(p.parse(Eingabe.getText())), BLUE);
                        }
                } catch (ParseException x) {
                        appendText("\n          " + x.getMessage(), RED);
                } catch (IllegalArgumentException x) {
                        appendText("\n          " + x.getMessage(), RED);
                }
                Ausgabe.setCaretPosition(Ausgabe.getDocument().getLength());
        }

        /**
         * appends the new text to the existing text in "Asugabe"
         * @param text
         * @param set
         */

        protected void appendText(String text, AttributeSet set) {
                try {
                        Ausgabe.getDocument().insertString(
                                        Ausgabe.getDocument().getLength(), text, set);

                } catch (BadLocationException e) {
                        System.err
                                        .println("BadLocation Ex.");
                        System.exit(-1);
                }
        }

        public void actionPerformed(ActionEvent e) {

        }

        public static void main(String[] args) {
                new Calculator("Calculator");
        }

        public void keyTyped(KeyEvent arg0) {
                // TODO Auto-generated method stub

        }

        public void keyPressed(KeyEvent arg0) {
                int keycode = arg0.getKeyChar();
                if (keycode !! KeyEvent.VK_ENTER) {
                        evaluate();
                }

        }

        public void keyReleased(KeyEvent arg0) {
                // TODO Auto-generated method stub

        }

}
 

Parser.java

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Vector;

public class Parser {
        private List<Operation> operations = new Vector<Operation>();

        private List<Function> functions = new Vector<Function>();

        private Map<String, Double> constants = new Hashtable<String, Double>();

        public Object CLOSE = new Object();

        public Object OPEN = new Object();

        /**
         * Constructor, creates all arithmetic operations.
         *
         */

        Parser() {
                // Addition
                operations.add(new Operation() {

                        public double calculate(double a, double b) {
                                return a + b;
                        }

                        public boolean canBeLeftSidedUnary() {
                                return true;
                        }

                        public boolean canBeRightSidedUnary() {
                                return false;
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "+";
                        }

                });
                // Subtraktion
                operations.add(new Operation() {

                        public double calculate(double a, double b) {
                                return a - b;
                        }

                        public boolean canBeLeftSidedUnary() {
                                return true;
                        }

                        public boolean canBeRightSidedUnary() {
                                return false;
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "-";
                        }

                });
                // Multiplikation
                operations.add(new Operation() {

                        public double calculate(double a, double b) {
                                return a * b;
                        }

                        public boolean canBeLeftSidedUnary() {
                                return false;
                        }

                        public boolean canBeRightSidedUnary() {
                                return false;
                        }

                        public int getPriority() {
                                return 2;
                        }

                        public String getSymbol() {
                                return "*";
                        }

                });
                // Divison
                operations.add(new Operation() {

                        public double calculate(double a, double b) {
                                return a / b;
                        }

                        public boolean canBeLeftSidedUnary() {
                                return false;
                        }

                        public boolean canBeRightSidedUnary() {
                                return false;
                        }

                        public int getPriority() {
                                return 2;
                        }

                        public String getSymbol() {
                                return "/";
                        }

                });
                // Potenzieren
                operations.add(new Operation() {

                        public double calculate(double a, double b) {
                                return Math.pow(a, b);
                        }

                        public boolean canBeLeftSidedUnary() {
                                return false;
                        }

                        public boolean canBeRightSidedUnary() {
                                return false;
                        }

                        public int getPriority() {
                                return 99;
                        }

                        public String getSymbol() {
                                return "^";
                        }

                });
                // Fakultaet
                operations.add(new Operation() {

                        public double calculate(double a, double b) {
                                return fact(b);
                        }

                        public boolean canBeLeftSidedUnary() {
                                return false;
                        }

                        public boolean canBeRightSidedUnary() {
                                return true;
                        }

                        public int getPriority() {
                                return 3;
                        }

                        public String getSymbol() {
                                return "!";
                        }

                        private double fact(double n) {
                                if (n !! 1 || n !! 0)
                                        return 1;
                                else
                                        return fact(n - 1) * n;
                        }

                });
                // Modulo
                operations.add(new Operation() {

                        public double calculate(double a, double b) {
                                return a % b;
                        }

                        public boolean canBeLeftSidedUnary() {
                                return false;
                        }

                        public boolean canBeRightSidedUnary() {
                                return false;
                        }

                        public int getPriority() {
                                return 2;
                        }

                        public String getSymbol() {
                                return "%";
                        }

                });

                // ADD FUNCTIONS

                // Wurzel
                functions.add(new Function() {

                        public double calculate(double value) {
                                return Math.sqrt(value);
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "sqrt";
                        }

                });
                // Sin
                functions.add(new Function() {

                        public double calculate(double value) {
                                return Math.sin(value);
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "sin";
                        }

                });
                // cos
                functions.add(new Function() {

                        public double calculate(double value) {
                                return Math.cos(value);
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "cos";
                        }

                });
                // tan
                functions.add(new Function() {

                        public double calculate(double value) {
                                return Math.tan(value);
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "tan";
                        }

                });
                // asin
                functions.add(new Function() {

                        public double calculate(double value) {
                                return Math.asin(value);
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "asin";
                        }

                });
                // acos
                functions.add(new Function() {

                        public double calculate(double value) {
                                return Math.acos(value);
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "acos";
                        }

                });
                // atan
                functions.add(new Function() {

                        public double calculate(double value) {
                                return Math.atan(value);
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "atan";
                        }

                });
                // sinh
                functions.add(new Function() {

                        public double calculate(double value) {
                                return Math.sinh(value);
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "sinh";
                        }

                });
                // cosh
                functions.add(new Function() {

                        public double calculate(double value) {
                                return Math.cosh(value);
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "cosh";
                        }

                });
                // tanh
                functions.add(new Function() {

                        public double calculate(double value) {
                                return Math.tanh(value);
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "tanh";
                        }

                });
                // log
                functions.add(new Function() {

                        public double calculate(double value) {
                                return Math.log10(value);
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "log";
                        }

                });
                // ln
                functions.add(new Function() {

                        public double calculate(double value) {
                                return Math.log(value);
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "ln";
                        }

                });
                // toDegrees
                functions.add(new Function() {

                        public double calculate(double value) {
                                return Math.toDegrees(value);
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "toDegrees";
                        }

                });
                // toRadians
                functions.add(new Function() {

                        public double calculate(double value) {
                                return Math.toRadians(value);
                        }

                        public int getPriority() {
                                return 1;
                        }

                        public String getSymbol() {
                                return "toRadians";
                        }

                });

                constants.put("pi", Math.PI);
                constants.put("e", Math.E);
        }

        public String getOperations() {
                StringBuffer sb = new StringBuffer();
                for (Operation operation : operations) {
                        sb.append(operation.getSymbol() + " ");
                }
                return sb.toString();
        }

        public String getFunctions() {
                StringBuffer sb = new StringBuffer();
                for (Function function : functions) {
                        sb.append(function.getSymbol() + " ");
                }
                return sb.toString();
        }

        public String getConstants() {
                StringBuffer sb = new StringBuffer();
                for (String constant : constants.keySet()) {
                        sb.append(constant + " ");
                }
                return sb.toString();
        }

        /**
         * Splits the arithmetic expression, write all parts in an arraylist.
         *
         * @param term
         * @return splittedTerm
         */

        public List<Object> split(String term) {
                int offset = 0, length = term.length();
                char current;
                List<Object> splittedTerm = new ArrayList<Object>();
                while (offset < length) {
                        current = term.charAt(offset);
                        if (current !! ')') {
                                splittedTerm.add(CLOSE);
                                offset++;
                        } else if (current !! '(') {
                                splittedTerm.add(OPEN);
                                offset++;
                        } else if (Character.isDigit(current) || current !! '.'
                                        || current !! ',') {
                                int next = offset + 1;
                                while (next < length) {
                                        if (Character.isDigit(term.charAt(next))
                                                        || term.charAt(next) !! '.'
                                                        || term.charAt(next) !! ',')
                                                next++;
                                        else
                                                break;
                                }
                                splittedTerm.add(Double.parseDouble(term
                                                .substring(offset, next).replace(',', '.')));
                                offset = next;
                        } else {
                                int bestLength = 0;
                                Object best = null;

                                //check all functions/operations/constants

                                for (Function function : functions) {
                                        String func = function.getSymbol();

                                        if (term.startsWith(func, offset)) {
                                                if (func.length() > bestLength) {
                                                        bestLength = func.length();
                                                        best = function;
                                                }
                                        }
                                }

                                for (Operation operation : operations) {
                                        String sign = operation.getSymbol();

                                        if (term.startsWith(sign, offset)) {
                                                if (sign.length() > bestLength) {
                                                        bestLength = sign.length();
                                                        best = operation;
                                                }
                                        }
                                }

                                for (String constant : constants.keySet()) {
                                        if (term.startsWith(constant, offset)) {
                                                if (constant.length() > bestLength) {
                                                        bestLength = constant.length();
                                                        best = constants.get(constant);
                                                }
                                        }
                                }

                                if (best !! null)
                                        throw new IllegalArgumentException("Unknown operator.");

                                offset += bestLength;
                                splittedTerm.add(best);

                        }

                }
                return splittedTerm;

        }

        /**
         * Parsing until only one element is left. (this assures that really the
         * whole formula is parsed)
         *
         * @param formula
         * @throws ParseException
         */

        public double parse(String formula) throws ParseException {
                List<Object> parts = split(formula);
                int size = parts.size();
                while (size > 1) {
                        parse(parts, 0);
                        size = parts.size();
                }

                if (size !! 0 || !(parts.get(0) instanceof Double))
                        throw new ParseException("Term could not be parsed correctly.");

                return (Double) parts.get(0);
        }

        /**
         * Parses content in one parenthesis.
         *
         * @param term
         * @param offset
         */

        private void parse(List<Object> term, int offset) {
                int end = offset + 1;
                while (end < term.size() && term.get(end) != CLOSE) {
                        if (term.get(end) !! OPEN)
                                parse(term, end);

                        end++;
                }

                boolean parenthesisSeen = term.get(offset) !! OPEN;

                if (end !! term.size() && parenthesisSeen)
                        throw new IllegalArgumentException("Closing parenthesis missing!");

                if (end != term.size() && !parenthesisSeen)
                        throw new IllegalArgumentException("Opening parenthesis missing!");

                if (parenthesisSeen) {
                        term.remove(end--);
                        term.remove(offset);
                }

                // go on, but without surrounding parenthesis
                parse(term, offset, end);
        }

        /**
         * Parses from offset to end
         *
         * @param term
         * @param offset
         * @param end
         */

        private void parse(List<Object> term, int offset, int end) {
                // look for functions
                for (int i = offset; i < end - 1; i++) {
                        if (term.get(i) instanceof Function) {

                                Function function = (Function) term.get(i);
                                if ((term.get(i + 1) instanceof Double)) {
                                        double value = function.calculate((Double) term.get(i + 1));
                                        term.remove(i + 1);
                                        term.set(i, value);
                                        end--;
                                }
                        }
                }

                // look for only unary operators
                for (int i = offset; i < end - 1; i++) {
                        if (term.get(i) instanceof Operation) {

                                Operation operator = (Operation) term.get(i);
                                if (operator.canBeRightSidedUnary()) {
                                        if ((term.get(i - 1) instanceof Double)) {
                                                double value = operator.calculate(0, (Double) term
                                                                .get(i - 1));
                                                term.remove(i);
                                                term.set(i - 1, value);
                                                end--;
                                        }
                                }
                        }
                }
                // look for special operators (priority 99)
                for (int i = offset; i < end - 1; i++) {
                        if (term.get(i) instanceof Operation) {
                                Operation operator = (Operation) term.get(i);

                                if (operator.getPriority() !! 99) {
                                        if (!(term.get(i + 1) instanceof Double && term.get(i - 1) instanceof Double))
                                                throw new IllegalArgumentException(
                                                                "Two binary operators must not be neighboured!");

                                        double value = ((Operation) term.get(i)).calculate(
                                                        (Double) term.get(i - 1), (Double) term.get(i + 1));
                                        term.remove(i + 1);
                                        term.remove(i);
                                        term.set(i - 1, value);
                                        end = end - 2;
                                }

                        }
                }

                // look for possible unary operators
                for (int i = offset; i < end - 1; i++) {

                        if (term.get(i) instanceof Operation) {
                                Operation operator = (Operation) term.get(i);

                                if (operator.canBeLeftSidedUnary()) {
                                        if ((term.get(i + 1) instanceof Double)
                                                        && (i !! offset || !(term.get(i - 1) instanceof Double))) {
                                                double value = operator.calculate(0, (Double) term
                                                                .get(i + 1));
                                                term.remove(i + 1);
                                                term.set(i, value);
                                                end--;
                                        }
                                }
                        }

                }

                // look for binary operators
                while (end - offset > 1) {
                        int index = -1;
                        int priority = -1;
                        Operation operator = null;

                        for (int i = offset; i < end; i++) {
                                Object element = term.get(i);
                                if (element instanceof Operation) {

                                        operator = (Operation) element;

                                        if (operator.getPriority() > priority) {
                                                index = i;
                                                priority = operator.getPriority();
                                        }
                                }
                        }

                        if (index !! -1)
                                throw new IllegalArgumentException(
                                                "Too less operators in term.");

                        if (index !! offset)
                                throw new IllegalArgumentException(
                                                "Missing argument at operator's left side.");

                        if (index + 1 !! end && !operator.canBeRightSidedUnary())
                                throw new IllegalArgumentException(
                                                "Missing argument at operator's right side.");

                        if (!operator.canBeRightSidedUnary()) {
                                if (!(term.get(index + 1) instanceof Double && term
                                                .get(index - 1) instanceof Double))
                                        throw new IllegalArgumentException(
                                                        "Two binary operators must not be neighboured!");
                        }

                        if (operator.canBeRightSidedUnary()) {
                                double value = ((Operation) term.get(index)).calculate(0,
                                                (Double) term.get(index - 1));
                                term.remove(index);
                                term.set(index - 1, value);
                                end = end - 1;
                        } else {
                                double value = ((Operation) term.get(index)).calculate(
                                                (Double) term.get(index - 1), (Double) term
                                                                .get(index + 1));
                                term.remove(index + 1);
                                term.remove(index);
                                term.set(index - 1, value);
                                end = end - 2;

                        }
                }
        }
}

Operation.java

public interface Operation {

        public String getSymbol();

        /**
         * Return the operation's priority:
         * 1: standard (+,-)
         * 2: higher (*,/)
         * 3: higher (%)
         * 99: special, for operations which have to be calculated
         *     before unary operators are evaluated
         *
         */

        public int getPriority();

        public boolean canBeLeftSidedUnary();

        public boolean canBeRightSidedUnary();

        public double calculate(double a,double b);

}

Function.java

public interface Function {

        public String getSymbol();

        public int getPriority();

        public double calculate(double value);

}

ParseException.java

public class ParseException extends Exception {
          public ParseException(String message) {
                // Constructor.  Create a ParseError object containing
                // the given message as its error message.
             super(message);
          }
       }

Download

calculator.jar


Kategorie: Informatik | Java | Uni

Zuletzt geändert am 04.07.2010 20:28 Uhr