mirror of
https://github.com/DanilaFe/abacus
synced 2026-01-26 08:35:20 +00:00
Compare commits
4 Commits
config-rew
...
plugins-up
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c03e191c36 | ||
| 5de9453bec | |||
| 6f99f07150 | |||
| 2cf41c1029 |
@@ -9,7 +9,7 @@ import org.nwapw.abacus.parsing.ShuntingYardParser;
|
|||||||
import org.nwapw.abacus.parsing.TreeBuilder;
|
import org.nwapw.abacus.parsing.TreeBuilder;
|
||||||
import org.nwapw.abacus.plugin.ClassFinder;
|
import org.nwapw.abacus.plugin.ClassFinder;
|
||||||
import org.nwapw.abacus.plugin.PluginManager;
|
import org.nwapw.abacus.plugin.PluginManager;
|
||||||
import org.nwapw.abacus.plugin.StandardPlugin;
|
//import org.nwapw.abacus.plugin.StandardPlugin;
|
||||||
import org.nwapw.abacus.tree.NumberReducer;
|
import org.nwapw.abacus.tree.NumberReducer;
|
||||||
import org.nwapw.abacus.tree.TreeNode;
|
import org.nwapw.abacus.tree.TreeNode;
|
||||||
|
|
||||||
@@ -67,16 +67,22 @@ public class Abacus {
|
|||||||
|
|
||||||
pluginManager.addListener(lexerTokenizer);
|
pluginManager.addListener(lexerTokenizer);
|
||||||
pluginManager.addListener(shuntingYardParser);
|
pluginManager.addListener(shuntingYardParser);
|
||||||
pluginManager.addInstantiated(new StandardPlugin(pluginManager));
|
//pluginManager.addInstantiated(new StandardPlugin(pluginManager));
|
||||||
|
/*
|
||||||
try {
|
try {
|
||||||
ClassFinder.loadJars("plugins")
|
ClassFinder.loadJars("plugins")
|
||||||
.forEach(plugin -> pluginManager.addClass(plugin));
|
.forEach(plugin -> pluginManager.addClass(plugin));
|
||||||
} catch (IOException | ClassNotFoundException e) {
|
} catch (IOException | ClassNotFoundException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}//*/
|
||||||
pluginManager.load();
|
pluginManager.load();
|
||||||
}
|
}
|
||||||
|
public void loadClass(Class<?> newClass){
|
||||||
|
pluginManager.addClass(newClass);
|
||||||
|
}
|
||||||
|
public void unloadClass(Class<?> newClass){
|
||||||
|
pluginManager.removeClass(newClass);
|
||||||
|
}
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
AbacusApplication.launch(AbacusApplication.class, args);
|
AbacusApplication.launch(AbacusApplication.class, args);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ import javafx.scene.Parent;
|
|||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main application class for JavaFX responsible for loading
|
||||||
|
* and displaying the fxml file.
|
||||||
|
*/
|
||||||
public class AbacusApplication extends Application {
|
public class AbacusApplication extends Application {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -8,12 +8,25 @@ import javafx.scene.text.Text;
|
|||||||
import javafx.util.Callback;
|
import javafx.util.Callback;
|
||||||
import org.nwapw.abacus.Abacus;
|
import org.nwapw.abacus.Abacus;
|
||||||
import org.nwapw.abacus.number.NumberInterface;
|
import org.nwapw.abacus.number.NumberInterface;
|
||||||
|
import org.nwapw.abacus.plugin.ClassFinder;
|
||||||
import org.nwapw.abacus.tree.TreeNode;
|
import org.nwapw.abacus.tree.TreeNode;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The controller for the abacus FX UI, responsible
|
||||||
|
* for all the user interaction.
|
||||||
|
*/
|
||||||
public class AbacusController {
|
public class AbacusController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant string that is displayed if the text could not be lexed or parsed.
|
||||||
|
*/
|
||||||
private static final String ERR_SYNTAX = "Syntax Error";
|
private static final String ERR_SYNTAX = "Syntax Error";
|
||||||
|
/**
|
||||||
|
* Constant string that is displayed if the tree could not be reduced.
|
||||||
|
*/
|
||||||
private static final String ERR_EVAL = "Evaluation Error";
|
private static final String ERR_EVAL = "Evaluation Error";
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@@ -32,9 +45,22 @@ public class AbacusController {
|
|||||||
private Button inputButton;
|
private Button inputButton;
|
||||||
@FXML
|
@FXML
|
||||||
private ComboBox<String> numberImplementationBox;
|
private ComboBox<String> numberImplementationBox;
|
||||||
|
@FXML
|
||||||
|
private Button loadButton;
|
||||||
|
@FXML
|
||||||
|
private Button unloadButton;
|
||||||
|
@FXML
|
||||||
|
private TextField loadField;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of history entries, created by the users.
|
||||||
|
*/
|
||||||
private ObservableList<HistoryModel> historyData;
|
private ObservableList<HistoryModel> historyData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The abacus instance used for calculations and all
|
||||||
|
* other main processing code.
|
||||||
|
*/
|
||||||
private ObservableList<String> numberImplementationOptions;
|
private ObservableList<String> numberImplementationOptions;
|
||||||
|
|
||||||
private Abacus abacus;
|
private Abacus abacus;
|
||||||
@@ -89,5 +115,38 @@ public class AbacusController {
|
|||||||
inputButton.setDisable(false);
|
inputButton.setDisable(false);
|
||||||
inputField.setText("");
|
inputField.setText("");
|
||||||
}
|
}
|
||||||
|
@FXML
|
||||||
|
private void loadClass(){
|
||||||
|
try {
|
||||||
|
for(Class<?> plugin :ClassFinder.loadJars("plugins")){
|
||||||
|
String name = "";
|
||||||
|
//String name = plugin.getName();
|
||||||
|
while(!(name.indexOf('/') ==-1)){
|
||||||
|
name=name.substring(name.indexOf('/')+1);
|
||||||
|
}
|
||||||
|
if(loadField.getText().equals("")||loadField.getText().equals(name)||(loadField.getText()+".class").equals(name)){
|
||||||
|
//abacus.loadClass(plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException | ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@FXML
|
||||||
|
private void unloadClass(){
|
||||||
|
try {
|
||||||
|
for(Class<?> plugin :ClassFinder.loadJars("plugins")){
|
||||||
|
String name = plugin.getName();
|
||||||
|
while(!(name.indexOf('/') ==-1)){
|
||||||
|
name=name.substring(name.indexOf('/')+1);
|
||||||
|
}
|
||||||
|
if(loadField.getText().equals("")||loadField.getText().equals(name)||(loadField.getText()+".class").equals(name)){
|
||||||
|
//abacus.unloadClass(plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException | ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,17 @@ import javafx.scene.input.MouseEvent;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.datatransfer.StringSelection;
|
import java.awt.datatransfer.StringSelection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cell that copies its value to the clipboard
|
||||||
|
* when double clicked.
|
||||||
|
* @param <S> The type of the table view generic type.
|
||||||
|
* @param <T> The type of the value contained in the cell.
|
||||||
|
*/
|
||||||
public class CopyableCell<S, T> extends TableCell<S, T> {
|
public class CopyableCell<S, T> extends TableCell<S, T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new copyable cell.
|
||||||
|
*/
|
||||||
public CopyableCell(){
|
public CopyableCell(){
|
||||||
addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
|
addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
|
||||||
if(event.getClickCount() == 2){
|
if(event.getClickCount() == 2){
|
||||||
|
|||||||
@@ -3,12 +3,33 @@ package org.nwapw.abacus.fx;
|
|||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data model used for storing history entries.
|
||||||
|
*/
|
||||||
public class HistoryModel {
|
public class HistoryModel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The property used for displaying the column
|
||||||
|
* for the user input.
|
||||||
|
*/
|
||||||
private final StringProperty input;
|
private final StringProperty input;
|
||||||
|
/**
|
||||||
|
* The property used for displaying the column
|
||||||
|
* that contains the parsed input.
|
||||||
|
*/
|
||||||
private final StringProperty parsed;
|
private final StringProperty parsed;
|
||||||
|
/**
|
||||||
|
* The property used for displaying the column
|
||||||
|
* that contains the program output.
|
||||||
|
*/
|
||||||
private final StringProperty output;
|
private final StringProperty output;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new history model with the given variables.
|
||||||
|
* @param input the user input
|
||||||
|
* @param parsed the parsed input
|
||||||
|
* @param output the program output.
|
||||||
|
*/
|
||||||
public HistoryModel(String input, String parsed, String output){
|
public HistoryModel(String input, String parsed, String output){
|
||||||
this.input = new SimpleStringProperty();
|
this.input = new SimpleStringProperty();
|
||||||
this.parsed = new SimpleStringProperty();
|
this.parsed = new SimpleStringProperty();
|
||||||
@@ -18,23 +39,47 @@ public class HistoryModel {
|
|||||||
this.output.setValue(output);
|
this.output.setValue(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the input property.
|
||||||
|
* @return the input property.
|
||||||
|
*/
|
||||||
public StringProperty inputProperty() {
|
public StringProperty inputProperty() {
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Gets the input.
|
||||||
|
* @return the input.
|
||||||
|
*/
|
||||||
public String getInput() {
|
public String getInput() {
|
||||||
return input.get();
|
return input.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the parsed input property.
|
||||||
|
* @return the parsed input property.
|
||||||
|
*/
|
||||||
public StringProperty parsedProperty() {
|
public StringProperty parsedProperty() {
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Gets the parsed input.
|
||||||
|
* @return the parsed input.
|
||||||
|
*/
|
||||||
public String getParsed() {
|
public String getParsed() {
|
||||||
return parsed.get();
|
return parsed.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the output property.
|
||||||
|
* @return the output property.
|
||||||
|
*/
|
||||||
public StringProperty outputProperty() {
|
public StringProperty outputProperty() {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Gets the program output.
|
||||||
|
* @return the output.
|
||||||
|
*/
|
||||||
public String getOutput() {
|
public String getOutput() {
|
||||||
return output.get();
|
return output.get();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package org.nwapw.abacus.number;
|
package org.nwapw.abacus.number;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.MathContext;
|
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A number that uses a BigDecimal to store its value,
|
||||||
|
* leading to infinite possible precision.
|
||||||
|
*/
|
||||||
public class PreciseNumber implements NumberInterface {
|
public class PreciseNumber implements NumberInterface {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -140,6 +140,11 @@ public class PluginManager {
|
|||||||
plugins.add(plugin);
|
plugins.add(plugin);
|
||||||
loadedPluginClasses.add(plugin.getClass());
|
loadedPluginClasses.add(plugin.getClass());
|
||||||
}
|
}
|
||||||
|
public void removeInstantiated(Plugin plugin){
|
||||||
|
if (loadedPluginClasses.contains(plugin.getClass())) return;
|
||||||
|
plugins.remove(plugin);
|
||||||
|
loadedPluginClasses.remove(plugin.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a class of plugin, and adds it to this
|
* Instantiates a class of plugin, and adds it to this
|
||||||
@@ -155,6 +160,14 @@ public class PluginManager {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void removeClass(Class<?> newClass){
|
||||||
|
if (!Plugin.class.isAssignableFrom(newClass) || newClass == Plugin.class) return;
|
||||||
|
try {
|
||||||
|
removeInstantiated((Plugin) newClass.getConstructor(PluginManager.class).newInstance(this));
|
||||||
|
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads all the plugins in the PluginManager.
|
* Loads all the plugins in the PluginManager.
|
||||||
|
|||||||
@@ -46,6 +46,9 @@
|
|||||||
<padding><Insets left="10" right="10" top="10" bottom="10"/></padding>
|
<padding><Insets left="10" right="10" top="10" bottom="10"/></padding>
|
||||||
<Label text="Number Implementation" GridPane.columnIndex="0" GridPane.rowIndex="0"/>
|
<Label text="Number Implementation" GridPane.columnIndex="0" GridPane.rowIndex="0"/>
|
||||||
<ComboBox fx:id="numberImplementationBox" GridPane.columnIndex="1" GridPane.rowIndex="0"/>
|
<ComboBox fx:id="numberImplementationBox" GridPane.columnIndex="1" GridPane.rowIndex="0"/>
|
||||||
|
<Button fx:id="loadButton" text="Load" GridPane.rowIndex="1" GridPane.columnIndex="0" maxWidth = "Infinity" onAction="#loadClass"/>
|
||||||
|
<Button fx:id="unloadButton" text="Unload" GridPane.rowIndex="1" GridPane.columnIndex="1" maxWidth = "Infinity" onAction="#unloadClass"/>
|
||||||
|
<TextField fx:id="loadField" GridPane.rowIndex="1" GridPane.columnIndex="2"/>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
</Tab>
|
</Tab>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
|
|||||||
Reference in New Issue
Block a user