| 
									
										
										
										
											2017-07-31 16:48:04 -07:00
										 |  |  | package org.nwapw.abacus.fx;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-03 14:04:09 -07:00
										 |  |  | import javafx.application.Platform;
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:30:37 -07:00
										 |  |  | import javafx.beans.value.ChangeListener;
 | 
					
						
							|  |  |  | import javafx.beans.value.ObservableValue;
 | 
					
						
							| 
									
										
										
										
											2017-07-31 17:49:57 -07:00
										 |  |  | import javafx.collections.FXCollections;
 | 
					
						
							|  |  |  | import javafx.collections.ObservableList;
 | 
					
						
							| 
									
										
										
										
											2017-07-31 16:52:34 -07:00
										 |  |  | import javafx.fxml.FXML;
 | 
					
						
							| 
									
										
										
										
											2017-07-31 22:53:42 -07:00
										 |  |  | import javafx.scene.control.*;
 | 
					
						
							| 
									
										
										
										
											2017-08-02 18:48:42 -07:00
										 |  |  | import javafx.scene.control.cell.CheckBoxListCell;
 | 
					
						
							| 
									
										
										
										
											2017-07-31 17:17:56 -07:00
										 |  |  | import javafx.scene.text.Text;
 | 
					
						
							| 
									
										
										
										
											2017-07-31 22:53:42 -07:00
										 |  |  | import javafx.util.Callback;
 | 
					
						
							| 
									
										
										
										
											2017-08-02 18:48:42 -07:00
										 |  |  | import javafx.util.StringConverter;
 | 
					
						
							| 
									
										
										
										
											2017-07-31 16:52:34 -07:00
										 |  |  | import org.nwapw.abacus.Abacus;
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:01:01 -07:00
										 |  |  | import org.nwapw.abacus.config.Configuration;
 | 
					
						
							| 
									
										
										
										
											2017-08-05 14:34:31 -07:00
										 |  |  | import org.nwapw.abacus.number.ComputationInterruptedException;
 | 
					
						
							| 
									
										
										
										
											2017-07-31 17:17:56 -07:00
										 |  |  | import org.nwapw.abacus.number.NumberInterface;
 | 
					
						
							| 
									
										
										
										
											2017-08-05 16:21:02 -07:00
										 |  |  | import org.nwapw.abacus.plugin.ClassFinder;
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:18:33 -07:00
										 |  |  | import org.nwapw.abacus.plugin.PluginListener;
 | 
					
						
							|  |  |  | import org.nwapw.abacus.plugin.PluginManager;
 | 
					
						
							| 
									
										
										
										
											2017-08-05 16:21:02 -07:00
										 |  |  | import org.nwapw.abacus.plugin.StandardPlugin;
 | 
					
						
							| 
									
										
										
										
											2017-07-31 17:17:56 -07:00
										 |  |  | import org.nwapw.abacus.tree.TreeNode;
 | 
					
						
							| 
									
										
										
										
											2017-07-31 16:52:34 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-05 17:04:07 -07:00
										 |  |  | import java.io.File;
 | 
					
						
							| 
									
										
										
										
											2017-08-05 16:21:02 -07:00
										 |  |  | import java.io.IOException;
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:01:01 -07:00
										 |  |  | import java.util.Set;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-31 22:53:42 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 10:47:31 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * The controller for the abacus FX UI, responsible
 | 
					
						
							|  |  |  |  * for all the user interaction.
 | 
					
						
							|  |  |  |  */
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:18:33 -07:00
										 |  |  | public class AbacusController implements PluginListener {
 | 
					
						
							| 
									
										
										
										
											2017-07-31 16:48:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-05 17:04:07 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * The file used for saving and loading configuration.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							|  |  |  |     public static final File CONFIG_FILE = new File("config.toml");
 | 
					
						
							| 
									
										
										
										
											2017-08-03 13:55:39 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * The title for the apply alert dialog.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							|  |  |  |     private static final String APPLY_MSG_TITLE = "\"Apply\" Needed";
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * The text for the header of the apply alert dialog.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							|  |  |  |     private static final String APPLY_MSG_HEADER = "The settings have not been applied.";
 | 
					
						
							|  |  |  |     /**
 | 
					
						
							|  |  |  |      * The text for the dialog that is shown if settings haven't been applied.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							|  |  |  |     private static final String APPLY_MSG_TEXT = "You have made changes to the configuration, however, you haven't pressed \"Apply\". " +
 | 
					
						
							| 
									
										
										
										
											2017-08-04 13:20:57 -07:00
										 |  |  |             "The changes to the configuration will not be present in the calculator until \"Apply\" is pressed.";
 | 
					
						
							| 
									
										
										
										
											2017-08-01 10:47:31 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Constant string that is displayed if the text could not be lexed or parsed.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							| 
									
										
										
										
											2017-07-31 17:17:56 -07:00
										 |  |  |     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.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							| 
									
										
										
										
											2017-07-31 17:17:56 -07:00
										 |  |  |     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-08-05 15:58:43 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Constant string that is displayed if the calculations are interrupted by an exception.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							|  |  |  |     private static final String ERR_EXCEPTION = "Exception Thrown";
 | 
					
						
							| 
									
										
										
										
											2017-08-03 18:16:48 -07:00
										 |  |  |     @FXML
 | 
					
						
							|  |  |  |     private TabPane coreTabPane;
 | 
					
						
							|  |  |  |     @FXML
 | 
					
						
							|  |  |  |     private Tab calculateTab;
 | 
					
						
							|  |  |  |     @FXML
 | 
					
						
							|  |  |  |     private Tab settingsTab;
 | 
					
						
							| 
									
										
										
										
											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;
 | 
					
						
							| 
									
										
										
										
											2017-07-31 17:17:56 -07:00
										 |  |  |     @FXML
 | 
					
						
							|  |  |  |     private Text outputText;
 | 
					
						
							|  |  |  |     @FXML
 | 
					
						
							|  |  |  |     private TextField inputField;
 | 
					
						
							|  |  |  |     @FXML
 | 
					
						
							|  |  |  |     private Button inputButton;
 | 
					
						
							| 
									
										
										
										
											2017-08-01 11:52:48 -07:00
										 |  |  |     @FXML
 | 
					
						
							| 
									
										
										
										
											2017-08-05 13:57:27 -07:00
										 |  |  |     private Button stopButton;
 | 
					
						
							|  |  |  |     @FXML
 | 
					
						
							| 
									
										
										
										
											2017-08-01 11:52:48 -07:00
										 |  |  |     private ComboBox<String> numberImplementationBox;
 | 
					
						
							| 
									
										
										
										
											2017-08-02 18:24:20 -07:00
										 |  |  |     @FXML
 | 
					
						
							| 
									
										
										
										
											2017-08-02 18:48:42 -07:00
										 |  |  |     private ListView<ToggleablePlugin> enabledPluginView;
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:30:37 -07:00
										 |  |  |     @FXML
 | 
					
						
							|  |  |  |     private TextField computationLimitField;
 | 
					
						
							| 
									
										
										
										
											2017-07-31 17:17:56 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							| 
									
										
										
										
											2017-08-01 11:52:48 -07:00
										 |  |  |     private ObservableList<String> numberImplementationOptions;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-02 18:48:42 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * The list of plugin objects that can be toggled on and off,
 | 
					
						
							|  |  |  |      * and, when reloaded, get added to the plugin manager's black list.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							|  |  |  |     private ObservableList<ToggleablePlugin> enabledPlugins;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-03 13:55:39 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * The abacus instance used for changing the plugin configuration.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							| 
									
										
										
										
											2017-07-31 16:52:34 -07:00
										 |  |  |     private Abacus abacus;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-03 13:55:39 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Boolean which represents whether changes were made to the configuration.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							|  |  |  |     private boolean changesMade;
 | 
					
						
							| 
									
										
										
										
											2017-08-03 18:12:40 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Whether an alert about changes to the configuration was already shown.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							|  |  |  |     private boolean reloadAlertShown;
 | 
					
						
							| 
									
										
										
										
											2017-08-03 13:55:39 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * The alert shown when a press to "apply" is needed.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							|  |  |  |     private Alert reloadAlert;
 | 
					
						
							| 
									
										
										
										
											2017-08-07 08:58:47 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * The runnable that takes care of killing computations that take too long.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							|  |  |  |     private final Runnable TIMER_RUNNABLE = () -> {
 | 
					
						
							|  |  |  |         try {
 | 
					
						
							| 
									
										
										
										
											2017-08-07 09:22:11 -07:00
										 |  |  |             Configuration abacusConfig = abacus.getConfiguration();
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:30:37 -07:00
										 |  |  |             if(abacusConfig.getComputationDelay() == 0) return;
 | 
					
						
							| 
									
										
										
										
											2017-08-07 09:22:11 -07:00
										 |  |  |             Thread.sleep((long) (abacusConfig.getComputationDelay() * 1000));
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:30:37 -07:00
										 |  |  |             performStop();
 | 
					
						
							|  |  |  |         } catch (InterruptedException e) { }
 | 
					
						
							| 
									
										
										
										
											2017-08-07 08:58:47 -07:00
										 |  |  |     };
 | 
					
						
							| 
									
										
										
										
											2017-08-05 14:34:31 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * The runnable used to perform the calculation.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							|  |  |  |     private final Runnable CALCULATION_RUNNABLE = new Runnable() {
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         private String attemptCalculation(){
 | 
					
						
							|  |  |  |             try {
 | 
					
						
							| 
									
										
										
										
											2017-08-05 15:58:43 -07:00
										 |  |  |                 TreeNode constructedTree = abacus.parseString(inputField.getText());
 | 
					
						
							|  |  |  |                 if (constructedTree == null) {
 | 
					
						
							|  |  |  |                     return ERR_SYNTAX;
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							| 
									
										
										
										
											2017-08-05 14:34:31 -07:00
										 |  |  |                 NumberInterface evaluatedNumber = abacus.evaluateTree(constructedTree);
 | 
					
						
							|  |  |  |                 if (evaluatedNumber == null) {
 | 
					
						
							|  |  |  |                     return ERR_EVAL;
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							| 
									
										
										
										
											2017-08-05 14:43:24 -07:00
										 |  |  |                 String resultingString = evaluatedNumber.toString();
 | 
					
						
							|  |  |  |                 historyData.add(new HistoryModel(inputField.getText(), constructedTree.toString(), resultingString));
 | 
					
						
							|  |  |  |                 return resultingString;
 | 
					
						
							| 
									
										
										
										
											2017-08-05 14:34:31 -07:00
										 |  |  |             } catch (ComputationInterruptedException exception) {
 | 
					
						
							|  |  |  |                 return ERR_STOP;
 | 
					
						
							| 
									
										
										
										
											2017-08-05 15:58:43 -07:00
										 |  |  |             } catch (RuntimeException exception){
 | 
					
						
							|  |  |  |                 exception.printStackTrace();
 | 
					
						
							|  |  |  |                 return ERR_EXCEPTION;
 | 
					
						
							| 
									
										
										
										
											2017-08-05 14:34:31 -07:00
										 |  |  |             }
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         @Override
 | 
					
						
							|  |  |  |         public void run() {
 | 
					
						
							|  |  |  |             String calculation = attemptCalculation();
 | 
					
						
							|  |  |  |             Platform.runLater(() -> {
 | 
					
						
							|  |  |  |                 outputText.setText(calculation);
 | 
					
						
							| 
									
										
										
										
											2017-08-05 14:36:42 -07:00
										 |  |  |                 inputField.setText("");
 | 
					
						
							| 
									
										
										
										
											2017-08-05 14:34:31 -07:00
										 |  |  |                 inputButton.setDisable(false);
 | 
					
						
							|  |  |  |                 stopButton.setDisable(true);
 | 
					
						
							|  |  |  |             });
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |     };
 | 
					
						
							| 
									
										
										
										
											2017-08-07 11:11:41 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * The thread that is waiting to pause the calculation.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:30:37 -07:00
										 |  |  |     private Thread computationLimitThread;
 | 
					
						
							| 
									
										
										
										
											2017-08-05 15:19:39 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * The thread in which the computation runs.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							| 
									
										
										
										
											2017-08-05 14:34:31 -07:00
										 |  |  |     private Thread calculationThread;
 | 
					
						
							| 
									
										
										
										
											2017-08-03 13:55:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-03 18:12:40 -07:00
										 |  |  |     /**
 | 
					
						
							|  |  |  |      * Alerts the user if the changes they made
 | 
					
						
							|  |  |  |      * have not yet been applied.
 | 
					
						
							|  |  |  |      */
 | 
					
						
							| 
									
										
										
										
											2017-08-04 13:20:57 -07:00
										 |  |  |     private void alertIfApplyNeeded(boolean ignorePrevious) {
 | 
					
						
							|  |  |  |         if (changesMade && (!reloadAlertShown || ignorePrevious)) {
 | 
					
						
							| 
									
										
										
										
											2017-08-03 18:12:40 -07:00
										 |  |  |             reloadAlertShown = true;
 | 
					
						
							|  |  |  |             reloadAlert.showAndWait();
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-31 16:52:34 -07:00
										 |  |  |     @FXML
 | 
					
						
							| 
									
										
										
										
											2017-08-04 13:20:57 -07:00
										 |  |  |     public void initialize() {
 | 
					
						
							| 
									
										
										
										
											2017-07-31 22:53:42 -07:00
										 |  |  |         Callback<TableColumn<HistoryModel, String>, TableCell<HistoryModel, String>> cellFactory =
 | 
					
						
							|  |  |  |                 param -> new CopyableCell<>();
 | 
					
						
							| 
									
										
										
										
											2017-08-02 18:48:42 -07:00
										 |  |  |         Callback<ListView<ToggleablePlugin>, ListCell<ToggleablePlugin>> pluginCellFactory =
 | 
					
						
							|  |  |  |                 param -> new CheckBoxListCell<>(ToggleablePlugin::enabledProperty, new StringConverter<ToggleablePlugin>() {
 | 
					
						
							|  |  |  |                     @Override
 | 
					
						
							|  |  |  |                     public String toString(ToggleablePlugin object) {
 | 
					
						
							|  |  |  |                         return object.getClassName().substring(object.getClassName().lastIndexOf('.') + 1);
 | 
					
						
							|  |  |  |                     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     @Override
 | 
					
						
							|  |  |  |                     public ToggleablePlugin fromString(String string) {
 | 
					
						
							|  |  |  |                         return new ToggleablePlugin(true, string);
 | 
					
						
							|  |  |  |                     }
 | 
					
						
							|  |  |  |                 });
 | 
					
						
							| 
									
										
										
										
											2017-07-31 22:53:42 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-31 17:49:57 -07:00
										 |  |  |         historyData = FXCollections.observableArrayList();
 | 
					
						
							| 
									
										
										
										
											2017-07-31 22:29:44 -07:00
										 |  |  |         historyTable.setItems(historyData);
 | 
					
						
							| 
									
										
										
										
											2017-08-01 11:52:48 -07:00
										 |  |  |         numberImplementationOptions = FXCollections.observableArrayList();
 | 
					
						
							|  |  |  |         numberImplementationBox.setItems(numberImplementationOptions);
 | 
					
						
							| 
									
										
										
										
											2017-08-03 18:12:40 -07:00
										 |  |  |         numberImplementationBox.getSelectionModel().selectedIndexProperty().addListener(e -> changesMade = true);
 | 
					
						
							| 
									
										
										
										
											2017-07-31 22:34:49 -07:00
										 |  |  |         historyTable.getSelectionModel().setCellSelectionEnabled(true);
 | 
					
						
							| 
									
										
										
										
											2017-08-02 18:48:42 -07:00
										 |  |  |         enabledPlugins = FXCollections.observableArrayList();
 | 
					
						
							|  |  |  |         enabledPluginView.setItems(enabledPlugins);
 | 
					
						
							|  |  |  |         enabledPluginView.setCellFactory(pluginCellFactory);
 | 
					
						
							| 
									
										
										
										
											2017-07-31 22:53:42 -07:00
										 |  |  |         inputColumn.setCellFactory(cellFactory);
 | 
					
						
							| 
									
										
										
										
											2017-07-31 22:29:44 -07:00
										 |  |  |         inputColumn.setCellValueFactory(cell -> cell.getValue().inputProperty());
 | 
					
						
							| 
									
										
										
										
											2017-07-31 22:53:42 -07:00
										 |  |  |         parsedColumn.setCellFactory(cellFactory);
 | 
					
						
							| 
									
										
										
										
											2017-07-31 22:29:44 -07:00
										 |  |  |         parsedColumn.setCellValueFactory(cell -> cell.getValue().parsedProperty());
 | 
					
						
							| 
									
										
										
										
											2017-07-31 22:53:42 -07:00
										 |  |  |         outputColumn.setCellFactory(cellFactory);
 | 
					
						
							| 
									
										
										
										
											2017-07-31 22:29:44 -07:00
										 |  |  |         outputColumn.setCellValueFactory(cell -> cell.getValue().outputProperty());
 | 
					
						
							| 
									
										
										
										
											2017-08-03 18:16:48 -07:00
										 |  |  |         coreTabPane.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
 | 
					
						
							| 
									
										
										
										
											2017-08-04 13:20:57 -07:00
										 |  |  |             if (oldValue.equals(settingsTab)) alertIfApplyNeeded(true);
 | 
					
						
							| 
									
										
										
										
											2017-08-03 18:16:48 -07:00
										 |  |  |         });
 | 
					
						
							| 
									
										
										
										
											2017-08-01 11:52:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-05 17:06:22 -07:00
										 |  |  |         abacus = new Abacus(new Configuration(CONFIG_FILE));
 | 
					
						
							| 
									
										
										
										
											2017-08-05 16:21:02 -07:00
										 |  |  |         PluginManager abacusPluginManager = abacus.getPluginManager();
 | 
					
						
							|  |  |  |         abacusPluginManager.addListener(this);
 | 
					
						
							|  |  |  |         abacusPluginManager.addInstantiated(new StandardPlugin(abacus.getPluginManager()));
 | 
					
						
							|  |  |  |         try {
 | 
					
						
							|  |  |  |             ClassFinder.loadJars("plugins").forEach(abacusPluginManager::addClass);
 | 
					
						
							|  |  |  |         } catch (IOException | ClassNotFoundException e) {
 | 
					
						
							|  |  |  |             e.printStackTrace();
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |         abacusPluginManager.reload();
 | 
					
						
							| 
									
										
										
										
											2017-08-03 13:55:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:30:37 -07:00
										 |  |  |         computationLimitField.setText(Double.toString(abacus.getConfiguration().getComputationDelay()));
 | 
					
						
							|  |  |  |         computationLimitField.textProperty().addListener((observable, oldValue, newValue) -> {
 | 
					
						
							|  |  |  |             if(!newValue.matches("(\\d+(\\.\\d*)?)?")) {
 | 
					
						
							|  |  |  |                 computationLimitField.setText(oldValue);
 | 
					
						
							|  |  |  |             } else {
 | 
					
						
							|  |  |  |                 changesMade = true;
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |         });
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-03 13:55:39 -07:00
										 |  |  |         changesMade = false;
 | 
					
						
							| 
									
										
										
										
											2017-08-03 18:12:40 -07:00
										 |  |  |         reloadAlertShown = false;
 | 
					
						
							| 
									
										
										
										
											2017-08-03 13:55:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         reloadAlert = new Alert(Alert.AlertType.WARNING);
 | 
					
						
							|  |  |  |         reloadAlert.setTitle(APPLY_MSG_TITLE);
 | 
					
						
							| 
									
										
										
										
											2017-08-03 18:12:40 -07:00
										 |  |  |         reloadAlert.setHeaderText(APPLY_MSG_HEADER);
 | 
					
						
							| 
									
										
										
										
											2017-08-03 13:55:39 -07:00
										 |  |  |         reloadAlert.setContentText(APPLY_MSG_TEXT);
 | 
					
						
							| 
									
										
										
										
											2017-07-31 16:52:34 -07:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-31 17:17:56 -07:00
										 |  |  |     @FXML
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:39:50 -07:00
										 |  |  |     public void performCalculation() {
 | 
					
						
							| 
									
										
										
										
											2017-08-05 13:26:29 -07:00
										 |  |  |         inputButton.setDisable(true);
 | 
					
						
							| 
									
										
										
										
											2017-08-05 14:34:31 -07:00
										 |  |  |         stopButton.setDisable(false);
 | 
					
						
							|  |  |  |         calculationThread = new Thread(CALCULATION_RUNNABLE);
 | 
					
						
							|  |  |  |         calculationThread.start();
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:30:37 -07:00
										 |  |  |         computationLimitThread = new Thread(TIMER_RUNNABLE);
 | 
					
						
							|  |  |  |         computationLimitThread.start();
 | 
					
						
							| 
									
										
										
										
											2017-08-03 14:04:09 -07:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2017-08-04 14:29:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-03 14:04:09 -07:00
										 |  |  |     @FXML
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:39:50 -07:00
										 |  |  |     public void performStop(){
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:30:37 -07:00
										 |  |  |         if(calculationThread != null) {
 | 
					
						
							| 
									
										
										
										
											2017-08-05 14:34:31 -07:00
										 |  |  |             calculationThread.interrupt();
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:30:37 -07:00
										 |  |  |             calculationThread = null;
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |         if(computationLimitThread != null){
 | 
					
						
							|  |  |  |             computationLimitThread.interrupt();
 | 
					
						
							|  |  |  |             computationLimitThread = null;
 | 
					
						
							|  |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2017-07-31 17:17:56 -07:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-03 19:00:13 -07:00
										 |  |  |     @FXML
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:39:50 -07:00
										 |  |  |     public void performSaveAndReload() {
 | 
					
						
							| 
									
										
										
										
											2017-08-03 19:00:13 -07:00
										 |  |  |         performSave();
 | 
					
						
							|  |  |  |         performReload();
 | 
					
						
							|  |  |  |         changesMade = false;
 | 
					
						
							|  |  |  |         reloadAlertShown = false;
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:01:01 -07:00
										 |  |  |     @FXML
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:39:50 -07:00
										 |  |  |     public void performReload() {
 | 
					
						
							| 
									
										
										
										
											2017-08-03 18:12:40 -07:00
										 |  |  |         alertIfApplyNeeded(true);
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:01:01 -07:00
										 |  |  |         abacus.getPluginManager().reload();
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:37:35 -07:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @FXML
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:39:50 -07:00
										 |  |  |     public void performSave() {
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:37:35 -07:00
										 |  |  |         Configuration configuration = abacus.getConfiguration();
 | 
					
						
							|  |  |  |         configuration.setNumberImplementation(numberImplementationBox.getSelectionModel().getSelectedItem());
 | 
					
						
							| 
									
										
										
										
											2017-08-03 13:55:39 -07:00
										 |  |  |         Set<String> disabledPlugins = configuration.getDisabledPlugins();
 | 
					
						
							|  |  |  |         disabledPlugins.clear();
 | 
					
						
							| 
									
										
										
										
											2017-08-04 13:20:57 -07:00
										 |  |  |         for (ToggleablePlugin pluginEntry : enabledPlugins) {
 | 
					
						
							|  |  |  |             if (!pluginEntry.isEnabled()) disabledPlugins.add(pluginEntry.getClassName());
 | 
					
						
							| 
									
										
										
										
											2017-08-03 13:55:39 -07:00
										 |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:30:37 -07:00
										 |  |  |         if(computationLimitField.getText().matches("\\d*(\\.\\d+)?") && computationLimitField.getText().length() != 0)
 | 
					
						
							|  |  |  |             configuration.setComputationDelay(Double.parseDouble(computationLimitField.getText()));
 | 
					
						
							| 
									
										
										
										
											2017-08-05 17:04:07 -07:00
										 |  |  |         configuration.saveTo(CONFIG_FILE);
 | 
					
						
							| 
									
										
										
										
											2017-08-03 13:55:39 -07:00
										 |  |  |         changesMade = false;
 | 
					
						
							| 
									
										
										
										
											2017-08-03 18:12:40 -07:00
										 |  |  |         reloadAlertShown = false;
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:01:01 -07:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:18:33 -07:00
										 |  |  |     @Override
 | 
					
						
							|  |  |  |     public void onLoad(PluginManager manager) {
 | 
					
						
							|  |  |  |         Configuration configuration = abacus.getConfiguration();
 | 
					
						
							|  |  |  |         Set<String> disabledPlugins = configuration.getDisabledPlugins();
 | 
					
						
							| 
									
										
										
										
											2017-08-04 12:04:37 -07:00
										 |  |  |         numberImplementationOptions.addAll(abacus.getPluginManager().getAllNumberImplementations());
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:18:33 -07:00
										 |  |  |         String actualImplementation = configuration.getNumberImplementation();
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:26:14 -07:00
										 |  |  |         String toSelect = (numberImplementationOptions.contains(actualImplementation)) ? actualImplementation : "<default>";
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:18:33 -07:00
										 |  |  |         numberImplementationBox.getSelectionModel().select(toSelect);
 | 
					
						
							| 
									
										
										
										
											2017-08-04 13:20:57 -07:00
										 |  |  |         for (Class<?> pluginClass : abacus.getPluginManager().getLoadedPluginClasses()) {
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:18:33 -07:00
										 |  |  |             String fullName = pluginClass.getName();
 | 
					
						
							| 
									
										
										
										
											2017-08-03 18:12:40 -07:00
										 |  |  |             ToggleablePlugin plugin = new ToggleablePlugin(!disabledPlugins.contains(fullName), fullName);
 | 
					
						
							|  |  |  |             plugin.enabledProperty().addListener(e -> changesMade = true);
 | 
					
						
							|  |  |  |             enabledPlugins.add(plugin);
 | 
					
						
							| 
									
										
										
										
											2017-08-02 19:18:33 -07:00
										 |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @Override
 | 
					
						
							|  |  |  |     public void onUnload(PluginManager manager) {
 | 
					
						
							|  |  |  |         enabledPlugins.clear();
 | 
					
						
							|  |  |  |         numberImplementationOptions.clear();
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2017-08-07 10:30:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-31 16:48:04 -07:00
										 |  |  | }
 |