mirror of
https://github.com/DanilaFe/abacus
synced 2026-01-25 16:15:19 +00:00
Compare commits
15 Commits
inv-trig-d
...
gradle-mod
| Author | SHA1 | Date | |
|---|---|---|---|
| d861444d13 | |||
| eac2a9ed6b | |||
| 31c61fdf95 | |||
| 8f251d2d13 | |||
| 99ffd51a43 | |||
| 00c51c62fd | |||
| 400ed6e70a | |||
| 2e0b1201a3 | |||
|
|
1e6cf08ec2 | ||
|
|
fee9f091fd | ||
|
|
4226df72f5 | ||
|
|
1f0e6a7ce4 | ||
|
|
efe76a6fdc | ||
|
|
ca6d8d2ba2 | ||
|
|
1d6957c4d9 |
25
build.gradle
25
build.gradle
@@ -1,20 +1,13 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'application'
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.1.3'
|
||||
}
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'application'
|
||||
subprojects {
|
||||
|
||||
repositories {
|
||||
apply plugin: 'java'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.3"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.moandjiezana.toml:toml4j:0.7.1'
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8"
|
||||
testCompile 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
mainClassName = 'org.nwapw.abacus.Abacus'
|
||||
|
||||
|
||||
8
core/build.gradle
Normal file
8
core/build.gradle
Normal file
@@ -0,0 +1,8 @@
|
||||
plugins {
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.1.3'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.moandjiezana.toml:toml4j:0.7.1'
|
||||
testCompile 'junit:junit:4.12'
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.nwapw.abacus;
|
||||
|
||||
import org.nwapw.abacus.config.Configuration;
|
||||
import org.nwapw.abacus.fx.AbacusApplication;
|
||||
import org.nwapw.abacus.number.NumberInterface;
|
||||
import org.nwapw.abacus.parsing.LexerTokenizer;
|
||||
import org.nwapw.abacus.parsing.ShuntingYardParser;
|
||||
@@ -61,10 +60,6 @@ public class Abacus {
|
||||
pluginManager.addListener(lexerTokenizer);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
AbacusApplication.launch(AbacusApplication.class, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current tree builder.
|
||||
*
|
||||
@@ -519,6 +519,144 @@ public class StandardPlugin extends Plugin {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The arcsine function (return type in radians).
|
||||
*/
|
||||
public final Function functionArcsin = new Function() {
|
||||
@Override
|
||||
protected boolean matchesParams(NumberInterface[] params) {
|
||||
return params.length == 1
|
||||
&& FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) <= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||
if(FUNCTION_ABS.apply(params[0]).compareTo(new NaiveNumber(0.8).promoteTo(params[0].getClass())) >= 0){
|
||||
NumberInterface[] newParams = {FUNCTION_SQRT.apply(fromInt(params[0].getClass(), 1).subtract(params[0].multiply(params[0])))};
|
||||
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2))
|
||||
.subtract(applyInternal(newParams)).multiply(fromInt(params[0].getClass(), params[0].signum()));
|
||||
}
|
||||
NumberInterface currentTerm = params[0], sum = currentTerm,
|
||||
multiplier = currentTerm.multiply(currentTerm), summandBound = sum.getMaxError().multiply(fromInt(sum.getClass(), 1).subtract(multiplier)),
|
||||
power = currentTerm, coefficient = fromInt(params[0].getClass(), 1);
|
||||
int exponent = 1;
|
||||
while(FUNCTION_ABS.apply(currentTerm).compareTo(summandBound) > 0){
|
||||
exponent += 2;
|
||||
power = power.multiply(multiplier);
|
||||
coefficient = coefficient.multiply(fromInt(params[0].getClass(), exponent-2))
|
||||
.divide(fromInt(params[0].getClass(), exponent - 1));
|
||||
currentTerm = power.multiply(coefficient).divide(fromInt(power.getClass(), exponent));
|
||||
sum = sum.add(currentTerm);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The arccosine function.
|
||||
*/
|
||||
public final Function functionArccos = new Function() {
|
||||
@Override
|
||||
protected boolean matchesParams(NumberInterface[] params) {
|
||||
return params.length == 1 && FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) <= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2))
|
||||
.subtract(functionArcsin.apply(params));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The arccosecant function.
|
||||
*/
|
||||
public final Function functionArccsc = new Function() {
|
||||
@Override
|
||||
protected boolean matchesParams(NumberInterface[] params) {
|
||||
return params.length == 1 && FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||
NumberInterface[] reciprocalParamArr = {fromInt(params[0].getClass(), 1).divide(params[0])};
|
||||
return functionArcsin.apply(reciprocalParamArr);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The arcsecant function.
|
||||
*/
|
||||
public final Function functionArcsec = new Function() {
|
||||
@Override
|
||||
protected boolean matchesParams(NumberInterface[] params) {
|
||||
return params.length == 1 && FUNCTION_ABS.apply(params[0]).compareTo(fromInt(params[0].getClass(), 1)) >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||
NumberInterface[] reciprocalParamArr = {fromInt(params[0].getClass(), 1).divide(params[0])};
|
||||
return functionArccos.apply(reciprocalParamArr);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The arctangent function.
|
||||
*/
|
||||
public final Function functionArctan = new Function() {
|
||||
@Override
|
||||
protected boolean matchesParams(NumberInterface[] params) {
|
||||
return params.length == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||
if(params[0].signum() == -1){
|
||||
NumberInterface[] negatedParams = {params[0].negate()};
|
||||
return applyInternal(negatedParams).negate();
|
||||
}
|
||||
if(params[0].compareTo(fromInt(params[0].getClass(), 1)) > 0){
|
||||
NumberInterface[] reciprocalParams = {fromInt(params[0].getClass(), 1).divide(params[0])};
|
||||
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2))
|
||||
.subtract(applyInternal(reciprocalParams));
|
||||
}
|
||||
if(params[0].compareTo(fromInt(params[0].getClass(), 1)) == 0){
|
||||
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 4));
|
||||
}
|
||||
if(params[0].compareTo(new NaiveNumber(0.9).promoteTo(params[0].getClass())) >= 0){
|
||||
NumberInterface[] newParams = {params[0].multiply(fromInt(params[0].getClass(),2 ))
|
||||
.divide(fromInt(params[0].getClass(), 1).subtract(params[0].multiply(params[0])))};
|
||||
return applyInternal(newParams).divide(fromInt(params[0].getClass(), 2));
|
||||
}
|
||||
NumberInterface currentPower = params[0], currentTerm = currentPower, sum = currentTerm,
|
||||
maxError = params[0].getMaxError(), multiplier = currentPower.multiply(currentPower).negate();
|
||||
int n = 1;
|
||||
while(FUNCTION_ABS.apply(currentTerm).compareTo(maxError) > 0){
|
||||
n += 2;
|
||||
currentPower = currentPower.multiply(multiplier);
|
||||
currentTerm = currentPower.divide(fromInt(currentPower.getClass(), n));
|
||||
sum = sum.add(currentTerm);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The arccotangent function. Range: (0, pi).
|
||||
*/
|
||||
public final Function functionArccot = new Function() {
|
||||
@Override
|
||||
protected boolean matchesParams(NumberInterface[] params) {
|
||||
return params.length == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NumberInterface applyInternal(NumberInterface[] params) {
|
||||
return piFor(params[0].getClass()).divide(fromInt(params[0].getClass(), 2))
|
||||
.subtract(functionArctan.apply(params));
|
||||
}
|
||||
};
|
||||
|
||||
public StandardPlugin(PluginManager manager) {
|
||||
super(manager);
|
||||
}
|
||||
@@ -633,6 +771,7 @@ public class StandardPlugin extends Plugin {
|
||||
registerFunction("exp", FUNCTION_EXP);
|
||||
registerFunction("ln", FUNCTION_LN);
|
||||
registerFunction("sqrt", FUNCTION_SQRT);
|
||||
|
||||
registerFunction("sin", functionSin);
|
||||
registerFunction("cos", functionCos);
|
||||
registerFunction("tan", functionTan);
|
||||
@@ -640,6 +779,13 @@ public class StandardPlugin extends Plugin {
|
||||
registerFunction("csc", functionCsc);
|
||||
registerFunction("cot", functionCot);
|
||||
|
||||
registerFunction("arcsin", functionArcsin);
|
||||
registerFunction("arccos", functionArccos);
|
||||
registerFunction("arctan", functionArctan);
|
||||
registerFunction("arcsec", functionArcsec);
|
||||
registerFunction("arccsc", functionArccsc);
|
||||
registerFunction("arccot", functionArccot);
|
||||
|
||||
registerFunction("random_int", FUNCTION_RAND_INT);
|
||||
|
||||
registerDocumentation(new Documentation("abs", "Absolute Value", "Finds the distance " +
|
||||
10
fx/build.gradle
Normal file
10
fx/build.gradle
Normal file
@@ -0,0 +1,10 @@
|
||||
plugins {
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.1.3'
|
||||
}
|
||||
apply plugin: 'application'
|
||||
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
}
|
||||
|
||||
mainClassName = 'org.nwapw.abacus.fx.AbacusApplication'
|
||||
@@ -33,4 +33,9 @@ public class AbacusApplication extends Application {
|
||||
super.stop();
|
||||
controller.performStop();
|
||||
}
|
||||
|
||||
public static void main(String[] args){
|
||||
launch(args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
rootProject.name = 'abacus'
|
||||
include 'core', 'fx'
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
package org.nwapw.abacus.window;
|
||||
|
||||
import org.nwapw.abacus.tree.TreeNode;
|
||||
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A table model to store data about the history of inputs
|
||||
* in the calculator.
|
||||
*/
|
||||
public class HistoryTableModel extends AbstractTableModel {
|
||||
|
||||
/**
|
||||
* Static array used to get the column names.
|
||||
*/
|
||||
public static final String[] COLUMN_NAMES = {
|
||||
"Input",
|
||||
"Parsed Input",
|
||||
"Output"
|
||||
};
|
||||
|
||||
/**
|
||||
* Static array used to get the class of each column.
|
||||
*/
|
||||
public static final Class[] CLASS_TYPES = {
|
||||
String.class,
|
||||
TreeNode.class,
|
||||
String.class
|
||||
};
|
||||
/**
|
||||
* The list of entries.
|
||||
*/
|
||||
List<HistoryEntry> entries;
|
||||
|
||||
/**
|
||||
* Creates a new empty history table model
|
||||
*/
|
||||
public HistoryTableModel() {
|
||||
entries = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an entry to the model.
|
||||
*
|
||||
* @param entry the entry to add.
|
||||
*/
|
||||
public void addEntry(HistoryEntry entry) {
|
||||
entries.add(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return entries.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int columnIndex) {
|
||||
return COLUMN_NAMES[columnIndex];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getColumnClass(int columnIndex) {
|
||||
return CLASS_TYPES[columnIndex];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
return entries.get(rowIndex).nthValue(columnIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class used specifically to hold data about
|
||||
* the previous entries into the calculator.
|
||||
*/
|
||||
public static class HistoryEntry {
|
||||
public String input;
|
||||
public TreeNode parsedInput;
|
||||
public String output;
|
||||
|
||||
public HistoryEntry(String input, TreeNode parsedInput, String output) {
|
||||
this.input = input;
|
||||
this.parsedInput = parsedInput;
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
Object nthValue(int n) {
|
||||
if (n == 0) return input;
|
||||
if (n == 1) return parsedInput;
|
||||
if (n == 2) return output;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,255 +0,0 @@
|
||||
package org.nwapw.abacus.window;
|
||||
|
||||
import org.nwapw.abacus.Abacus;
|
||||
import org.nwapw.abacus.number.NumberInterface;
|
||||
import org.nwapw.abacus.tree.TreeNode;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
/**
|
||||
* The main UI window for the calculator.
|
||||
*/
|
||||
public class Window extends JFrame {
|
||||
|
||||
private static final String CALC_STRING = "Calculate";
|
||||
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:";
|
||||
|
||||
/**
|
||||
* Array of Strings to which the "calculate" button's text
|
||||
* changes. For instance, in the graph tab, the name will
|
||||
* be "Graph" and not "Calculate".
|
||||
*/
|
||||
private static final String[] BUTTON_NAMES = {
|
||||
CALC_STRING,
|
||||
CALC_STRING
|
||||
};
|
||||
|
||||
/**
|
||||
* Array of booleans that determine whether the input
|
||||
* field and the input button are enabled at a particular
|
||||
* index.
|
||||
*/
|
||||
private static boolean[] INPUT_ENABLED = {
|
||||
true,
|
||||
false
|
||||
};
|
||||
|
||||
/**
|
||||
* The instance of the Abacus class, used
|
||||
* for interaction with plugins and configuration.
|
||||
*/
|
||||
private Abacus abacus;
|
||||
/**
|
||||
* The last output by the calculator.
|
||||
*/
|
||||
private String lastOutput;
|
||||
|
||||
/**
|
||||
* The tabbed pane that separates calculator contexts.
|
||||
*/
|
||||
private JTabbedPane pane;
|
||||
|
||||
/**
|
||||
* The panel where the output occurs.
|
||||
*/
|
||||
private JPanel calculationPanel;
|
||||
/**
|
||||
* The text area reserved for the last output.
|
||||
*/
|
||||
private JTextArea lastOutputArea;
|
||||
/**
|
||||
* The table used for storing history results.
|
||||
*/
|
||||
private JTable historyTable;
|
||||
/**
|
||||
* The table model used for managing history.
|
||||
*/
|
||||
private HistoryTableModel historyModel;
|
||||
/**
|
||||
* The scroll pane for the history area.
|
||||
*/
|
||||
private JScrollPane historyScroll;
|
||||
|
||||
/**
|
||||
* The panel where the input occurs.
|
||||
*/
|
||||
private JPanel inputPanel;
|
||||
/**
|
||||
* The input text field.
|
||||
*/
|
||||
private JTextField inputField;
|
||||
/**
|
||||
* The "submit" button.
|
||||
*/
|
||||
private JButton inputEnterButton;
|
||||
|
||||
/**
|
||||
* The side panel for separate configuration.
|
||||
*/
|
||||
private JPanel settingsPanel;
|
||||
/**
|
||||
* Panel for elements relating to number
|
||||
* system selection.
|
||||
*/
|
||||
private JPanel numberSystemPanel;
|
||||
/**
|
||||
* The possible list of number systems.
|
||||
*/
|
||||
private JComboBox<String> numberSystemList;
|
||||
/**
|
||||
* The panel for elements relating to
|
||||
* function selection.
|
||||
*/
|
||||
private JPanel functionSelectPanel;
|
||||
/**
|
||||
* The list of functions available to the user.
|
||||
*/
|
||||
private JComboBox<String> functionList;
|
||||
|
||||
/**
|
||||
* Action listener that causes the input to be evaluated.
|
||||
*/
|
||||
private ActionListener evaluateListener = (event) -> {
|
||||
TreeNode parsedExpression = abacus.parseString(inputField.getText());
|
||||
if (parsedExpression == null) {
|
||||
lastOutputArea.setText(SYNTAX_ERR_STRING);
|
||||
return;
|
||||
}
|
||||
NumberInterface numberInterface = abacus.evaluateTree(parsedExpression);
|
||||
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("");
|
||||
};
|
||||
|
||||
/**
|
||||
* Array of listeners that tell the input button how to behave
|
||||
* at a given input tab.
|
||||
*/
|
||||
private ActionListener[] listeners = {
|
||||
evaluateListener,
|
||||
null
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new window with the given manager.
|
||||
*
|
||||
* @param abacus the calculator instance to interact with other components.
|
||||
*/
|
||||
public Window(Abacus abacus) {
|
||||
this();
|
||||
this.abacus = abacus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new window.
|
||||
*/
|
||||
private Window() {
|
||||
super();
|
||||
|
||||
lastOutput = "";
|
||||
|
||||
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
setSize(320, 480);
|
||||
|
||||
inputField = new JTextField();
|
||||
inputEnterButton = new JButton(CALC_STRING);
|
||||
|
||||
inputPanel = new JPanel();
|
||||
inputPanel.setLayout(new BorderLayout());
|
||||
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 = INPUT_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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean b) {
|
||||
super.setVisible(b);
|
||||
if (b) inputField.requestFocusInWindow();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user