diff --git a/src/main/java/org/nwapw/abacus/Abacus.java b/src/main/java/org/nwapw/abacus/Abacus.java index 1ee8f8a..16738b2 100644 --- a/src/main/java/org/nwapw/abacus/Abacus.java +++ b/src/main/java/org/nwapw/abacus/Abacus.java @@ -1,6 +1,7 @@ package org.nwapw.abacus; import org.nwapw.abacus.config.ConfigurationObject; +import org.nwapw.abacus.fx.AbacusApplication; import org.nwapw.abacus.number.NaiveNumber; import org.nwapw.abacus.number.NumberInterface; import org.nwapw.abacus.parsing.LexerTokenizer; @@ -11,9 +12,7 @@ import org.nwapw.abacus.plugin.PluginManager; import org.nwapw.abacus.plugin.StandardPlugin; import org.nwapw.abacus.tree.NumberReducer; import org.nwapw.abacus.tree.TreeNode; -import org.nwapw.abacus.window.Window; -import javax.swing.*; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; @@ -79,13 +78,7 @@ public class Abacus { } public static void main(String[] args) { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (ClassNotFoundException | InstantiationException | UnsupportedLookAndFeelException | IllegalAccessException e) { - e.printStackTrace(); - } - - new Window(new Abacus()).setVisible(true); + AbacusApplication.launch(AbacusApplication.class, args); } /** diff --git a/src/main/java/org/nwapw/abacus/fx/AbacusApplication.java b/src/main/java/org/nwapw/abacus/fx/AbacusApplication.java new file mode 100644 index 0000000..3f86fdd --- /dev/null +++ b/src/main/java/org/nwapw/abacus/fx/AbacusApplication.java @@ -0,0 +1,20 @@ +package org.nwapw.abacus.fx; + +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.stage.Stage; + +public class AbacusApplication extends Application { + + @Override + public void start(Stage primaryStage) throws Exception { + Parent parent = FXMLLoader.load(getClass().getResource("/abacus.fxml")); + Scene mainScene = new Scene(parent, 320, 480); + primaryStage.setScene(mainScene); + primaryStage.setTitle("Abacus"); + primaryStage.show(); + } + +} diff --git a/src/main/java/org/nwapw/abacus/fx/AbacusController.java b/src/main/java/org/nwapw/abacus/fx/AbacusController.java new file mode 100644 index 0000000..7c9d539 --- /dev/null +++ b/src/main/java/org/nwapw/abacus/fx/AbacusController.java @@ -0,0 +1,77 @@ +package org.nwapw.abacus.fx; + +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; + + +public class AbacusController { + + private static final String ERR_SYNTAX = "Syntax Error"; + private static final String ERR_EVAL = "Evaluation Error"; + + @FXML + private TableView historyTable; + @FXML + private TableColumn inputColumn; + @FXML + private TableColumn parsedColumn; + @FXML + private TableColumn outputColumn; + @FXML + private Text outputText; + @FXML + private TextField inputField; + @FXML + private Button inputButton; + + private ObservableList historyData; + + private Abacus abacus; + + @FXML + public void initialize(){ + Callback, TableCell> cellFactory = + param -> new CopyableCell<>(); + + abacus = new Abacus(); + historyData = FXCollections.observableArrayList(); + historyTable.setItems(historyData); + historyTable.getSelectionModel().setCellSelectionEnabled(true); + inputColumn.setCellFactory(cellFactory); + inputColumn.setCellValueFactory(cell -> cell.getValue().inputProperty()); + parsedColumn.setCellFactory(cellFactory); + parsedColumn.setCellValueFactory(cell -> cell.getValue().parsedProperty()); + outputColumn.setCellFactory(cellFactory); + outputColumn.setCellValueFactory(cell -> cell.getValue().outputProperty()); + } + + @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())); + + inputButton.setDisable(false); + inputField.setText(""); + } + +} diff --git a/src/main/java/org/nwapw/abacus/fx/CopyableCell.java b/src/main/java/org/nwapw/abacus/fx/CopyableCell.java new file mode 100644 index 0000000..7755704 --- /dev/null +++ b/src/main/java/org/nwapw/abacus/fx/CopyableCell.java @@ -0,0 +1,26 @@ +package org.nwapw.abacus.fx; + +import javafx.scene.control.TableCell; +import javafx.scene.input.MouseEvent; + +import java.awt.*; +import java.awt.datatransfer.StringSelection; + +public class CopyableCell extends TableCell { + + public CopyableCell(){ + addEventFilter(MouseEvent.MOUSE_CLICKED, event -> { + if(event.getClickCount() == 2){ + Toolkit.getDefaultToolkit().getSystemClipboard() + .setContents(new StringSelection(getText()), null); + } + }); + } + + @Override + protected void updateItem(T item, boolean empty) { + super.updateItem(item, empty); + setText((empty || item == null) ? null : item.toString()); + setGraphic(null); + } +} diff --git a/src/main/java/org/nwapw/abacus/fx/HistoryModel.java b/src/main/java/org/nwapw/abacus/fx/HistoryModel.java new file mode 100644 index 0000000..2a267b5 --- /dev/null +++ b/src/main/java/org/nwapw/abacus/fx/HistoryModel.java @@ -0,0 +1,42 @@ +package org.nwapw.abacus.fx; + +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; + +public class HistoryModel { + + private final StringProperty input; + private final StringProperty parsed; + private final StringProperty output; + + public HistoryModel(String input, String parsed, String output){ + this.input = new SimpleStringProperty(); + this.parsed = new SimpleStringProperty(); + this.output = new SimpleStringProperty(); + this.input.setValue(input); + this.parsed.setValue(parsed); + this.output.setValue(output); + } + + public StringProperty inputProperty() { + return input; + } + public String getInput() { + return input.get(); + } + + public StringProperty parsedProperty() { + return parsed; + } + public String getParsed() { + return parsed.get(); + } + + public StringProperty outputProperty() { + return output; + } + public String getOutput() { + return output.get(); + } + +} diff --git a/src/main/resources/abacus.fxml b/src/main/resources/abacus.fxml new file mode 100644 index 0000000..9a68947 --- /dev/null +++ b/src/main/resources/abacus.fxml @@ -0,0 +1,46 @@ + + + + + + + + +
+ + + +
+ + + + + + + + + + +
+ + + + + + + + + +
+ +