diff --git a/src/me/ByteEdit/boxes/CompilationBox.java b/src/me/ByteEdit/boxes/CompilationBox.java index debe169..491e074 100644 --- a/src/me/ByteEdit/boxes/CompilationBox.java +++ b/src/me/ByteEdit/boxes/CompilationBox.java @@ -1,7 +1,6 @@ package me.ByteEdit.boxes; import java.awt.BorderLayout; -import java.awt.Color; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -22,7 +21,6 @@ import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.KeyStroke; -import javax.swing.UIManager; import javax.swing.border.EmptyBorder; import javax.tools.JavaCompiler; import javax.tools.SimpleJavaFileObject; @@ -36,6 +34,7 @@ import org.objectweb.asm.tree.ClassNode; import me.ByteEdit.edit.Disassembler; import me.ByteEdit.main.Main; +import me.ByteEdit.main.ThemeManager; public class CompilationBox extends JFrame { @@ -46,32 +45,25 @@ public class CompilationBox extends JFrame { public CompilationBox() { compSuccess = new CompilationSuccess(); - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - e.printStackTrace(); - } + ThemeManager.registerFrames(compSuccess); setTitle("Java Compiler"); setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); setBounds((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - 400), (int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 - 200), 800, 400); contentPane = new JPanel(); - contentPane.setBackground(Main.dark ? new Color(0x2F2F2F) : Color.GRAY); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(new BorderLayout(0, 0)); - Main.theme.apply(textArea); + ThemeManager.registerTextArea(textArea); textArea.setEditable(true); textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); textArea.setCodeFoldingEnabled(true); - textArea.setBackground(Main.dark ? new Color(0x2F2F2F) : Color.LIGHT_GRAY); RTextScrollPane scrollPane = new RTextScrollPane(); scrollPane.setViewportView(textArea); scrollPane.setLineNumbersEnabled(true); scrollPane.setFoldIndicatorEnabled(true); - scrollPane.getGutter().setBackground(Main.dark ? new Color(0x2F2F2F) : Color.LIGHT_GRAY); contentPane.add(scrollPane); KeyStroke ctrlS = KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_DOWN_MASK); diff --git a/src/me/ByteEdit/boxes/CompilationSuccess.java b/src/me/ByteEdit/boxes/CompilationSuccess.java index 2a40ab0..95e13ee 100644 --- a/src/me/ByteEdit/boxes/CompilationSuccess.java +++ b/src/me/ByteEdit/boxes/CompilationSuccess.java @@ -1,19 +1,17 @@ package me.ByteEdit.boxes; import java.awt.BorderLayout; -import java.awt.Color; import java.awt.Toolkit; import javax.swing.JFrame; import javax.swing.JPanel; -import javax.swing.UIManager; import javax.swing.border.EmptyBorder; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.SyntaxConstants; import org.fife.ui.rtextarea.RTextScrollPane; -import me.ByteEdit.main.Main; +import me.ByteEdit.main.ThemeManager; public class CompilationSuccess extends JFrame { @@ -21,32 +19,24 @@ public class CompilationSuccess extends JFrame { RSyntaxTextArea textArea = new RSyntaxTextArea(); public CompilationSuccess() { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - e.printStackTrace(); - } setTitle("Java Compiler - Result"); setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); setBounds((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - 400), (int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 - 200), 800, 400); contentPane = new JPanel(); - contentPane.setBackground(Main.dark ? new Color(0x2F2F2F) : Color.GRAY); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(new BorderLayout(0, 0)); - Main.theme.apply(textArea); + ThemeManager.registerTextArea(textArea); textArea.setEditable(true); textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA_DISASSEMBLE); textArea.setCodeFoldingEnabled(true); - textArea.setBackground(Main.dark ? new Color(0x2F2F2F) : Color.LIGHT_GRAY); RTextScrollPane scrollPane = new RTextScrollPane(); scrollPane.setViewportView(textArea); scrollPane.setLineNumbersEnabled(true); scrollPane.setFoldIndicatorEnabled(true); - scrollPane.getGutter().setBackground(Main.dark ? new Color(0x2F2F2F) : Color.LIGHT_GRAY); contentPane.add(scrollPane); } } diff --git a/src/me/ByteEdit/boxes/GlobalSearchBox.java b/src/me/ByteEdit/boxes/GlobalSearchBox.java index caa5a38..bc904e4 100644 --- a/src/me/ByteEdit/boxes/GlobalSearchBox.java +++ b/src/me/ByteEdit/boxes/GlobalSearchBox.java @@ -15,7 +15,6 @@ import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.KeyStroke; -import javax.swing.UIManager; import javax.swing.border.EmptyBorder; import org.objectweb.asm.tree.AbstractInsnNode; @@ -27,6 +26,7 @@ import org.objectweb.asm.tree.MethodNode; import me.ByteEdit.boxes.GlobalSearchOpenBox.Info; import me.ByteEdit.main.Main; +import me.ByteEdit.main.ThemeManager; import me.ByteEdit.utils.UnicodeUtils; public class GlobalSearchBox extends JFrame { @@ -43,12 +43,8 @@ public class GlobalSearchBox extends JFrame { private GlobalSearchOpenBox openBox; public GlobalSearchBox() { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - e.printStackTrace(); - } openBox = new GlobalSearchOpenBox(); + ThemeManager.registerFrames(openBox); setResizable(false); setTitle("Global Search"); setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); diff --git a/src/me/ByteEdit/boxes/GlobalSearchOpenBox.java b/src/me/ByteEdit/boxes/GlobalSearchOpenBox.java index 1b72048..4bc9945 100644 --- a/src/me/ByteEdit/boxes/GlobalSearchOpenBox.java +++ b/src/me/ByteEdit/boxes/GlobalSearchOpenBox.java @@ -8,7 +8,6 @@ import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; -import javax.swing.UIManager; import javax.swing.border.EmptyBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; @@ -24,11 +23,6 @@ public class GlobalSearchOpenBox extends JFrame { DefaultListModel model; public GlobalSearchOpenBox() { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - e.printStackTrace(); - } setResizable(false); setTitle("Global Search - Result"); setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); diff --git a/src/me/ByteEdit/boxes/OptionBox.java b/src/me/ByteEdit/boxes/OptionBox.java index 0e2c13d..9e832e7 100644 --- a/src/me/ByteEdit/boxes/OptionBox.java +++ b/src/me/ByteEdit/boxes/OptionBox.java @@ -5,7 +5,6 @@ import java.awt.Toolkit; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JPanel; -import javax.swing.UIManager; import javax.swing.border.EmptyBorder; public class OptionBox extends JFrame { @@ -15,11 +14,6 @@ public class OptionBox extends JFrame { public JCheckBox chckbxComputeMax; public OptionBox() { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - e.printStackTrace(); - } setResizable(false); setTitle("Options"); setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); diff --git a/src/me/ByteEdit/boxes/SearchBox.java b/src/me/ByteEdit/boxes/SearchBox.java index 40c34d8..db1568b 100644 --- a/src/me/ByteEdit/boxes/SearchBox.java +++ b/src/me/ByteEdit/boxes/SearchBox.java @@ -15,7 +15,6 @@ import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.KeyStroke; -import javax.swing.UIManager; import javax.swing.border.EmptyBorder; import me.ByteEdit.main.Main; @@ -28,11 +27,6 @@ public class SearchBox extends JFrame { public JCheckBox chckbxCaseSensitive; public SearchBox() { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - e.printStackTrace(); - } setResizable(false); setTitle("Find/Replace"); setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); diff --git a/src/me/ByteEdit/boxes/ThemeBox.java b/src/me/ByteEdit/boxes/ThemeBox.java new file mode 100644 index 0000000..b055ae0 --- /dev/null +++ b/src/me/ByteEdit/boxes/ThemeBox.java @@ -0,0 +1,101 @@ +package me.ByteEdit.boxes; + +import java.awt.BorderLayout; +import java.awt.Font; +import java.awt.Toolkit; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.DefaultListModel; +import javax.swing.JFrame; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.ListSelectionModel; +import javax.swing.UIManager; +import javax.swing.UIManager.LookAndFeelInfo; +import javax.swing.border.EmptyBorder; + +import com.formdev.flatlaf.FlatDarculaLaf; +import com.formdev.flatlaf.FlatDarkLaf; +import com.formdev.flatlaf.FlatIntelliJLaf; +import com.formdev.flatlaf.FlatLightLaf; +import com.formdev.flatlaf.intellijthemes.FlatAllIJThemes; + +import me.ByteEdit.main.ThemeManager; + +public class ThemeBox extends JFrame { + + private JPanel contentPane; + private final JScrollPane scrollPane = new JScrollPane(); + private final JList list; + + public ThemeBox() { + setTitle("Theme Chooser"); + setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + setBounds((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - 200), + (int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 - 200), 400, 400); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + contentPane.setLayout(new BorderLayout(0, 0)); + + contentPane.add(scrollPane, BorderLayout.CENTER); + DefaultListModel model = new DefaultListModel<>(); + list = new JList(model); + list.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + LAFI lafi = model.get(list.locationToIndex(e.getPoint())); + if (lafi.className != null) + ThemeManager.changeUIManager(lafi.className, lafi.isDark); + } + } + }); + list.setFont(new Font("Tahoma", Font.BOLD, 18)); + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + model.addElement(new LAFI(null, "--- Installed Themes ---")); + for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { + model.addElement(new LAFI(info.getClassName(), info.getName(), false)); + } + + model.addElement(new LAFI(null, "--- Core Themes ---")); + model.addElement(new LAFI(FlatLightLaf.class.getName(), "Flat Light", false)); + model.addElement(new LAFI(FlatDarkLaf.class.getName(), "Flat Dark", true)); + model.addElement(new LAFI(FlatIntelliJLaf.class.getName(), "Flat IntelliJ", false)); + model.addElement(new LAFI(FlatDarculaLaf.class.getName(), "Flat Darcula", true)); + + model.addElement(new LAFI(null, "--- IntelliJ Themes ---")); + for (LookAndFeelInfo info : FlatAllIJThemes.INFOS) { + model.addElement(new LAFI(info.getClassName(), info.getName())); + } + + scrollPane.setViewportView(list); + } + + static class LAFI { + final String className; + final String name; + final Boolean isDark; + + public LAFI(String className, String name) { + this.className = className; + this.name = name; + this.isDark = null; + } + + public LAFI(String className, String name, boolean isDark) { + this.className = className; + this.name = name; + this.isDark = Boolean.valueOf(isDark); + } + + @Override + public String toString() { + return name; + } + } + +} diff --git a/src/me/ByteEdit/boxes/TypeOpenBox.java b/src/me/ByteEdit/boxes/TypeOpenBox.java index 8e561cd..304bd9b 100644 --- a/src/me/ByteEdit/boxes/TypeOpenBox.java +++ b/src/me/ByteEdit/boxes/TypeOpenBox.java @@ -11,7 +11,6 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.ListSelectionModel; -import javax.swing.UIManager; import javax.swing.border.EmptyBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; @@ -27,11 +26,6 @@ public class TypeOpenBox extends JFrame { public JTextField txtSearch; public TypeOpenBox() { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - e.printStackTrace(); - } setResizable(false); setTitle("Open Type"); setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); diff --git a/src/me/ByteEdit/boxes/UnicodeBox.java b/src/me/ByteEdit/boxes/UnicodeBox.java index 28c59ee..b1dc335 100644 --- a/src/me/ByteEdit/boxes/UnicodeBox.java +++ b/src/me/ByteEdit/boxes/UnicodeBox.java @@ -9,7 +9,6 @@ import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; -import javax.swing.UIManager; import javax.swing.border.EmptyBorder; import me.ByteEdit.main.Main; @@ -20,11 +19,6 @@ public class UnicodeBox extends JFrame { private JPanel contentPane; public UnicodeBox() { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - e.printStackTrace(); - } setResizable(false); setTitle("Unicode Converter"); setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); diff --git a/src/me/ByteEdit/main/Main.java b/src/me/ByteEdit/main/Main.java index e1c78be..55551dc 100644 --- a/src/me/ByteEdit/main/Main.java +++ b/src/me/ByteEdit/main/Main.java @@ -1,6 +1,5 @@ package me.ByteEdit.main; -import java.awt.Color; import java.awt.Component; import java.awt.EventQueue; import java.awt.Font; @@ -49,7 +48,6 @@ import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTree; import javax.swing.KeyStroke; -import javax.swing.UIManager; import javax.swing.border.EmptyBorder; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; @@ -70,7 +68,6 @@ import org.fife.ui.autocomplete.DefaultCompletionProvider; import org.fife.ui.autocomplete.ShorthandCompletion; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.SyntaxConstants; -import org.fife.ui.rsyntaxtextarea.Theme; import org.fife.ui.rsyntaxtextarea.folding.CurlyFoldParser; import org.fife.ui.rsyntaxtextarea.folding.FoldParserManager; import org.fife.ui.rtextarea.RTextScrollPane; @@ -85,6 +82,7 @@ import me.ByteEdit.boxes.GlobalSearchBox; import me.ByteEdit.boxes.OptionBox; import me.ByteEdit.boxes.RenameBox; import me.ByteEdit.boxes.SearchBox; +import me.ByteEdit.boxes.ThemeBox; import me.ByteEdit.boxes.TypeOpenBox; import me.ByteEdit.boxes.UnicodeBox; import me.ByteEdit.edit.Assembler; @@ -111,9 +109,9 @@ public class Main extends JFrame { public static UnicodeBox unicodeBox; public static RenameBox renameBox; public static CompilationBox compilationBox; + public static ThemeBox themeBox; public static JTree tree; public static RTextScrollPane scrollPane_ByteEdit; - public static Theme theme; public static File saveFolder; public static HashSet fakedFolders = new HashSet<>(); @@ -130,11 +128,13 @@ public class Main extends JFrame { try { Main frame = new Main(); frame.setVisible(true); + ThemeManager.applyRSTATheme(); } catch (Exception e) { e.printStackTrace(); } } }); + } /** @@ -200,23 +200,12 @@ public class Main extends JFrame { return provider; } - public static boolean dark = true; - /** * Create the frame. */ public Main() { INSTANCE = this; - File light = new File(System.getProperty("java.io.tmpdir") + File.pathSeparator + "ByteEditLight.conf"); - if (light.exists()) { - dark = false; - } - try { - theme = Theme.load(getClass().getClassLoader() - .getResourceAsStream(dark ? "org/fife/eclipse_dark.xml" : "org/fife/eclipse.xml")); - } catch (IOException e2) { - e2.printStackTrace(); - } + ThemeManager.registerFrames(this); globalSearchBox = new GlobalSearchBox(); searchBox = new SearchBox(); typeOpenBox = new TypeOpenBox(); @@ -224,22 +213,25 @@ public class Main extends JFrame { unicodeBox = new UnicodeBox(); renameBox = new RenameBox(); compilationBox = new CompilationBox(); + themeBox = new ThemeBox(); + ThemeManager.registerFrames(globalSearchBox); + ThemeManager.registerFrames(searchBox); + ThemeManager.registerFrames(typeOpenBox); + ThemeManager.registerFrames(optionBox); + ThemeManager.registerFrames(unicodeBox); + ThemeManager.registerFrames(renameBox); + ThemeManager.registerFrames(compilationBox); + ThemeManager.registerFrames(themeBox); + ThemeManager.load(); setTitle("ByteEdit"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - 407), (int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 - 237), 814, 474); - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - e.printStackTrace(); - } contentPane = new JPanel(); - contentPane.setBackground(dark ? new Color(0x2F2F2F) : Color.GRAY); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(new GridLayout(0, 1, 0, 0)); JSplitPane splitPane = new JSplitPane(); - splitPane.setBackground(dark ? new Color(0x2F2F2F) : Color.GRAY); splitPane.setResizeWeight(0.2); contentPane.add(splitPane); JScrollPane scrollPane = new JScrollPane(); @@ -316,14 +308,9 @@ public class Main extends JFrame { } }); tree.setFont(new Font("Verdana", Font.PLAIN, 11)); - tree.setBackground(dark ? new Color(0x2F2F2F) : Color.LIGHT_GRAY); tree.setCellRenderer(new DefaultTreeCellRenderer() { { putClientProperty("html.disable", Boolean.TRUE); - setBackgroundNonSelectionColor(dark ? new Color(0x2F2F2F) : Color.LIGHT_GRAY); - setBackgroundSelectionColor(Color.GRAY); - setTextNonSelectionColor(dark ? new Color(0xeeeeee) : Color.BLACK); - setTextSelectionColor(dark ? new Color(0xeeeeee) : Color.BLACK); } }); scrollPane.setViewportView(tree); @@ -464,17 +451,7 @@ public class Main extends JFrame { @Override public void actionPerformed(ActionEvent e) { - if (light.exists()) - light.delete(); - else - try { - light.createNewFile(); - } catch (IOException e1) { - } - dark = !dark; - JOptionPane.showMessageDialog(Main.this, - "Theme switched to " + (dark ? "Dark" : "Light") + ".\nPlease restart ByteEdit.", - "Theme changed", JOptionPane.INFORMATION_MESSAGE); + themeBox.setVisible(true); } }, ctrlB, JComponent.WHEN_IN_FOCUSED_WINDOW); txtByteEditView.registerKeyboardAction(new ActionListener() { @@ -566,14 +543,12 @@ public class Main extends JFrame { txtByteEditView.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA_DISASSEMBLE); txtByteEditView.setCodeFoldingEnabled(true); scrollPane_ByteEdit = new RTextScrollPane(); - theme.apply(txtByteEditView); + ThemeManager.registerTextArea(txtByteEditView); splitPane.setRightComponent(scrollPane_ByteEdit); - txtByteEditView.setBackground(dark ? new Color(0x2F2F2F) : Color.LIGHT_GRAY); scrollPane_ByteEdit.setViewportView(txtByteEditView); scrollPane_ByteEdit.setLineNumbersEnabled(true); scrollPane_ByteEdit.setFoldIndicatorEnabled(true); - scrollPane_ByteEdit.getGutter().setBackground(dark ? new Color(0x2F2F2F) : Color.LIGHT_GRAY); } private final Pattern jumpableInstructionPattern = Pattern.compile("^\t\t(?!//|\t+).+ .+"); @@ -787,15 +762,50 @@ public class Main extends JFrame { if (action == 0) { final File file = fileChooser.getSelectedFile(); saveFolder = file.getParentFile(); + boolean shouldSave = false; if (file.exists()) { int dialogResult = JOptionPane.showConfirmDialog(null, "This file already exists! Overwrite it?", "Warning", JOptionPane.YES_NO_OPTION); if (dialogResult == JOptionPane.YES_OPTION) { save(file, classNodes.values()); + shouldSave = true; } } else { - save(file, classNodes.values()); + shouldSave = true; } + + if (shouldSave) + synchronized (treeLock) { + if (isChangingFile) { + return; + } + try { + isChangingFile = true; + try { + Main.this.setTitle("ByteEdit - Saving '" + file.getCanonicalPath() + "'"); + } catch (IOException ex) { + Main.this.setTitle("ByteEdit - Saving '" + file.getAbsolutePath() + "'"); + } + new Thread(new Runnable() { + public void run() { + synchronized (treeLock) { + save(file, classNodes.values()); + EventQueue.invokeLater(new Runnable() { + public void run() { + synchronized (treeLock) { + isChangingFile = false; + Main.this.setTitle("ByteEdit"); + } + } + }); + } + } + }).start(); + } catch (Throwable t) { + t.printStackTrace(); + showError(t); + } + } } } diff --git a/src/me/ByteEdit/main/ThemeManager.java b/src/me/ByteEdit/main/ThemeManager.java new file mode 100644 index 0000000..6ee9d34 --- /dev/null +++ b/src/me/ByteEdit/main/ThemeManager.java @@ -0,0 +1,110 @@ +package me.ByteEdit.main; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JFrame; +import javax.swing.LookAndFeel; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.Theme; + +import com.formdev.flatlaf.IntelliJTheme; +import com.formdev.flatlaf.intellijthemes.FlatArcDarkIJTheme; + +public class ThemeManager { + + private static boolean dark = true; + + private static File file; + + private static Theme rstaThemeDark, rstaThemeLight; + + private static List textAreas = new ArrayList(); + private static List frames = new ArrayList(); + + static { + String s = System.getenv("APPDATA"); + if (s == null) + s = System.getProperty("user.home"); + file = new File(s, "ByteEditTheme.conf"); + } + + public static void save() { + try (BufferedWriter wr = new BufferedWriter(new FileWriter(file))) { + wr.write(UIManager.getLookAndFeel().getClass().getName() + "\n"); + wr.write(Boolean.toString(dark)); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public static void load() { + try { + rstaThemeDark = Theme + .load(ThemeManager.class.getClassLoader().getResourceAsStream("org/fife/eclipse_dark.xml")); + rstaThemeLight = Theme + .load(ThemeManager.class.getClassLoader().getResourceAsStream("org/fife/eclipse.xml")); + } catch (IOException ex) { + ex.printStackTrace(); + } + + String theme = null; + if (file.exists()) { + try (BufferedReader read = new BufferedReader(new FileReader(file))) { + theme = read.readLine(); + boolean dark = Boolean.parseBoolean(read.readLine()); + changeUIManager(theme, dark); + } catch (Exception ex) { + ex.printStackTrace(); + } + } else { + theme = FlatArcDarkIJTheme.class.getName(); + changeUIManager(theme, true); + } + } + + public static void changeUIManager(String clazz, Boolean isDark) { + try { + UIManager.setLookAndFeel(clazz); + LookAndFeel laf = UIManager.getLookAndFeel(); + boolean nextDark = false; + if (laf instanceof IntelliJTheme.ThemeLaf) { + IntelliJTheme.ThemeLaf t = (IntelliJTheme.ThemeLaf) laf; + nextDark = t.isDark(); + } else if (isDark != null) { + nextDark = isDark.booleanValue(); + } + if (nextDark != dark) { + dark = nextDark; + applyRSTATheme(); + } + frames.forEach(SwingUtilities::updateComponentTreeUI); + save(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + public static void applyRSTATheme() { + Theme theme = dark ? rstaThemeDark : rstaThemeLight; + textAreas.forEach(theme::apply); + } + + public static void registerFrames(JFrame frame) { + frames.add(frame); + } + + public static void registerTextArea(RSyntaxTextArea textArea) { + textAreas.add(textArea); + } + +}