1
0
mirror of https://github.com/DanilaFe/abacus synced 2024-11-18 08:29:33 -08:00
Abacus/src/org/nwapw/abacus/window/Window.java

242 lines
7.6 KiB
Java
Raw Normal View History

2017-07-25 14:52:57 -07:00
package org.nwapw.abacus.window;
import org.nwapw.abacus.number.NumberInterface;
import org.nwapw.abacus.plugin.PluginManager;
import org.nwapw.abacus.tree.NumberReducer;
import org.nwapw.abacus.tree.TreeNode;
2017-07-25 14:52:57 -07:00
import javax.swing.*;
import java.awt.*;
2017-07-26 14:48:43 -07:00
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionListener;
2017-07-26 14:48:43 -07:00
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
2017-07-25 14:52:57 -07:00
2017-07-26 10:10:37 -07:00
/**
* The main UI window for the calculator.
*/
2017-07-25 14:52:57 -07:00
public class Window extends JFrame {
private static final String CALC_STRING = "Calculate";
private static final String SELECT_STRING = "Select";
private static final String SYNTAX_ERR_STRING = "Syntax Error";
private static final String EVAL_ERR_STRING = "Evaluation Error";
private static final String NUMBER_SYSTEM_LABEL = "Number Type:";
private static final String FUNCTION_LABEL = "Functions:";
private static final String[] BUTTON_NAMES = {
CALC_STRING,
CALC_STRING
};
private static boolean[] BUTTON_ENABLED = {
true,
false
};
/**
* The plugin manager used to retrieve functions.
*/
private PluginManager manager;
/**
* The reducer used to evaluate the tree.
*/
private NumberReducer reducer;
2017-07-26 10:10:37 -07:00
/**
* The last output by the calculator.
*/
2017-07-25 14:52:57 -07:00
private String lastOutput;
/**
* The tabbed pane that separates calculator contexts.
*/
private JTabbedPane pane;
2017-07-26 10:10:37 -07:00
/**
* The panel where the output occurs.
*/
private JPanel calculationPanel;
2017-07-26 10:10:37 -07:00
/**
* The text area reserved for the last output.
*/
private JTextArea lastOutputArea;
2017-07-26 10:10:37 -07:00
/**
* The table used for storing history results.
2017-07-26 10:10:37 -07:00
*/
private JTable historyTable;
/**
* The table model used for managing history.
*/
private HistoryTableModel historyModel;
2017-07-26 10:10:37 -07:00
/**
* The scroll pane for the history area.
*/
private JScrollPane historyScroll;
2017-07-26 10:10:37 -07:00
/**
* The panel where the input occurs.
*/
private JPanel inputPanel;
2017-07-26 10:10:37 -07:00
/**
* The input text field.
*/
private JTextField inputField;
2017-07-26 10:10:37 -07:00
/**
* The "submit" button.
*/
private JButton inputEnterButton;
2017-07-26 10:10:37 -07:00
/**
* The side panel for separate configuration.
*/
private JPanel settingsPanel;
2017-07-26 10:10:37 -07:00
/**
* Panel for elements relating to number
* system selection.
*/
private JPanel numberSystemPanel;
2017-07-26 10:10:37 -07:00
/**
* The possible list of number systems.
*/
private JComboBox<String> numberSystemList;
2017-07-26 10:10:37 -07:00
/**
* The panel for elements relating to
* function selection.
*/
private JPanel functionSelectPanel;
2017-07-26 10:10:37 -07:00
/**
* The list of functions available to the user.
*/
private JComboBox<String> functionList;
2017-07-26 10:10:37 -07:00
/**
* Action listener that causes the input to be evaluated.
2017-07-26 10:10:37 -07:00
*/
private ActionListener evaluateListener = (event) -> {
TreeNode parsedExpression = TreeNode.fromString(inputField.getText());
if(parsedExpression == null){
lastOutputArea.setText(SYNTAX_ERR_STRING);
return;
}
NumberInterface numberInterface = parsedExpression.reduce(reducer);
if(numberInterface == null){
lastOutputArea.setText(EVAL_ERR_STRING);;
return;
}
lastOutput = numberInterface.toString();
historyModel.addEntry(new HistoryTableModel.HistoryEntry(inputField.getText(), parsedExpression, lastOutput));
historyTable.invalidate();
lastOutputArea.setText(lastOutput);
inputField.setText("");
};
private ActionListener[] listeners = {
evaluateListener,
null
};
/**
* Creates a new window with the given manager.
* @param manager the manager to use.
*/
public Window(PluginManager manager){
this();
this.manager = manager;
reducer = new NumberReducer(manager);
}
/**
* Creates a new window.
*/
private Window() {
2017-07-25 14:52:57 -07:00
super();
lastOutput = "";
2017-07-26 15:23:22 -07:00
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
2017-07-26 17:19:43 -07:00
setSize(320, 480);
inputField = new JTextField();
inputEnterButton = new JButton(CALC_STRING);
inputPanel = new JPanel();
inputPanel.setLayout(new BorderLayout());
2017-07-25 22:08:12 -07:00
inputPanel.add(inputField, BorderLayout.CENTER);
inputPanel.add(inputEnterButton, BorderLayout.SOUTH);
historyModel = new HistoryTableModel();
historyTable = new JTable(historyModel);
historyScroll = new JScrollPane(historyTable);
lastOutputArea = new JTextArea(lastOutput);
lastOutputArea.setEditable(false);
calculationPanel = new JPanel();
calculationPanel.setLayout(new BorderLayout());
calculationPanel.add(historyScroll, BorderLayout.CENTER);
calculationPanel.add(lastOutputArea, BorderLayout.SOUTH);
numberSystemList = new JComboBox<>();
numberSystemPanel = new JPanel();
numberSystemPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
numberSystemPanel.setLayout(new FlowLayout());
numberSystemPanel.add(new JLabel(NUMBER_SYSTEM_LABEL));
numberSystemPanel.add(numberSystemList);
numberSystemPanel.setMaximumSize(numberSystemPanel.getPreferredSize());
functionList = new JComboBox<>();
functionSelectPanel = new JPanel();
functionSelectPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
functionSelectPanel.setLayout(new FlowLayout());
functionSelectPanel.add(new JLabel(FUNCTION_LABEL));
functionSelectPanel.add(functionList);
functionSelectPanel.setMaximumSize(functionSelectPanel.getPreferredSize());
settingsPanel = new JPanel();
settingsPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
settingsPanel.setLayout(new BoxLayout(settingsPanel, BoxLayout.PAGE_AXIS));
settingsPanel.add(numberSystemPanel);
settingsPanel.add(functionSelectPanel);
pane = new JTabbedPane();
pane.add("Calculator", calculationPanel);
pane.add("Settings", settingsPanel);
pane.addChangeListener(e -> {
int selectionIndex = pane.getSelectedIndex();
boolean enabled = BUTTON_ENABLED[selectionIndex];
ActionListener listener = listeners[selectionIndex];
inputEnterButton.setText(BUTTON_NAMES[selectionIndex]);
inputField.setEnabled(enabled);
inputEnterButton.setEnabled(enabled);
for(ActionListener removingListener : inputEnterButton.getActionListeners()){
inputEnterButton.removeActionListener(removingListener);
inputField.removeActionListener(removingListener);
}
if(listener != null){
inputEnterButton.addActionListener(listener);
inputField.addActionListener(listener);
}
});
add(pane, BorderLayout.CENTER);
add(inputPanel, BorderLayout.SOUTH);
inputEnterButton.addActionListener(evaluateListener);
inputField.addActionListener(evaluateListener);
2017-07-26 14:48:43 -07:00
historyTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
Point clickPoint = e.getPoint();
if(e.getClickCount() == 2){
int row = historyTable.rowAtPoint(clickPoint);
int column = historyTable.columnAtPoint(clickPoint);
String toCopy = historyTable.getValueAt(row, column).toString();
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(toCopy), null);
}
}
});
2017-07-25 14:52:57 -07:00
}
}