From dad546c5b51149f62c04fceefcbea349450787d8 Mon Sep 17 00:00:00 2001 From: Riley Jones Date: Thu, 3 Aug 2017 14:04:09 -0700 Subject: [PATCH 1/5] Add stop button --- .../org/nwapw/abacus/fx/AbacusController.java | 72 ++++++++++++++----- .../nwapw/abacus/plugin/StandardPlugin.java | 18 +++-- .../org/nwapw/abacus/tree/BinaryNode.java | 11 ++- .../org/nwapw/abacus/tree/FunctionNode.java | 10 ++- .../java/org/nwapw/abacus/tree/UnaryNode.java | 9 ++- src/main/resources/abacus.fxml | 2 + 6 files changed, 96 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/nwapw/abacus/fx/AbacusController.java b/src/main/java/org/nwapw/abacus/fx/AbacusController.java index aa898d8..8b45f85 100644 --- a/src/main/java/org/nwapw/abacus/fx/AbacusController.java +++ b/src/main/java/org/nwapw/abacus/fx/AbacusController.java @@ -1,5 +1,6 @@ package org.nwapw.abacus.fx; +import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; @@ -25,7 +26,10 @@ public class AbacusController { * Constant string that is displayed if the tree could not be reduced. */ private static final String ERR_EVAL = "Evaluation Error"; - + /** + * Constant string that is displayed if the calculations are stopped before they are done. + */ + private static final String ERR_STOP = "Stopped"; @FXML private TableView historyTable; @FXML @@ -54,6 +58,16 @@ public class AbacusController { */ private ObservableList numberImplementationOptions; + /** + * Thread used for calculating. + */ + private Thread calcThread; + + /** + * Checks whether the calculator is calculating. + */ + private boolean calculating; + private Abacus abacus; @FXML @@ -87,24 +101,48 @@ public class AbacusController { @FXML private void performCalculation(){ - inputButton.setDisable(true); - TreeNode constructedTree = abacus.parseString(inputField.getText()); - if(constructedTree == null){ - outputText.setText(ERR_SYNTAX); - inputButton.setDisable(false); - return; - } - NumberInterface evaluatedNumber = abacus.evaluateTree(constructedTree); - if(evaluatedNumber == null){ - outputText.setText(ERR_EVAL); - inputButton.setDisable(false); - return; - } - outputText.setText(evaluatedNumber.toString()); - historyData.add(new HistoryModel(inputField.getText(), constructedTree.toString(), evaluatedNumber.toString())); + Runnable calculator = new Runnable(){ + public void run() { + calculating = true; + Platform.runLater(() -> inputButton.setDisable(true)); + TreeNode constructedTree = abacus.parseString(inputField.getText()); + if (constructedTree == null) { + Platform.runLater(() ->outputText.setText(ERR_SYNTAX)); + Platform.runLater(() -> inputButton.setDisable(false)); + //return; + }else { + NumberInterface evaluatedNumber = abacus.evaluateTree(constructedTree); + if (evaluatedNumber == null) { + if(Thread.currentThread().isInterrupted()){ + Platform.runLater(() -> outputText.setText(ERR_STOP)); + Platform.runLater(() -> inputButton.setDisable(false)); + }else { + Platform.runLater(() -> outputText.setText(ERR_EVAL)); + Platform.runLater(() -> inputButton.setDisable(false)); + //return; + } + } else { + Platform.runLater(() -> outputText.setText(evaluatedNumber.toString())); + historyData.add(new HistoryModel(inputField.getText(), constructedTree.toString(), evaluatedNumber.toString())); + + Platform.runLater(() -> inputButton.setDisable(false)); + Platform.runLater(() -> inputField.setText("")); + } + } + calculating = false; + } + }; + if(!calculating) { + calcThread = new Thread(calculator); + calcThread.start(); + } + } + @FXML + private void stopCalculation(){ + calcThread.interrupt(); + calculating = false; inputButton.setDisable(false); - inputField.setText(""); } } diff --git a/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java b/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java index d7b14f3..f879a65 100755 --- a/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java +++ b/src/main/java/org/nwapw/abacus/plugin/StandardPlugin.java @@ -116,7 +116,7 @@ public class StandardPlugin extends Plugin { NumberInterface factorial = params[0]; NumberInterface multiplier = params[0]; //It is necessary to later prevent calls of factorial on anything but non-negative integers. - while ((multiplier = multiplier.subtract(NaiveNumber.ONE.promoteTo(multiplier.getClass()))).signum() == 1) { + while (!Thread.currentThread().isInterrupted()&&(multiplier = multiplier.subtract(NaiveNumber.ONE.promoteTo(multiplier.getClass()))).signum() == 1) { factorial = factorial.multiply(multiplier); } return factorial; @@ -170,11 +170,12 @@ public class StandardPlugin extends Plugin { int n = 0; if(params[0].signum() <= 0){ NumberInterface currentTerm = NaiveNumber.ONE.promoteTo(params[0].getClass()), sum = currentTerm; - while(FUNCTION_ABS.apply(currentTerm).compareTo(maxError) > 0){ + while(!Thread.currentThread().isInterrupted()&&FUNCTION_ABS.apply(currentTerm).compareTo(maxError) > 0){ n++; currentTerm = currentTerm.multiply(params[0]).divide((new NaiveNumber(n)).promoteTo(params[0].getClass())); sum = sum.add(currentTerm); } + //System.out.println(Thread.currentThread().isInterrupted()); return sum; } else{ @@ -192,8 +193,11 @@ public class StandardPlugin extends Plugin { right = right.multiply(nextN); //System.out.println(left + ", " + right); } - while(left.compareTo(right) > 0); + while(!Thread.currentThread().isInterrupted()&&left.compareTo(right) > 0); //System.out.println(n+1); + //System.out.println(Thread.currentThread().isInterrupted()); + if(Thread.currentThread().isInterrupted()) + return left; return sum; } } @@ -211,7 +215,7 @@ public class StandardPlugin extends Plugin { protected NumberInterface applyInternal(NumberInterface[] params) { NumberInterface param = params[0]; int powersOf2 = 0; - while (FUNCTION_ABS.apply(param.subtract(NaiveNumber.ONE.promoteTo(param.getClass()))).compareTo((new NaiveNumber(0.1)).promoteTo(param.getClass())) >= 0) { + while (!Thread.currentThread().isInterrupted()&&FUNCTION_ABS.apply(param.subtract(NaiveNumber.ONE.promoteTo(param.getClass()))).compareTo((new NaiveNumber(0.1)).promoteTo(param.getClass())) >= 0) { if (param.subtract(NaiveNumber.ONE.promoteTo(param.getClass())).signum() == 1) { param = param.divide(new NaiveNumber(2).promoteTo(param.getClass())); powersOf2++; @@ -265,7 +269,7 @@ public class StandardPlugin extends Plugin { NumberInterface a = (new NaiveNumber(1)).promoteTo(number.getClass()), b = a, c = a; NumberInterface sum = NaiveNumber.ZERO.promoteTo(number.getClass()); int n = 0; - while (a.compareTo(maxError) >= 1) { + while (!Thread.currentThread().isInterrupted()&&a.compareTo(maxError) >= 1) { n++; a = a.divide((new NaiveNumber(3)).promoteTo(number.getClass())); b = b.divide((new NaiveNumber(4)).promoteTo(number.getClass())); @@ -352,10 +356,12 @@ public class StandardPlugin extends Plugin { } ArrayList list = factorialLists.get(numberClass); if(n >= list.size()){ - while(list.size() < n + 16){ + while(!Thread.currentThread().isInterrupted()&&list.size() < n + 16){ list.add(list.get(list.size()-1).multiply(new NaiveNumber(list.size()).promoteTo(numberClass))); } } + if(Thread.currentThread().isInterrupted()) + return null; return list.get(n); } diff --git a/src/main/java/org/nwapw/abacus/tree/BinaryNode.java b/src/main/java/org/nwapw/abacus/tree/BinaryNode.java index 6ec7b80..7d95404 100644 --- a/src/main/java/org/nwapw/abacus/tree/BinaryNode.java +++ b/src/main/java/org/nwapw/abacus/tree/BinaryNode.java @@ -92,10 +92,19 @@ public class BinaryNode extends TreeNode { @Override public T reduce(Reducer reducer) { + if(Thread.currentThread().isInterrupted()) + return null; T leftReduce = left.reduce(reducer); + if(Thread.currentThread().isInterrupted()) + return null; T rightReduce = right.reduce(reducer); if (leftReduce == null || rightReduce == null) return null; - return reducer.reduceNode(this, leftReduce, rightReduce); + if(Thread.currentThread().isInterrupted()) + return null; + T a = reducer.reduceNode(this, leftReduce, rightReduce); + if(Thread.currentThread().isInterrupted()) + return null; + return a; } @Override diff --git a/src/main/java/org/nwapw/abacus/tree/FunctionNode.java b/src/main/java/org/nwapw/abacus/tree/FunctionNode.java index a0ee26e..af0662d 100644 --- a/src/main/java/org/nwapw/abacus/tree/FunctionNode.java +++ b/src/main/java/org/nwapw/abacus/tree/FunctionNode.java @@ -62,12 +62,20 @@ public class FunctionNode extends TreeNode { @Override public T reduce(Reducer reducer) { + if(Thread.currentThread().isInterrupted()) + return null; Object[] reducedChildren = new Object[children.size()]; for (int i = 0; i < reducedChildren.length; i++) { reducedChildren[i] = children.get(i).reduce(reducer); if (reducedChildren[i] == null) return null; } - return reducer.reduceNode(this, reducedChildren); + //System.out.println(Thread.currentThread().isInterrupted()); + if(Thread.currentThread().isInterrupted()) + return null; + T a = reducer.reduceNode(this, reducedChildren); + if(Thread.currentThread().isInterrupted()) + return null; + return a; } @Override diff --git a/src/main/java/org/nwapw/abacus/tree/UnaryNode.java b/src/main/java/org/nwapw/abacus/tree/UnaryNode.java index 298d25d..ce1ff90 100644 --- a/src/main/java/org/nwapw/abacus/tree/UnaryNode.java +++ b/src/main/java/org/nwapw/abacus/tree/UnaryNode.java @@ -33,9 +33,16 @@ public class UnaryNode extends TreeNode { @Override public T reduce(Reducer reducer) { + if(Thread.currentThread().isInterrupted()) + return null; Object reducedChild = applyTo.reduce(reducer); if (reducedChild == null) return null; - return reducer.reduceNode(this, reducedChild); + if(Thread.currentThread().isInterrupted()) + return null; + T a = reducer.reduceNode(this, reducedChild); + if(Thread.currentThread().isInterrupted()) + return null; + return a; } /** diff --git a/src/main/resources/abacus.fxml b/src/main/resources/abacus.fxml index 183e247..2001583 100644 --- a/src/main/resources/abacus.fxml +++ b/src/main/resources/abacus.fxml @@ -37,6 +37,8 @@