1
0
mirror of https://github.com/DanilaFe/abacus synced 2024-06-27 21:26:24 -07:00
Abacus/src/main/java/org/nwapw/abacus/fx/AbacusController.java

168 lines
6.2 KiB
Java
Raw Normal View History

package org.nwapw.abacus.fx;
2017-08-03 14:04:09 -07:00
import javafx.application.Platform;
2017-07-31 17:49:57 -07:00
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.text.Text;
import javafx.util.Callback;
import org.nwapw.abacus.Abacus;
import org.nwapw.abacus.number.NumberInterface;
import org.nwapw.abacus.tree.TreeNode;
2017-08-01 10:47:31 -07:00
/**
* The controller for the abacus FX UI, responsible
* for all the user interaction.
*/
public class AbacusController {
2017-08-01 10:47:31 -07:00
/**
* Constant string that is displayed if the text could not be lexed or parsed.
*/
private static final String ERR_SYNTAX = "Syntax Error";
2017-08-01 10:47:31 -07:00
/**
* Constant string that is displayed if the tree could not be reduced.
*/
private static final String ERR_EVAL = "Evaluation Error";
2017-08-03 14:04:09 -07:00
/**
* Constant string that is displayed if the calculations are stopped before they are done.
*/
private static final String ERR_STOP = "Stopped";
2017-07-31 22:29:44 -07:00
@FXML
private TableView<HistoryModel> historyTable;
@FXML
private TableColumn<HistoryModel, String> inputColumn;
@FXML
private TableColumn<HistoryModel, String> parsedColumn;
@FXML
private TableColumn<HistoryModel, String> outputColumn;
@FXML
private Text outputText;
@FXML
private TextField inputField;
@FXML
private Button inputButton;
@FXML
private ComboBox<String> numberImplementationBox;
2017-08-01 10:47:31 -07:00
/**
* The list of history entries, created by the users.
*/
2017-07-31 17:49:57 -07:00
private ObservableList<HistoryModel> historyData;
2017-08-01 10:47:31 -07:00
/**
* The abacus instance used for calculations and all
* other main processing code.
*/
private ObservableList<String> numberImplementationOptions;
2017-08-03 14:04:09 -07:00
/**
* Thread used for calculating.
*/
private Thread calcThread;
/**
* Checks whether the calculator is calculating.
*/
private boolean calculating;
2017-08-03 15:16:26 -07:00
/**
* Seconds delayed for timer;
*/
private double delay = 0;
private Abacus abacus;
@FXML
public void initialize(){
Callback<TableColumn<HistoryModel, String>, TableCell<HistoryModel, String>> cellFactory =
param -> new CopyableCell<>();
2017-07-31 17:49:57 -07:00
historyData = FXCollections.observableArrayList();
2017-07-31 22:29:44 -07:00
historyTable.setItems(historyData);
numberImplementationOptions = FXCollections.observableArrayList();
numberImplementationBox.setItems(numberImplementationOptions);
numberImplementationBox.valueProperty().addListener((observable, oldValue, newValue)
-> {
abacus.getConfiguration().setNumberImplementation(newValue);
abacus.getConfiguration().saveTo(Abacus.CONFIG_FILE);
});
historyTable.getSelectionModel().setCellSelectionEnabled(true);
inputColumn.setCellFactory(cellFactory);
2017-07-31 22:29:44 -07:00
inputColumn.setCellValueFactory(cell -> cell.getValue().inputProperty());
parsedColumn.setCellFactory(cellFactory);
2017-07-31 22:29:44 -07:00
parsedColumn.setCellValueFactory(cell -> cell.getValue().parsedProperty());
outputColumn.setCellFactory(cellFactory);
2017-07-31 22:29:44 -07:00
outputColumn.setCellValueFactory(cell -> cell.getValue().outputProperty());
abacus = new Abacus();
numberImplementationOptions.addAll(abacus.getPluginManager().getAllNumbers());
String actualImplementation = abacus.getConfiguration().getNumberImplementation();
String toSelect = (numberImplementationOptions.contains(actualImplementation)) ? actualImplementation : "naive";
numberImplementationBox.getSelectionModel().select(toSelect);
}
@FXML
private void performCalculation(){
2017-08-03 14:04:09 -07:00
Runnable calculator = new Runnable(){
public void run() {
2017-08-03 15:16:26 -07:00
if(delay>0) {
Runnable timer = new Runnable() {
public void run() {
long gap = (long) (delay * 1000);
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime <= gap) {
}
stopCalculation();
}
};
Thread maxTime = new Thread(timer);
maxTime.setName("maxTime");
maxTime.start();
}
2017-08-03 14:04:09 -07:00
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()));
2017-07-31 22:29:44 -07:00
2017-08-03 14:04:09 -07:00
Platform.runLater(() -> inputButton.setDisable(false));
Platform.runLater(() -> inputField.setText(""));
}
}
calculating = false;
}
};
if(!calculating) {
calcThread = new Thread(calculator);
2017-08-03 15:16:26 -07:00
calcThread.setName("calcThread");
2017-08-03 14:04:09 -07:00
calcThread.start();
}
}
@FXML
private void stopCalculation(){
calcThread.interrupt();
calculating = false;
2017-08-03 15:16:26 -07:00
Platform.runLater(() ->inputButton.setDisable(false));
}
}