Compare commits

3 Commits

Author SHA1 Message Date
f15534c4d5 fix
All checks were successful
Build the Jar / build (push) Successful in 12s
2025-12-22 09:53:31 -06:00
fdbcb56b1b fix 2025-12-22 09:46:16 -06:00
b9c4c6f3e7 fix 2025-12-22 09:24:35 -06:00
7 changed files with 367 additions and 279 deletions

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Ask2AgentMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>

View File

@@ -2,9 +2,12 @@
<library name="lib"> <library name="lib">
<CLASSES> <CLASSES>
<root url="jar://$PROJECT_DIR$/lib/flatlaf-3.7.jar!/" /> <root url="jar://$PROJECT_DIR$/lib/flatlaf-3.7.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/flatlaf-3.7-javadoc.jar!/" /> <root url="jar://$PROJECT_DIR$/lib/flatlaf-extras-3.7.jar!/" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES /> <SOURCES>
<root url="jar://$PROJECT_DIR$/lib/flatlaf-extras-3.7-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/flatlaf-3.7-sources.jar!/" />
</SOURCES>
</library> </library>
</component> </component>

View File

@@ -4,6 +4,8 @@ package dev.sillyangel.calc;
// java to javax, com, dev // java to javax, com, dev
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.awt.datatransfer.*;
import java.io.Serial;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.io.IOException; import java.io.IOException;
@@ -16,6 +18,7 @@ import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment; import javax.swing.GroupLayout.Alignment;
import javax.swing.*; import javax.swing.*;
import com.formdev.flatlaf.FlatDarculaLaf; import com.formdev.flatlaf.FlatDarculaLaf;
import com.formdev.flatlaf.themes.FlatMacDarkLaf;
import com.formdev.flatlaf.FlatIntelliJLaf; import com.formdev.flatlaf.FlatIntelliJLaf;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.FlatLaf;
@@ -25,37 +28,49 @@ import com.formdev.flatlaf.util.SystemInfo;
import dev.sillyangel.calc.themes.*; import dev.sillyangel.calc.themes.*;
public class Calculator extends JFrame implements KeyListener { public class Calculator extends JFrame implements KeyListener {
private static final String PREF_NODE_NAME = "dev/sillyangel/calc"; @Serial
private static boolean
private static int
public static final Preferences prefs = Preferences.userRoot().node(PREF_NODE_NAME);
public static String APPILCATION_VERSION = "1.0.0pre";
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final String PREF_NODE_NAME = "dev/sillyangel/calc";
private static final String PREF_THEME = "theme";
private static final String PREF_FONT_SIZE = "fontSize";
private static final String PREF_ALWAYS_ON_TOP = "alwaysOnTop";
public static final Preferences prefs = Preferences.userRoot().node(PREF_NODE_NAME);
public static String APPLICATION_VERSION = "1.0.0pre";
private JPanel contentPane; private JPanel contentPane;
private JTextField display; private JTextField display;
private String operand1; private String operand1;
private String operator; private String operator;
private String operand2; private String operand2;
private JButton btnDiv;
private JButton btnMul;
private JButton btnMin;
private JButton btnPlus;
protected boolean resultVisible; protected boolean resultVisible;
protected double result; protected double result;
private String[] Modes = new String[] {"Standard", "Scientific", "Data calculation"}; private JComboBox<String> modeselect;
private JComboBox<String> modeselect;
private final CalculatorHistory history; private final CalculatorHistory history;
private final List<String> undoStack = new ArrayList<>();
private int undoIndex = -1;
public static final String getVersion() { public static String getVersion() {
return APPILCATION_VERSION; return APPLICATION_VERSION;
} }
public static void main(String[] args) { public static void main(String[] args) {
// IntelliJTheme.setup(Calculator.class.getResourceAsStream("/DarkPurple.theme.json")); // Load saved theme preference
// FlatMacDarkLaf.setup(); String savedTheme = prefs.get(PREF_THEME, "MacDarkBlue");
// MacDarkRed.setup();
MacDarkBlue.setup(); // Apply saved theme on startup
try {
switch (savedTheme) {
case "MacDarkBlue" -> MacDarkBlue.setup();
case "MacDarkRed" -> MacDarkRed.setup();
case "MacLightBlue" -> MacLightBlue.setup();
case "MacLightRed" -> MacLightRed.setup();
case "Default" -> FlatMacDarkLaf.setup();
default -> FlatMacDarkLaf.setup();
}
} catch (Exception e) {
FlatMacDarkLaf.setup();
}
System.out.println("\nangel's awesome calculator (acc) " + Calculator.getVersion()); System.out.println("\nangel's awesome calculator (acc) " + Calculator.getVersion());
System.out.println("created by angel"); System.out.println("created by angel");
System.out.println("---------------------------------"); System.out.println("---------------------------------");
@@ -67,12 +82,6 @@ public class Calculator extends JFrame implements KeyListener {
if( SystemInfo.isLinux ) { // why is linux different if( SystemInfo.isLinux ) { // why is linux different
JFrame.setDefaultLookAndFeelDecorated(true); JFrame.setDefaultLookAndFeelDecorated(true);
} }
try {
// UIManager.setLookAndFeel("com.formdev.flatlaf.themes.FlatMacDarkLaf");
UIManager.put("defaultFont", new Font("Segoe UI", Font.PLAIN, 29));
} catch (Throwable e) {
e.printStackTrace();
}
EventQueue.invokeLater(new Runnable() { EventQueue.invokeLater(new Runnable() {
public void run() { public void run() {
try { try {
@@ -203,8 +212,9 @@ public class Calculator extends JFrame implements KeyListener {
menubar.add(edit); menubar.add(edit);
menubar.add(help); menubar.add(help);
setJMenuBar(menubar); setJMenuBar(menubar);
modeselect = new JComboBox<>(Modes); String[] modes = new String[]{"Standard", "Scientific", "Data calculation"};
modeselect = new JComboBox<>(modes);
modeselect.addActionListener(new ActionListener() { modeselect.addActionListener(new ActionListener() {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
@@ -252,249 +262,193 @@ public class Calculator extends JFrame implements KeyListener {
JButton btn8 = new JButton("8"); JButton btn8 = new JButton("8");
JButton btn9 = new JButton("9"); JButton btn9 = new JButton("9");
btnDiv = new JButton("/"); JButton btnDiv = new JButton("/");
btnMul = new JButton("*"); JButton btnMul = new JButton("*");
btnMin = new JButton("-"); JButton btnMin = new JButton("-");
btnPlus = new JButton("+"); JButton btnPlus = new JButton("+");
btnDot.addActionListener(new ActionListener() { btnDot.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
String n = display.getText(); // get the text on the display String n = display.getText();
if (n.contains(".")) return; // if it already contains a "." skip rest of this if (n.contains(".")) return;
processDigit(e.getActionCommand());
}
});
btnEq.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
math();
}
});
btnBackspace.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
backspace();
}
});
btnClearEntry.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
clearEntry();
}
});
btnClear.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
clearAll();
}
});
btnPlus.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setOperator(e.getActionCommand());
}
});
btnDiv.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setOperator(e.getActionCommand());
}
});
btnMul.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setOperator(e.getActionCommand());
}
});
btnMin.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setOperator(e.getActionCommand());
}
});
btn0.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
processDigit(e.getActionCommand());
}
});
btn1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
processDigit(e.getActionCommand());
}
});
btn2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
processDigit(e.getActionCommand());
}
});
btn3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
processDigit(e.getActionCommand());
}
});
btn4.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
processDigit(e.getActionCommand());
}
});
btn5.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
processDigit(e.getActionCommand());
}
});
btn6.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
processDigit(e.getActionCommand());
}
});
btn7.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
processDigit(e.getActionCommand());
}
});
btn8.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
processDigit(e.getActionCommand());
}
});
btn9.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
processDigit(e.getActionCommand()); processDigit(e.getActionCommand());
} }
}); });
btnPlusMin.addActionListener(new ActionListener() { btnPlusMin.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String tmp = display.getText();
if (tmp == null || tmp.isEmpty()) return;
char first = tmp.charAt(0);
if (first == '-') {
tmp = tmp.substring(1, tmp.length());
display.setText(tmp);
} else {
display.setText("-" + tmp);
}
}
});
btnPercent.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
setOperator("%"); String tmp = display.getText();
if (tmp == null || tmp.isEmpty()) return;
char first = tmp.charAt(0);
if (first == '-') {
tmp = tmp.substring(1);
display.setText(tmp);
} else {
display.setText("-" + tmp);
}
} }
}); });
btnReciprocal.addActionListener(new ActionListener() { btnClear.addActionListener(e -> clearAll());
public void actionPerformed(ActionEvent e) { btnReciprocal.addActionListener(e -> reciprocal());
reciprocal(); btnSquare.addActionListener(e -> square());
} btnSquareRoot.addActionListener(e -> squareRoot());
}); btnEq.addActionListener(e -> math());
btnBackspace.addActionListener(e -> backspace());
btnClearEntry.addActionListener(e -> display.setText(""));
btnSquare.addActionListener(new ActionListener() { JButton[] buttons = {
public void actionPerformed(ActionEvent e) { btnPercent, btnClearEntry, btnClear, btnBackspace, btnReciprocal, btnSquare,
square(); btnSquareRoot, btnDiv, btn7, btn8, btn9, btnMul, btn4, btn5, btn6, btnMin,
} btn1, btn2, btn3, btnPlus, btnPlusMin, btn0, btnDot, btnEq
}); };
JButton[] operatorButtons = {
btnSquareRoot.addActionListener(new ActionListener() { btnPlus, btnDiv, btnMul, btnMin, btnPercent
public void actionPerformed(ActionEvent e) { };
squareRoot(); JButton[] digitButtons = {
} btn0, btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8,
}); btn9
};
// Add action listeners to each digit button to process the number input
for (JButton button : digitButtons)
// btnBackspace.setFont(new Font("Segoe UI", Font.PLAIN, 29)); button.addActionListener(e -> processDigit(e.getActionCommand()));
// btnClear.setFont(new Font("Segoe UI", Font.PLAIN, 29)); // Add action listeners to each operator to process what operator button has been clicked
// btnClearEntry.setFont(new Font("Segoe UI", Font.PLAIN, 29)); for (JButton button : operatorButtons)
// btnPlusMin.setFont(new Font("Segoe UI", Font.PLAIN, 29)); button.addActionListener(e -> setOperator(e.getActionCommand()));
// btnEq.setFont(new Font("Segoe UI", Font.PLAIN, 29)); // add the buttons to the main display panel
// btnDot.setFont(new Font("Segoe UI", Font.PLAIN, 29)); for(JButton button: buttons) {
// btn0.setFont(new Font("Segoe UI", Font.PLAIN, 29)); button.setFocusable(false);
// btn1.setFont(new Font("Segoe UI", Font.PLAIN, 29)); button.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// btn2.setFont(new Font("Segoe UI", Font.PLAIN, 29)); buttonPanel.add(button);
// btn3.setFont(new Font("Segoe UI", Font.PLAIN, 29)); }
// btn4.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// btn5.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// btn6.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// btn7.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// btn8.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// btn9.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// btnMul.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// btnMin.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// btnDiv.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// btnPlus.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// btnPercent.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// btnReciprocal.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// btnSquare.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// btnSquareRoot.setFont(new Font("Segoe UI", Font.PLAIN, 29));
// Make all buttons non-focusable so keyboard input always goes to the frame because if we don't it breaks
btnBackspace.setFocusable(false);
btnClear.setFocusable(false);
btnClearEntry.setFocusable(false);
btnPlusMin.setFocusable(false);
btnEq.setFocusable(false);
btnDot.setFocusable(false);
btn0.setFocusable(false);
btn1.setFocusable(false);
btn2.setFocusable(false);
btn3.setFocusable(false);
btn4.setFocusable(false);
btn5.setFocusable(false);
btn6.setFocusable(false);
btn7.setFocusable(false);
btn8.setFocusable(false);
btn9.setFocusable(false);
btnMul.setFocusable(false);
btnMin.setFocusable(false);
btnDiv.setFocusable(false);
btnPlus.setFocusable(false);
btnPercent.setFocusable(false);
btnReciprocal.setFocusable(false);
btnSquare.setFocusable(false);
btnSquareRoot.setFocusable(false);
buttonPanel.add(btnPercent);
buttonPanel.add(btnClearEntry);
buttonPanel.add(btnClear);
buttonPanel.add(btnBackspace);
buttonPanel.add(btnReciprocal);
buttonPanel.add(btnSquare);
buttonPanel.add(btnSquareRoot);
buttonPanel.add(btnDiv);
buttonPanel.add(btn7);
buttonPanel.add(btn8);
buttonPanel.add(btn9);
buttonPanel.add(btnMul);
buttonPanel.add(btn4);
buttonPanel.add(btn5);
buttonPanel.add(btn6);
buttonPanel.add(btnMin);
buttonPanel.add(btn1);
buttonPanel.add(btn2);
buttonPanel.add(btn3);
buttonPanel.add(btnPlus);
buttonPanel.add(btnPlusMin);
buttonPanel.add(btn0);
buttonPanel.add(btnDot);
buttonPanel.add(btnEq);
contentPane.setLayout(gl_contentPane); contentPane.setLayout(gl_contentPane);
} }
// Undo/Redo functionality
private void saveToUndoStack(String value) {
// Remove any states after current index (if user undid and then made a new action)
if (undoIndex < undoStack.size() - 1) {
undoStack.subList(undoIndex + 1, undoStack.size()).clear();
}
undoStack.add(value);
undoIndex = undoStack.size() - 1;
}
private void undoAction() {
if (undoIndex > 0) {
undoIndex--;
display.setText(undoStack.get(undoIndex));
} else {
System.out.println("Nothing to undo");
}
}
private void redoAction() {
if (undoIndex < undoStack.size() - 1) {
undoIndex++;
display.setText(undoStack.get(undoIndex));
} else {
System.out.println("Nothing to redo");
}
}
// Clipboard operations
private void cutAction() {
copyAction();
display.setText("");
}
private void copyAction() {
String text = 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);
}
}
private 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);
display.setText(text);
saveToUndoStack(text);
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(this,
"Pasted content is not a valid number",
"Invalid Input", JOptionPane.ERROR_MESSAGE);
}
}
} catch (Exception ex) {
System.err.println("Error pasting: " + ex.getMessage());
}
}
// History dialog
private void showHistoryDialog() {
JDialog historyDialog = new JDialog(this, "Calculation History", true);
historyDialog.setSize(500, 400);
historyDialog.setLocationRelativeTo(this);
historyDialog.setLayout(new BorderLayout(10, 10));
List<String> historyList = 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);
}
private void clearHistoryAction() {
int result = JOptionPane.showConfirmDialog(this,
"Are you sure you want to clear all calculation history?",
"Clear History", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
history.clearHistory();
JOptionPane.showMessageDialog(this,
"History cleared successfully",
"Success", JOptionPane.INFORMATION_MESSAGE);
}
}
private void PreferencesAction() { private void PreferencesAction() {
JDialog dialog = new JDialog(this, "Preferences", true); JDialog dialog = new JDialog(this, "Preferences", true);
dialog.setSize(320, 220); dialog.setSize(400, 280);
dialog.setLocationRelativeTo(this); dialog.setLocationRelativeTo(this);
dialog.setLayout(new BorderLayout(10, 10)); dialog.setLayout(new BorderLayout(10, 10));
@@ -502,9 +456,31 @@ public class Calculator extends JFrame implements KeyListener {
panel.setBorder(new EmptyBorder(10, 10, 10, 10)); panel.setBorder(new EmptyBorder(10, 10, 10, 10));
panel.setLayout(new GridLayout(0, 2, 8, 8)); panel.setLayout(new GridLayout(0, 2, 8, 8));
// Theme selector // Color theme selector
JComboBox<String> themeBox = new JComboBox<>(new String[]{"Dark", "Light"}); JComboBox<String> colorThemeBox = new JComboBox<>(new String[]{
themeBox.setSelectedItem(prefs.get(PREF_THEME, "Dark")); "Default", "MacDarkBlue", "MacDarkRed", "MacLightBlue", "MacLightRed"
});
String savedTheme = prefs.get(PREF_THEME, "MacDarkBlue");
colorThemeBox.setSelectedItem(savedTheme);
// Light/Dark mode toggle
JComboBox<String> modeBox = new JComboBox<>(new String[]{"Dark", "Light"});
boolean isDark = isThemeDark(savedTheme);
modeBox.setSelectedItem(isDark ? "Dark" : "Light");
// Update color theme when mode changes
modeBox.addActionListener(e -> {
String currentTheme = (String) colorThemeBox.getSelectedItem();
String mode = (String) modeBox.getSelectedItem();
String counterpart = getThemeCounterpart(currentTheme, "Light".equals(mode));
colorThemeBox.setSelectedItem(counterpart);
});
// Update mode when color theme changes
colorThemeBox.addActionListener(e -> {
String theme = (String) colorThemeBox.getSelectedItem();
modeBox.setSelectedItem(isThemeDark(theme) ? "Dark" : "Light");
});
// Font size // Font size
JSpinner fontSizeSpinner = new JSpinner( JSpinner fontSizeSpinner = new JSpinner(
@@ -514,16 +490,19 @@ public class Calculator extends JFrame implements KeyListener {
) )
); );
// Always on top // Always on top
JCheckBox alwaysOnTopBox = new JCheckBox( JCheckBox alwaysOnTopBox = new JCheckBox(
"Always on top", "Always on top",
prefs.getBoolean(PREF_ALWAYS_ON_TOP, false) prefs.getBoolean(PREF_ALWAYS_ON_TOP, false)
); );
panel.add(new JLabel("Theme")); panel.add(new JLabel("Color Theme:"));
panel.add(themeBox); panel.add(colorThemeBox);
panel.add(new JLabel("Font size")); panel.add(new JLabel("Mode:"));
panel.add(modeBox);
panel.add(new JLabel("Font Size:"));
panel.add(fontSizeSpinner); panel.add(fontSizeSpinner);
panel.add(new JLabel("")); panel.add(new JLabel(""));
@@ -533,7 +512,7 @@ public class Calculator extends JFrame implements KeyListener {
JButton close = new JButton("Close"); JButton close = new JButton("Close");
apply.addActionListener(e -> { apply.addActionListener(e -> {
String theme = (String) themeBox.getSelectedItem(); String theme = (String) colorThemeBox.getSelectedItem();
int fontSize = (int) fontSizeSpinner.getValue(); int fontSize = (int) fontSizeSpinner.getValue();
boolean alwaysOnTop = alwaysOnTopBox.isSelected(); boolean alwaysOnTop = alwaysOnTopBox.isSelected();
@@ -560,11 +539,20 @@ public class Calculator extends JFrame implements KeyListener {
try { try {
FlatAnimatedLafChange.showSnapshot(); FlatAnimatedLafChange.showSnapshot();
if ("Light".equals(theme)) { switch (theme) {
FlatIntelliJLaf.setup(); case "Default" -> {
} else { if (FlatLaf.isLafDark()) {
FlatDarculaLaf.setup(); FlatDarculaLaf.setup();
} } else {
FlatIntelliJLaf.setup();
}
}
case "MacDarkBlue" -> MacDarkBlue.setup();
case "MacDarkRed" -> MacDarkRed.setup();
case "MacLightBlue" -> MacLightBlue.setup();
case "MacLightRed" -> MacLightRed.setup();
default -> FlatDarculaLaf.setup();
}
FlatLaf.updateUI(); FlatLaf.updateUI();
FlatAnimatedLafChange.hideSnapshotWithAnimation(); FlatAnimatedLafChange.hideSnapshotWithAnimation();
} catch (Exception ex) { } catch (Exception ex) {
@@ -606,13 +594,11 @@ public class Calculator extends JFrame implements KeyListener {
} }
private void UpdateMode(String Mode) { private void UpdateMode(String Mode) {
if (Mode == "Standard") { if ("Standard".equals(Mode)) {
System.out.println("User has Selected Standard"); System.out.println("User has Selected Standard");
} else if (Mode == "Scientific") { } else if ("Scientific".equals(Mode)) {
// System.out.println("User has Selected Scientific Calculator");
CalculatorModes.Scientific(); CalculatorModes.Scientific();
} else if (Mode == "Data calculation") { } else if ("Data calculation".equals(Mode)) {
// System.out.println("User has Selected Date calculation mode");
CalculatorModes.DateCalculation(); CalculatorModes.DateCalculation();
} else { } else {
System.out.println(Mode); System.out.println(Mode);
@@ -673,12 +659,13 @@ public class Calculator extends JFrame implements KeyListener {
} }
private void processDigit(String actionCommand) { private void processDigit(String actionCommand) {
if (resultVisible == true) { if (resultVisible) {
display.setText(""); display.setText("");
resultVisible = false; resultVisible = false;
} }
display.setText(display.getText() + actionCommand); String newValue = display.getText() + actionCommand;
display.setText(newValue);
saveToUndoStack(newValue);
} }
private void setOperator(String daop) { private void setOperator(String daop) {
operand1 = display.getText(); operand1 = display.getText();
@@ -691,15 +678,15 @@ public class Calculator extends JFrame implements KeyListener {
double op1 = Double.parseDouble(operand1); double op1 = Double.parseDouble(operand1);
double op2 = Double.parseDouble(operand2); double op2 = Double.parseDouble(operand2);
if (operator == "+") { if ("+".equals(operator)) {
result = op1+op2; result = op1+op2;
} else if (operator == "-") { } else if ("-".equals(operator)) {
result = op1-op2; result = op1-op2;
} else if (operator == "*") { } else if ("*".equals(operator)) {
result = op1*op2; result = op1*op2;
} else if (operator == "/") { } else if ("/".equals(operator)) {
result = op1/op2; result = op1/op2;
} else if (operator == "%") { } else if ("%".equals(operator)) {
result = op1 % op2; result = op1 % op2;
} else { } else {
result = op2; result = op2;
@@ -707,12 +694,19 @@ public class Calculator extends JFrame implements KeyListener {
System.out.println("Op2: " + op2); System.out.println("Op2: " + op2);
} }
// Save calculation to history
if (!operator.isEmpty()) {
String calculation = operand1 + " " + operator + " " + operand2 + " = " + result;
history.saveToHistory(calculation);
}
operator = ""; operator = "";
operand1 = ""; operand1 = "";
operand2 = ""; operand2 = "";
resultVisible = true; resultVisible = true;
display.setText(""+result); display.setText(""+result);
saveToUndoStack(""+result);
} }
private void loadPreferences() { private void loadPreferences() {
@@ -739,6 +733,8 @@ public class Calculator extends JFrame implements KeyListener {
case "dark", "darcula" -> FlatDarculaLaf.setup(); case "dark", "darcula" -> FlatDarculaLaf.setup();
case "macdarkblue" -> MacDarkBlue.setup(); case "macdarkblue" -> MacDarkBlue.setup();
case "macdarkred" -> MacDarkRed.setup(); case "macdarkred" -> MacDarkRed.setup();
case "maclightblue" -> MacLightBlue.setup();
case "maclightred" -> MacLightRed.setup();
default -> FlatDarculaLaf.setup(); default -> FlatDarculaLaf.setup();
} }
FlatLaf.updateUI(); FlatLaf.updateUI();
@@ -749,6 +745,43 @@ public class Calculator extends JFrame implements KeyListener {
} }
} }
/**
* Determines if a theme is dark mode
*/
private boolean isThemeDark(String theme) {
if (theme == null) return true;
return theme.toLowerCase().contains("dark") ||
"Default".equals(theme) && FlatLaf.isLafDark();
}
/**
* Gets the light/dark counterpart of a theme
* For example: MacDarkBlue <-> MacLightBlue
*/
private String getThemeCounterpart(String theme, boolean toLight) {
if (theme == null || "Default".equals(theme)) {
return "Default";
}
// Handle Mac themes
if (theme.startsWith("Mac")) {
if (toLight) {
// Switch to light variant
return theme.replace("Dark", "Light");
} else {
// Switch to dark variant
return theme.replace("Light", "Dark");
}
}
return theme;
}
private boolean isCustomMacTheme(String theme) {
String lower = theme.toLowerCase();
return lower.equals("macdarkblue") || lower.equals("macdarkred") ||
lower.equals("maclightblue") || lower.equals("maclightred");
}
// Implement the keyPressed method // Implement the keyPressed method
@@ -756,7 +789,7 @@ public class Calculator extends JFrame implements KeyListener {
public void keyPressed(KeyEvent e) { public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode(); int keyCode = e.getKeyCode();
// System.out.println("Key Pressed: " + KeyEvent.getKeyText(keyCode)); // System.out.println("Key Pressed: " + KeyEvent.getKeyText(keyCode));
if (KeyEvent.getKeyText(keyCode) == "Enter") { if ("Enter".equals(KeyEvent.getKeyText(keyCode))) {
math(); math();
} else if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE) { } else if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
backspace(); backspace();

View File

@@ -0,0 +1,20 @@
package dev.sillyangel.calc.themes;
import com.formdev.flatlaf.themes.FlatMacLightLaf;
public class MacLightBlue extends FlatMacLightLaf {
public static final String NAME = "MacLightBlue";
public static boolean setup() {
return setup( new MacLightBlue() );
}
public static void installLafInfo() {
installLafInfo( NAME, MacLightBlue.class );
}
@Override
public String getName() {
return NAME;
}
}

View File

@@ -0,0 +1,4 @@
# base theme (light, dark, intellij, darcula, maclight or macdark); only used by theme editor
@baseTheme = macdark
@accentColor = #0e59c3ff

View File

@@ -0,0 +1,20 @@
package dev.sillyangel.calc.themes;
import com.formdev.flatlaf.themes.FlatMacLightLaf;
public class MacLightRed extends FlatMacLightLaf {
public static final String NAME = "MacLightRed";
public static boolean setup() {
return setup( new MacLightRed() );
}
public static void installLafInfo() {
installLafInfo( NAME, MacLightRed.class );
}
@Override
public String getName() {
return NAME;
}
}

View File

@@ -0,0 +1,2 @@
@baseTheme = macdark
@accentColor = #a83e32