Add src/main/java/dev/sillyangel/calc/utils/Utils.java
Some checks failed
Build the Jar / build (push) Failing after 13s
Some checks failed
Build the Jar / build (push) Failing after 13s
This commit is contained in:
254
src/main/java/dev/sillyangel/calc/utils/Utils.java
Normal file
254
src/main/java/dev/sillyangel/calc/utils/Utils.java
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
package dev.sillyangel.calc.utils;
|
||||||
|
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import java.awt.datatransfer.Clipboard;
|
||||||
|
import java.awt.datatransfer.DataFlavor;
|
||||||
|
import java.awt.datatransfer.StringSelection;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.FlowLayout;
|
||||||
|
import java.awt.Font;
|
||||||
|
import dev.sillyangel.calc.Calculator;
|
||||||
|
|
||||||
|
public class Utils {
|
||||||
|
// private double result;
|
||||||
|
// private boolean resultVisible;
|
||||||
|
private Calculator ci;
|
||||||
|
public Utils(Calculator ci) {
|
||||||
|
System.out.printf("");
|
||||||
|
this.ci = ci;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reciprocal() {
|
||||||
|
String tmp = ci.display.getText();
|
||||||
|
if (tmp == null || tmp.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
double value = Double.parseDouble(tmp);
|
||||||
|
if (value != 0) {
|
||||||
|
ci.result = 1.0 / value;
|
||||||
|
ci.display.setText("" + ci.result);
|
||||||
|
ci.resultVisible = true;
|
||||||
|
} else {
|
||||||
|
ci.display.setText("Error: Div by Zero");
|
||||||
|
ci.resultVisible = false;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
ci.display.setText("Error: Invalid Input");
|
||||||
|
ci.resultVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearAll() {
|
||||||
|
ci.display.setText("");
|
||||||
|
ci.operand1 = "";
|
||||||
|
ci.operand2 = "";
|
||||||
|
ci.operator = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void square() {
|
||||||
|
String tmp = ci.display.getText();
|
||||||
|
if (tmp == null || tmp.isEmpty()) return;
|
||||||
|
double value = Double.parseDouble(tmp);
|
||||||
|
ci.result = value * value;
|
||||||
|
ci.display.setText("" + ci.result);
|
||||||
|
ci.resultVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void squareRoot() {
|
||||||
|
String tmp = ci.display.getText();
|
||||||
|
if (tmp == null || tmp.isEmpty()) return;
|
||||||
|
double value = Double.parseDouble(tmp);
|
||||||
|
if (value >= 0) {
|
||||||
|
ci.result = Math.sqrt(value);
|
||||||
|
ci.display.setText("" + ci.result);
|
||||||
|
ci.resultVisible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void backspace() {
|
||||||
|
String tmp = ci.display.getText();
|
||||||
|
if (tmp.length()>1) // if there is more than 1 character
|
||||||
|
ci.display.setText( tmp.substring(0, tmp.length()-1) );
|
||||||
|
else // otherwise just make display empty
|
||||||
|
ci.display.setText("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void math() {
|
||||||
|
ci.operand2 = ci.display.getText();
|
||||||
|
double op1 = Double.parseDouble(ci.operand1);
|
||||||
|
double op2 = Double.parseDouble(ci.operand2);
|
||||||
|
|
||||||
|
if ("+".equals(ci.operator)) {
|
||||||
|
ci.result = op1+op2;
|
||||||
|
} else if ("-".equals(ci.operator)) {
|
||||||
|
ci.result = op1-op2;
|
||||||
|
} else if ("*".equals(ci.operator)) {
|
||||||
|
ci.result = op1*op2;
|
||||||
|
} else if ("/".equals(ci.operator)) {
|
||||||
|
ci.result = op1/op2;
|
||||||
|
} else if ("%".equals(ci.operator)) {
|
||||||
|
ci.result = op1 % op2;
|
||||||
|
} else {
|
||||||
|
ci.result = op2;
|
||||||
|
System.out.println("Op: " + op1);
|
||||||
|
System.out.println("Op2: " + op2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save calculation to history
|
||||||
|
if (!ci.operator.isEmpty()) {
|
||||||
|
String calculation = ci.operand1 + " " + ci.operator + " " + ci.operand2 + " = " + ci.result;
|
||||||
|
ci.history.saveToHistory(calculation);
|
||||||
|
}
|
||||||
|
|
||||||
|
ci.operator = "";
|
||||||
|
ci.operand1 = "";
|
||||||
|
ci.operand2 = "";
|
||||||
|
|
||||||
|
ci.resultVisible = true;
|
||||||
|
ci.display.setText(""+ci.result);
|
||||||
|
saveToUndoStack(""+ci.result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveToUndoStack(String value) {
|
||||||
|
// Remove any states after current index (if user undid and then made a new action)
|
||||||
|
if (ci.undoIndex < ci.undoStack.size() - 1) {
|
||||||
|
ci.undoStack.subList(ci.undoIndex + 1, ci.undoStack.size()).clear();
|
||||||
|
}
|
||||||
|
ci.undoStack.add(value);
|
||||||
|
ci.undoIndex = ci.undoStack.size() - 1;
|
||||||
|
}
|
||||||
|
public void undoAction() {
|
||||||
|
if (ci.undoIndex > 0) {
|
||||||
|
ci.undoIndex--;
|
||||||
|
ci.display.setText(ci.undoStack.get(ci.undoIndex));
|
||||||
|
} else {
|
||||||
|
System.out.println("Nothing to undo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void redoAction() {
|
||||||
|
if (ci.undoIndex < ci.undoStack.size() - 1) {
|
||||||
|
ci.undoIndex++;
|
||||||
|
ci.display.setText(ci.undoStack.get(ci.undoIndex));
|
||||||
|
} else {
|
||||||
|
System.out.println("Nothing to redo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clipboard operations
|
||||||
|
public void cutAction() {
|
||||||
|
copyAction();
|
||||||
|
ci.display.setText("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void copyAction() {
|
||||||
|
String text = ci.display.getText();
|
||||||
|
if (text != null && !text.isEmpty()) {
|
||||||
|
StringSelection selection = new StringSelection(text);
|
||||||
|
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
clipboard.setContents(selection, null);
|
||||||
|
System.out.println("Copied: " + text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pasteAction() {
|
||||||
|
try {
|
||||||
|
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
String text = (String) clipboard.getData(DataFlavor.stringFlavor);
|
||||||
|
if (text != null && !text.isEmpty()) {
|
||||||
|
// Validate that pasted content is a valid number
|
||||||
|
try {
|
||||||
|
Double.parseDouble(text);
|
||||||
|
ci.display.setText(text);
|
||||||
|
saveToUndoStack(text);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
JOptionPane.showMessageDialog(ci,
|
||||||
|
"Pasted content is not a valid number",
|
||||||
|
"Invalid Input", JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
System.err.println("Error pasting: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void processDigit(String actionCommand) {
|
||||||
|
if (ci.resultVisible) {
|
||||||
|
ci.display.setText("");
|
||||||
|
ci.resultVisible = false;
|
||||||
|
}
|
||||||
|
String newValue = ci.display.getText() + actionCommand;
|
||||||
|
ci.display.setText(newValue);
|
||||||
|
saveToUndoStack(newValue);
|
||||||
|
}
|
||||||
|
public void setOperator(String daop) {
|
||||||
|
ci.operand1 = ci.display.getText();
|
||||||
|
ci.operator = daop;
|
||||||
|
ci.display.setText("");
|
||||||
|
}
|
||||||
|
public void clearEntry() {
|
||||||
|
ci.display.setText("");
|
||||||
|
}
|
||||||
|
public void showHistoryDialog() {
|
||||||
|
JDialog historyDialog = new JDialog(this.ci, "Calculation History", true);
|
||||||
|
historyDialog.setSize(500, 400);
|
||||||
|
historyDialog.setLocationRelativeTo(this.ci);
|
||||||
|
historyDialog.setLayout(new BorderLayout(10, 10));
|
||||||
|
|
||||||
|
List<String> historyList = ci.history.getCalculationHistory();
|
||||||
|
|
||||||
|
if (historyList.isEmpty()) {
|
||||||
|
JLabel emptyLabel = new JLabel("No calculation history yet", SwingConstants.CENTER);
|
||||||
|
emptyLabel.setFont(new Font("Segoe UI", Font.PLAIN, 14));
|
||||||
|
historyDialog.add(emptyLabel, BorderLayout.CENTER);
|
||||||
|
} else {
|
||||||
|
JTextArea historyTextArea = new JTextArea();
|
||||||
|
historyTextArea.setEditable(false);
|
||||||
|
historyTextArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
|
||||||
|
|
||||||
|
StringBuilder historyText = new StringBuilder();
|
||||||
|
for (String entry : historyList) {
|
||||||
|
historyText.append(entry).append("\n");
|
||||||
|
}
|
||||||
|
historyTextArea.setText(historyText.toString());
|
||||||
|
|
||||||
|
JScrollPane scrollPane = new JScrollPane(historyTextArea);
|
||||||
|
historyDialog.add(scrollPane, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// Status label
|
||||||
|
JLabel statusLabel = new JLabel("Total calculations: " + historyList.size());
|
||||||
|
statusLabel.setBorder(new EmptyBorder(5, 10, 5, 10));
|
||||||
|
historyDialog.add(statusLabel, BorderLayout.NORTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
||||||
|
JButton closeButton = new JButton("Close");
|
||||||
|
closeButton.addActionListener(e -> historyDialog.dispose());
|
||||||
|
buttonPanel.add(closeButton);
|
||||||
|
|
||||||
|
historyDialog.add(buttonPanel, BorderLayout.SOUTH);
|
||||||
|
historyDialog.setVisible(true);
|
||||||
|
}
|
||||||
|
public void clearHistoryAction() {
|
||||||
|
int result = JOptionPane.showConfirmDialog(this.ci,
|
||||||
|
"Are you sure you want to clear all calculation history?",
|
||||||
|
"Clear History", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
|
||||||
|
|
||||||
|
if (result == JOptionPane.YES_OPTION) {
|
||||||
|
ci.history.clearHistory();
|
||||||
|
JOptionPane.showMessageDialog(this.ci,
|
||||||
|
"History cleared successfully",
|
||||||
|
"Success", JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user