Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
2fdf160ed3
|
|||
|
f15534c4d5
|
|||
|
fdbcb56b1b
|
|||
|
b9c4c6f3e7
|
|||
| 751f878a32 | |||
| 3d1d98ee7b | |||
| bf126de5b9 | |||
| 485dccdf3b | |||
| 5b9568013d | |||
| 48c2e0abd9 | |||
| ebdf464c31 | |||
| b812535366 | |||
| a52fe8dc78 | |||
| cc2a625fc1 | |||
| c7659bb44e | |||
| 16e85a3fe3 | |||
| c8aa7a9648 | |||
| cdc05c9b67 | |||
| 250384e738 | |||
| 1c749e1098 | |||
| c3756e1982 | |||
| 97777f1046 | |||
| c59fdc4430 |
@@ -26,7 +26,7 @@ jobs:
|
||||
|
||||
- name: Compile Java files
|
||||
run: |
|
||||
javac -encoding UTF-8 -cp "lib/flatlaf-3.7.jar" -d out/production/Calc \
|
||||
javac -encoding UTF-8 -cp "lib/flatlaf-3.7.jar:lib/flatlaf-extras-3.7.jar" -d out/production/Calc \
|
||||
$(find src/main/java -name "*.java")
|
||||
|
||||
- name: Copy resources
|
||||
|
||||
6
.idea/copilot.data.migration.ask2agent.xml
generated
Normal file
6
.idea/copilot.data.migration.ask2agent.xml
generated
Normal 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>
|
||||
7
.idea/libraries/lib.xml
generated
7
.idea/libraries/lib.xml
generated
@@ -2,9 +2,12 @@
|
||||
<library name="lib">
|
||||
<CLASSES>
|
||||
<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>
|
||||
<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>
|
||||
</component>
|
||||
Binary file not shown.
BIN
lib/flatlaf-3.7-sources.jar
Normal file
BIN
lib/flatlaf-3.7-sources.jar
Normal file
Binary file not shown.
BIN
lib/flatlaf-extras-3.7-javadoc.jar
Normal file
BIN
lib/flatlaf-extras-3.7-javadoc.jar
Normal file
Binary file not shown.
BIN
lib/flatlaf-extras-3.7-sources.jar
Normal file
BIN
lib/flatlaf-extras-3.7-sources.jar
Normal file
Binary file not shown.
BIN
lib/flatlaf-extras-3.7.jar
Normal file
BIN
lib/flatlaf-extras-3.7.jar
Normal file
Binary file not shown.
@@ -4,6 +4,8 @@ package dev.sillyangel.calc;
|
||||
// java to javax, com, dev
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.datatransfer.*;
|
||||
import java.io.Serial;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
@@ -15,38 +17,68 @@ import javax.swing.LayoutStyle.ComponentPlacement;
|
||||
import javax.swing.GroupLayout;
|
||||
import javax.swing.GroupLayout.Alignment;
|
||||
import javax.swing.*;
|
||||
import com.formdev.flatlaf.FlatDarculaLaf;
|
||||
import com.formdev.flatlaf.themes.FlatMacDarkLaf;
|
||||
import com.formdev.flatlaf.FlatIntelliJLaf;
|
||||
import java.util.prefs.Preferences;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import dev.sillyangel.calc.themes.*;
|
||||
import dev.sillyangel.calc.CalculatorModes;
|
||||
|
||||
|
||||
public class Calculator extends JFrame implements KeyListener {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
private JPanel contentPane;
|
||||
private JTextField display;
|
||||
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 JTextField display;
|
||||
private String operand1;
|
||||
private String operator;
|
||||
private String operand2;
|
||||
private JButton btnDiv;
|
||||
private JButton btnMul;
|
||||
private JButton btnMin;
|
||||
private JButton btnPlus;
|
||||
protected boolean resultVisible;
|
||||
protected double result;
|
||||
private String[] Modes = new String[] {"Standard", "Scientific", "Data calculation"};
|
||||
private JComboBox<String> modeselect;
|
||||
private final CalculatorHistory history;
|
||||
private final List<String> undoStack = new ArrayList<>();
|
||||
private int undoIndex = -1;
|
||||
|
||||
public static String getVersion() {
|
||||
return APPLICATION_VERSION;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// IntelliJTheme.setup(Calculator.class.getResourceAsStream("/DarkPurple.theme.json"));
|
||||
// FlatMacDarkLaf.setup();
|
||||
// MacDarkRed.setup();
|
||||
MacDarkBlue.setup();
|
||||
// Load saved theme preference
|
||||
String savedTheme = prefs.get(PREF_THEME, "MacDarkBlue");
|
||||
|
||||
// Apply saved theme on startup
|
||||
try {
|
||||
// UIManager.setLookAndFeel("com.formdev.flatlaf.themes.FlatMacDarkLaf");
|
||||
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
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("created by angel");
|
||||
System.out.println("---------------------------------");
|
||||
if( SystemInfo.isMacOS ) {
|
||||
System.setProperty( "apple.laf.useScreenMenuBar", "true" );
|
||||
System.setProperty( "apple.awt.application.name", "Calculator" );
|
||||
System.setProperty( "apple.awt.application.appearance", "system" );
|
||||
}
|
||||
if( SystemInfo.isLinux ) { // why is linux different
|
||||
JFrame.setDefaultLookAndFeelDecorated(true);
|
||||
}
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
@@ -59,11 +91,12 @@ public class Calculator extends JFrame implements KeyListener {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Calculator() {
|
||||
history = new CalculatorHistory();
|
||||
|
||||
setBackground(new Color(32, 32, 32));
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
// setIconImage(Toolkit.getDefaultToolkit().getImage(Calculator.class.getResource("/images/appIcon.png")));
|
||||
//setIconImage(Toolkit.getDefaultToolkit().getImage(Calculator.class.getResource("/images/appIcon.png")));
|
||||
List<Image> icons = new ArrayList<>();
|
||||
icons.add(Toolkit.getDefaultToolkit().getImage(Calculator.class.getResource("/images/appIcon16.png")));
|
||||
icons.add(Toolkit.getDefaultToolkit().getImage(Calculator.class.getResource("/images/appIcon32.png")));
|
||||
@@ -72,17 +105,18 @@ public class Calculator extends JFrame implements KeyListener {
|
||||
icons.add(Toolkit.getDefaultToolkit().getImage(Calculator.class.getResource("/images/appIcon512.png")));
|
||||
icons.add(Toolkit.getDefaultToolkit().getImage(Calculator.class.getResource("/images/appIcon1024.png")));
|
||||
setIconImages(icons);
|
||||
|
||||
|
||||
setTitle("AAC");
|
||||
setBounds(100, 100, 368, 556);
|
||||
setFocusable(true);
|
||||
addKeyListener(this);
|
||||
|
||||
contentPane = new JPanel();
|
||||
JPanel contentPane = new JPanel();
|
||||
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
setContentPane(contentPane);
|
||||
|
||||
display = new JTextField();
|
||||
display.setFocusable(false);
|
||||
display.setEditable(false);
|
||||
display.setFont(new Font("Segoe UI", Font.PLAIN, 22));
|
||||
display.setColumns(10);
|
||||
@@ -96,7 +130,8 @@ public class Calculator extends JFrame implements KeyListener {
|
||||
}
|
||||
});
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
|
||||
GroupLayout gl_contentPane = new GroupLayout(contentPane);
|
||||
gl_contentPane.setHorizontalGroup(
|
||||
gl_contentPane.createParallelGroup(Alignment.LEADING)
|
||||
@@ -125,18 +160,65 @@ public class Calculator extends JFrame implements KeyListener {
|
||||
JMenuBar menubar = new JMenuBar();
|
||||
|
||||
JMenu help = new JMenu("Help");
|
||||
JMenu file = new JMenu("File");
|
||||
JMenu edit = new JMenu("Edit");
|
||||
/*
|
||||
* Edit Will have
|
||||
* Undo
|
||||
* Redo
|
||||
* Cut
|
||||
* Copy
|
||||
* Paste
|
||||
* Delete which is just Backspace or Clear all a
|
||||
* Settings
|
||||
* */
|
||||
|
||||
|
||||
|
||||
JMenuItem Exit = new JMenuItem("Exit");
|
||||
Exit.addActionListener(e -> System.exit(1));
|
||||
Exit.setMnemonic('E');
|
||||
|
||||
JMenuItem about = new JMenuItem("About");
|
||||
about.setMnemonic('A');
|
||||
about.addActionListener(e -> aboutActionPerformed());
|
||||
|
||||
|
||||
JMenuItem undo = new JMenuItem("Undo");
|
||||
JMenuItem redo = new JMenuItem("Redo");
|
||||
JMenuItem cut = new JMenuItem("Cut");
|
||||
JMenuItem copy = new JMenuItem("Copy");
|
||||
JMenuItem paste = new JMenuItem("Paste");
|
||||
JMenuItem delete = new JMenuItem("Delete");
|
||||
delete.addActionListener(e -> clearEntry());
|
||||
JMenuItem preferencesm = new JMenuItem("Preferences");
|
||||
preferencesm.setMnemonic('P');
|
||||
preferencesm.addActionListener(e -> PreferencesAction());
|
||||
undo.addActionListener(e -> undoAction());
|
||||
redo.addActionListener(e -> redoAction());
|
||||
cut.addActionListener(e -> cutAction());
|
||||
copy.addActionListener(e -> copyAction());
|
||||
paste.addActionListener(e -> pasteAction());
|
||||
|
||||
edit.add(undo);
|
||||
edit.add(redo);
|
||||
edit.add(cut);
|
||||
edit.add(copy);
|
||||
edit.add(paste);
|
||||
edit.add(delete);
|
||||
edit.add(preferencesm);
|
||||
|
||||
file.add(Exit);
|
||||
file.setMnemonic('F');
|
||||
help.add(about);
|
||||
help.setMnemonic('H');
|
||||
edit.setMnemonic('E');
|
||||
menubar.add(file);
|
||||
menubar.add(edit);
|
||||
menubar.add(help);
|
||||
setJMenuBar(menubar);
|
||||
|
||||
modeselect = new JComboBox<>(Modes);
|
||||
|
||||
String[] modes = new String[]{"Standard", "Scientific", "Data calculation"};
|
||||
JComboBox<String> modeselect = new JComboBox<>(modes);
|
||||
modeselect.addActionListener(new ActionListener() {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@@ -184,247 +266,304 @@ public class Calculator extends JFrame implements KeyListener {
|
||||
JButton btn8 = new JButton("8");
|
||||
JButton btn9 = new JButton("9");
|
||||
|
||||
btnDiv = new JButton("/");
|
||||
btnMul = new JButton("*");
|
||||
btnMin = new JButton("-");
|
||||
btnPlus = new JButton("+");
|
||||
JButton btnDiv = new JButton("/");
|
||||
JButton btnMul = new JButton("*");
|
||||
JButton btnMin = new JButton("-");
|
||||
JButton btnPlus = new JButton("+");
|
||||
|
||||
btnDot.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String n = display.getText(); // get the text on the display
|
||||
if (n.contains(".")) return; // if it already contains a "." skip rest of this
|
||||
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) {
|
||||
String n = display.getText();
|
||||
if (n.contains(".")) return;
|
||||
processDigit(e.getActionCommand());
|
||||
}
|
||||
});
|
||||
|
||||
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) {
|
||||
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() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
reciprocal();
|
||||
}
|
||||
});
|
||||
btnClear.addActionListener(e -> clearAll());
|
||||
btnReciprocal.addActionListener(e -> 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() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
square();
|
||||
}
|
||||
});
|
||||
|
||||
btnSquareRoot.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
squareRoot();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
btnBackspace.setFont(new Font("Segoe UI", Font.PLAIN, 29));
|
||||
btnClear.setFont(new Font("Segoe UI", Font.PLAIN, 29));
|
||||
btnClearEntry.setFont(new Font("Segoe UI", Font.PLAIN, 29));
|
||||
btnPlusMin.setFont(new Font("Segoe UI", Font.PLAIN, 29));
|
||||
btnEq.setFont(new Font("Segoe UI", Font.PLAIN, 29));
|
||||
btnDot.setFont(new Font("Segoe UI", Font.PLAIN, 29));
|
||||
btn0.setFont(new Font("Segoe UI", Font.PLAIN, 29));
|
||||
btn1.setFont(new Font("Segoe UI", Font.PLAIN, 29));
|
||||
btn2.setFont(new Font("Segoe UI", Font.PLAIN, 29));
|
||||
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);
|
||||
JButton[] buttons = {
|
||||
btnPercent, btnClearEntry, btnClear, btnBackspace, btnReciprocal, btnSquare,
|
||||
btnSquareRoot, btnDiv, btn7, btn8, btn9, btnMul, btn4, btn5, btn6, btnMin,
|
||||
btn1, btn2, btn3, btnPlus, btnPlusMin, btn0, btnDot, btnEq
|
||||
};
|
||||
JButton[] operatorButtons = {
|
||||
btnPlus, btnDiv, btnMul, btnMin, btnPercent
|
||||
};
|
||||
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)
|
||||
button.addActionListener(e -> processDigit(e.getActionCommand()));
|
||||
// Add action listeners to each operator to process what operator button has been clicked
|
||||
for (JButton button : operatorButtons)
|
||||
button.addActionListener(e -> setOperator(e.getActionCommand()));
|
||||
// add the buttons to the main display panel
|
||||
for(JButton button: buttons) {
|
||||
button.setFocusable(false);
|
||||
button.setFont(new Font("Segoe UI", Font.PLAIN, 29));
|
||||
buttonPanel.add(button);
|
||||
}
|
||||
|
||||
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() {
|
||||
JDialog dialog = new JDialog(this, "Preferences", true);
|
||||
dialog.setSize(400, 280);
|
||||
dialog.setLocationRelativeTo(this);
|
||||
dialog.setLayout(new BorderLayout(10, 10));
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||
panel.setLayout(new GridLayout(0, 2, 8, 8));
|
||||
|
||||
// Color theme selector
|
||||
JComboBox<String> colorThemeBox = new JComboBox<>(new String[]{
|
||||
"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
|
||||
JSpinner fontSizeSpinner = new JSpinner(
|
||||
new SpinnerNumberModel(
|
||||
prefs.getInt(PREF_FONT_SIZE, 22),
|
||||
12, 48, 1
|
||||
)
|
||||
);
|
||||
|
||||
// Always on top
|
||||
JCheckBox alwaysOnTopBox = new JCheckBox(
|
||||
"Always on top",
|
||||
prefs.getBoolean(PREF_ALWAYS_ON_TOP, false)
|
||||
);
|
||||
|
||||
panel.add(new JLabel("Color Theme:"));
|
||||
panel.add(colorThemeBox);
|
||||
|
||||
panel.add(new JLabel("Mode:"));
|
||||
panel.add(modeBox);
|
||||
|
||||
panel.add(new JLabel("Font Size:"));
|
||||
panel.add(fontSizeSpinner);
|
||||
|
||||
panel.add(new JLabel(""));
|
||||
panel.add(alwaysOnTopBox);
|
||||
|
||||
JButton apply = new JButton("Apply");
|
||||
JButton close = new JButton("Close");
|
||||
|
||||
apply.addActionListener(e -> {
|
||||
String theme = (String) colorThemeBox.getSelectedItem();
|
||||
int fontSize = (int) fontSizeSpinner.getValue();
|
||||
boolean alwaysOnTop = alwaysOnTopBox.isSelected();
|
||||
|
||||
prefs.put(PREF_THEME, theme);
|
||||
prefs.putInt(PREF_FONT_SIZE, fontSize);
|
||||
prefs.putBoolean(PREF_ALWAYS_ON_TOP, alwaysOnTop);
|
||||
|
||||
applyPreferences(theme, fontSize, alwaysOnTop);
|
||||
});
|
||||
|
||||
close.addActionListener(e -> dialog.dispose());
|
||||
|
||||
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
||||
buttons.add(apply);
|
||||
buttons.add(close);
|
||||
|
||||
dialog.add(panel, BorderLayout.CENTER);
|
||||
dialog.add(buttons, BorderLayout.SOUTH);
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
private void applyPreferences(String theme, int fontSize, boolean alwaysOnTop) {
|
||||
display.setFont(new Font("Segoe UI", Font.PLAIN, fontSize));
|
||||
setAlwaysOnTop(alwaysOnTop);
|
||||
|
||||
try {
|
||||
FlatAnimatedLafChange.showSnapshot();
|
||||
switch (theme) {
|
||||
case "Default" -> {
|
||||
if (FlatLaf.isLafDark()) {
|
||||
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();
|
||||
FlatAnimatedLafChange.hideSnapshotWithAnimation();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void aboutActionPerformed() {
|
||||
JLabel titleLabel = new JLabel( "Angel's Awesome Calculator" );
|
||||
titleLabel.putClientProperty( FlatClientProperties.STYLE_CLASS, "h1" );
|
||||
@@ -451,6 +590,7 @@ public class Calculator extends JFrame implements KeyListener {
|
||||
titleLabel,
|
||||
"a very okay calculator app created in java (uses flatlaf)",
|
||||
" ",
|
||||
"Version " + Calculator.getVersion(),
|
||||
"Copyright " + Year.now() + " angel",
|
||||
linkLabel,
|
||||
},
|
||||
@@ -458,13 +598,11 @@ public class Calculator extends JFrame implements KeyListener {
|
||||
}
|
||||
|
||||
private void UpdateMode(String Mode) {
|
||||
if (Mode == "Standard") {
|
||||
if ("Standard".equals(Mode)) {
|
||||
System.out.println("User has Selected Standard");
|
||||
} else if (Mode == "Scientific") {
|
||||
// System.out.println("User has Selected Scientific Calculator");
|
||||
} else if ("Scientific".equals(Mode)) {
|
||||
CalculatorModes.Scientific();
|
||||
} else if (Mode == "Data calculation") {
|
||||
// System.out.println("User has Selected Date calculation mode");
|
||||
} else if ("Data calculation".equals(Mode)) {
|
||||
CalculatorModes.DateCalculation();
|
||||
} else {
|
||||
System.out.println(Mode);
|
||||
@@ -525,12 +663,13 @@ public class Calculator extends JFrame implements KeyListener {
|
||||
}
|
||||
|
||||
private void processDigit(String actionCommand) {
|
||||
if (resultVisible == true) {
|
||||
if (resultVisible) {
|
||||
display.setText("");
|
||||
resultVisible = false;
|
||||
}
|
||||
display.setText(display.getText() + actionCommand);
|
||||
|
||||
String newValue = display.getText() + actionCommand;
|
||||
display.setText(newValue);
|
||||
saveToUndoStack(newValue);
|
||||
}
|
||||
private void setOperator(String daop) {
|
||||
operand1 = display.getText();
|
||||
@@ -543,15 +682,15 @@ public class Calculator extends JFrame implements KeyListener {
|
||||
double op1 = Double.parseDouble(operand1);
|
||||
double op2 = Double.parseDouble(operand2);
|
||||
|
||||
if (operator == "+") {
|
||||
if ("+".equals(operator)) {
|
||||
result = op1+op2;
|
||||
} else if (operator == "-") {
|
||||
} else if ("-".equals(operator)) {
|
||||
result = op1-op2;
|
||||
} else if (operator == "*") {
|
||||
} else if ("*".equals(operator)) {
|
||||
result = op1*op2;
|
||||
} else if (operator == "/") {
|
||||
} else if ("/".equals(operator)) {
|
||||
result = op1/op2;
|
||||
} else if (operator == "%") {
|
||||
} else if ("%".equals(operator)) {
|
||||
result = op1 % op2;
|
||||
} else {
|
||||
result = op2;
|
||||
@@ -559,20 +698,102 @@ public class Calculator extends JFrame implements KeyListener {
|
||||
System.out.println("Op2: " + op2);
|
||||
}
|
||||
|
||||
// Save calculation to history
|
||||
if (!operator.isEmpty()) {
|
||||
String calculation = operand1 + " " + operator + " " + operand2 + " = " + result;
|
||||
history.saveToHistory(calculation);
|
||||
}
|
||||
|
||||
operator = "";
|
||||
operand1 = "";
|
||||
operand2 = "";
|
||||
|
||||
resultVisible = true;
|
||||
display.setText(""+result);
|
||||
saveToUndoStack(""+result);
|
||||
}
|
||||
|
||||
private void loadPreferences() {
|
||||
int fontSize = prefs.getInt(PREF_FONT_SIZE, 22);
|
||||
boolean alwaysOnTop = prefs.getBoolean(PREF_ALWAYS_ON_TOP, false);
|
||||
|
||||
display.setFont(new Font("Segoe UI", Font.PLAIN, fontSize));
|
||||
setAlwaysOnTop(alwaysOnTop);
|
||||
}
|
||||
|
||||
private void changeThemes(String theme) {
|
||||
boolean dark = switch (theme.toLowerCase()) {
|
||||
case "dark", "darcula", "macdarkblue", "macdarkred" -> true;
|
||||
default -> false;
|
||||
};
|
||||
|
||||
// Only switch if needed
|
||||
if (FlatLaf.isLafDark() != dark || isCustomMacTheme(theme)) {
|
||||
EventQueue.invokeLater(() -> {
|
||||
FlatAnimatedLafChange.showSnapshot();
|
||||
try {
|
||||
switch (theme.toLowerCase()) {
|
||||
case "light" -> FlatIntelliJLaf.setup();
|
||||
case "dark", "darcula" -> FlatDarculaLaf.setup();
|
||||
case "macdarkblue" -> MacDarkBlue.setup();
|
||||
case "macdarkred" -> MacDarkRed.setup();
|
||||
case "maclightblue" -> MacLightBlue.setup();
|
||||
case "maclightred" -> MacLightRed.setup();
|
||||
default -> FlatDarculaLaf.setup();
|
||||
}
|
||||
FlatLaf.updateUI();
|
||||
} finally {
|
||||
FlatAnimatedLafChange.hideSnapshotWithAnimation();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
int keyCode = e.getKeyCode();
|
||||
// System.out.println("Key Pressed: " + KeyEvent.getKeyText(keyCode));
|
||||
if (KeyEvent.getKeyText(keyCode) == "Enter") {
|
||||
if ("Enter".equals(KeyEvent.getKeyText(keyCode))) {
|
||||
math();
|
||||
} else if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
|
||||
backspace();
|
||||
|
||||
138
src/main/java/dev/sillyangel/calc/CalculatorHistory.java
Normal file
138
src/main/java/dev/sillyangel/calc/CalculatorHistory.java
Normal file
@@ -0,0 +1,138 @@
|
||||
package dev.sillyangel.calc;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Manages calculation history for the calculator application.
|
||||
* Stores calculations in a file and provides methods to retrieve and manage history.
|
||||
*/
|
||||
public class CalculatorHistory {
|
||||
private final List<String> calculationHistory = new ArrayList<>();
|
||||
private final Path historyFilePath;
|
||||
private static final String HISTORY_DIR = System.getProperty("user.home") + File.separator + ".calculator";
|
||||
private static final String HISTORY_FILE = "calc_history.txt";
|
||||
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
public CalculatorHistory() {
|
||||
historyFilePath = Paths.get(HISTORY_DIR, HISTORY_FILE);
|
||||
initializeHistoryFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the history file and directory structure.
|
||||
* Creates the directory and file if they don't exist, and loads existing history.
|
||||
*/
|
||||
private void initializeHistoryFile() {
|
||||
try {
|
||||
// Create directory if it doesn't exist
|
||||
Path dir = Paths.get(HISTORY_DIR);
|
||||
if (!Files.exists(dir)) {
|
||||
Files.createDirectories(dir);
|
||||
System.out.println("Created history directory: " + HISTORY_DIR);
|
||||
}
|
||||
|
||||
// Create file if it doesn't exist
|
||||
if (!Files.exists(historyFilePath)) {
|
||||
Files.createFile(historyFilePath);
|
||||
System.out.println("Created history file: " + historyFilePath);
|
||||
}
|
||||
|
||||
// Load existing history
|
||||
loadHistory();
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error initializing history file: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a calculation to the history file.
|
||||
* @param calculation The calculation string to save (e.g., "5 + 3 = 8")
|
||||
*/
|
||||
public void saveToHistory(String calculation) {
|
||||
try {
|
||||
String timestamp = LocalDateTime.now().format(formatter);
|
||||
String entry = "[" + timestamp + "] " + calculation;
|
||||
|
||||
// Add to memory list
|
||||
calculationHistory.add(entry);
|
||||
|
||||
// Append to file
|
||||
Files.write(historyFilePath,
|
||||
(entry + System.lineSeparator()).getBytes(),
|
||||
StandardOpenOption.APPEND);
|
||||
|
||||
System.out.println("Saved to history: " + entry);
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error saving to history: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads history from the file into memory.
|
||||
*/
|
||||
private void loadHistory() {
|
||||
try {
|
||||
if (Files.exists(historyFilePath)) {
|
||||
List<String> lines = Files.readAllLines(historyFilePath);
|
||||
calculationHistory.addAll(lines);
|
||||
System.out.println("Loaded " + lines.size() + " history entries");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error loading history: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of all calculation history entries.
|
||||
* @return A list of history entries with timestamps
|
||||
*/
|
||||
public List<String> getCalculationHistory() {
|
||||
return new ArrayList<>(calculationHistory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the most recent N history entries.
|
||||
* @param count The number of entries to return
|
||||
* @return A list of the most recent history entries
|
||||
*/
|
||||
public List<String> getRecentHistory(int count) {
|
||||
int size = calculationHistory.size();
|
||||
int fromIndex = Math.max(0, size - count);
|
||||
return new ArrayList<>(calculationHistory.subList(fromIndex, size));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all history entries from memory and file.
|
||||
*/
|
||||
public void clearHistory() {
|
||||
try {
|
||||
calculationHistory.clear();
|
||||
Files.write(historyFilePath, new byte[0], StandardOpenOption.TRUNCATE_EXISTING);
|
||||
System.out.println("History cleared");
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error clearing history: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of history entries.
|
||||
* @return The count of history entries
|
||||
*/
|
||||
public int getHistoryCount() {
|
||||
return calculationHistory.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the history file.
|
||||
* @return The file path as a string
|
||||
*/
|
||||
public String getHistoryFilePath() {
|
||||
return historyFilePath.toString();
|
||||
}
|
||||
}
|
||||
|
||||
20
src/main/java/dev/sillyangel/calc/themes/MacLightBlue.java
Normal file
20
src/main/java/dev/sillyangel/calc/themes/MacLightBlue.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
# base theme (light, dark, intellij, darcula, maclight or macdark); only used by theme editor
|
||||
@baseTheme = macdark
|
||||
|
||||
@accentColor = #0e59c3ff
|
||||
20
src/main/java/dev/sillyangel/calc/themes/MacLightRed.java
Normal file
20
src/main/java/dev/sillyangel/calc/themes/MacLightRed.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
@baseTheme = macdark
|
||||
@accentColor = #a83e32
|
||||
Reference in New Issue
Block a user