diff --git a/src/main/java/dev/sillyangel/calc/Calculator.java b/src/main/java/dev/sillyangel/calc/Calculator.java index 14d1aa0..de15121 100644 --- a/src/main/java/dev/sillyangel/calc/Calculator.java +++ b/src/main/java/dev/sillyangel/calc/Calculator.java @@ -17,6 +17,7 @@ import javax.swing.GroupLayout.Alignment; import javax.swing.*; import com.formdev.flatlaf.FlatDarculaLaf; 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; @@ -486,9 +487,85 @@ public class Calculator extends JFrame implements KeyListener { } private void PreferencesAction() { - System.out.println("preferences panel are open"); + JDialog dialog = new JDialog(this, "Preferences", true); + dialog.setSize(320, 220); + 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)); + + // Theme selector + JComboBox themeBox = new JComboBox<>(new String[]{"Dark", "Light"}); + themeBox.setSelectedItem(prefs.get(PREF_THEME, "Dark")); + + // 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("Theme")); + panel.add(themeBox); + + 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) themeBox.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(); + if ("Light".equals(theme)) { + FlatIntelliJLaf.setup(); + } else { + 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" ); @@ -631,11 +708,43 @@ public class Calculator extends JFrame implements KeyListener { resultVisible = true; display.setText(""+result); } - private void changeThemes(String theme) { - // something like - // https://github.com/DJ-Raven/raven-java-swing-tutorial-project/blob/main/dark-light-switch/src/raven/themes/Test.java#L106 + + 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(); + default -> FlatDarculaLaf.setup(); + } + FlatLaf.updateUI(); + } finally { + FlatAnimatedLafChange.hideSnapshotWithAnimation(); + } + }); + } + } + + + // Implement the keyPressed method @Override public void keyPressed(KeyEvent e) {