|
Menü |
CalculatorInhaltsverzeichnis (hide) Calculator ist ein kleiner Rechner, welcher mathematische Ausdrücke numerisch auswertet. Screenshot![]() Funktionen
Calculator beherrscht außerdem die Kommandos "help" und "clear", um eine Auflistung aller Funktionen anzuzeigen, bzw. die Anzeige zu löschen. QuelltextCalculator.javaimport 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.javaimport 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.javapublic 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.javapublic interface Function { public String getSymbol(); public int getPriority(); public double calculate(double value); } ParseException.javapublic class ParseException extends Exception { public ParseException(String message) { // Constructor. Create a ParseError object containing // the given message as its error message. super(message); } } DownloadKategorie: Informatik | Java | Uni |