Swing/DarkMode の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/DarkMode へ行く。
- Swing/DarkMode の差分を削除
--- category: swing folder: DarkMode title: JEditorPaneのStyleSheetをLight・Darkテーマに合わせて切り替える tags: [JEditorPane, StyleSheet, LookAndFeel, Toolkit, PropertyChangeListener] author: aterai pubdate: 2025-04-07T09:41:23+09:00 description: JEditorPaneのStyleSheetを起動時のシステムテーマがLightかDarkかなどに応じて切り替えるよう設定します。 image: https://drive.google.com/uc?id=1rNhaj-mqEkjn2ntU4yNaMPj-DJOdzBfW --- * Summary [#summary] `JEditorPane`の`StyleSheet`を起動時のシステムテーマが`Light`か`Dark`かなどに応じて切り替えるよう設定します。 #download(https://drive.google.com/uc?id=1rNhaj-mqEkjn2ntU4yNaMPj-DJOdzBfW) * Source Code Examples [#sourcecode] #code(link){{ public static void updateTheme(JEditorPane editor) { updateTheme(editor, isDarkMode()); } public static void updateTheme(JEditorPane editor, boolean isDark) { EditorKit kit = editor.getEditorKit(); HTMLEditorKit htmlEditorKit; if (kit instanceof HTMLEditorKit) { htmlEditorKit = (HTMLEditorKit) kit; } else { htmlEditorKit = new HTMLEditorKit(); } if (isDark) { htmlEditorKit.setStyleSheet(makeDarkStyleSheet()); editor.setBackground(new Color(0x1E_1F_22)); } else { htmlEditorKit.setStyleSheet(makeLightStyleSheet()); editor.setBackground(new Color(0xEE_EE_EE)); } editor.setEditorKit(htmlEditorKit); } public static boolean isDarkMode() { boolean isDark; String os = System.getProperty("os.name").toLowerCase(Locale.ENGLISH); if (os.contains("windows")) { isDark = isWindowsDarkMode(); } else if (os.contains("linux")) { isDark = isLinuxDarkMode(); } else if (os.contains("mac")) { isDark = isMackDarkMode(); } else { isDark = false; } return isDark; } public static String getProcessOutput(String... cmd) throws IOException, InterruptedException { ProcessBuilder builder = new ProcessBuilder(cmd); builder.redirectErrorStream(true); Process p = builder.start(); String str; try (BufferedReader pr = new BufferedReader( new InputStreamReader(p.getInputStream()))) { str = pr.lines().collect(Collectors.joining(System.lineSeparator())); } return str; } public static boolean isWindowsDarkMode() { String[] cmd = { "powershell.exe", "Get-ItemPropertyValue", "-Path", "HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", "-Name", "AppsUseLightTheme;" }; boolean isDarkMode; try { String str = getProcessOutput(cmd).trim(); isDarkMode = Objects.equals("0", str); } catch (IOException | InterruptedException ex) { Logger.getGlobal().severe(ex::getMessage); isDarkMode = false; } return isDarkMode; } public static boolean isLinuxDarkMode() { Toolkit tk = Toolkit.getDefaultToolkit(); Object theme = tk.getDesktopProperty("gnome.Net/ThemeName"); return Objects.toString(theme).contains("dark"); } public static boolean isMackDarkMode() { return false; } // https://raw.githack.com/google/code-prettify/master/styles/index.html // Prettify Themes Gallery public static StyleSheet makeLightStyleSheet() { StyleSheet styleSheet = new StyleSheet(); styleSheet.addRule("pre{background:#eeeeee}"); styleSheet.addRule(".str{color:#008800}"); styleSheet.addRule(".kwd{color:#000088}"); styleSheet.addRule(".com{color:#880000}"); styleSheet.addRule(".typ{color:#660066}"); styleSheet.addRule(".lit{color:#006666}"); styleSheet.addRule(".pun{color:#666600}"); styleSheet.addRule(".pln{color:#000000}"); styleSheet.addRule(".tag{color:#000088}"); styleSheet.addRule(".atn{color:#660066}"); styleSheet.addRule(".atv{color:#008800}"); styleSheet.addRule(".dec{color:#660066}"); return styleSheet; } public static StyleSheet makeDarkStyleSheet() { StyleSheet styleSheet = new StyleSheet(); styleSheet.addRule("pre{background:#1e1f22}"); styleSheet.addRule(".str{color:#ffa0a0}"); styleSheet.addRule(".kwd{color:#f0e68c;font-weight:bold}"); styleSheet.addRule(".com{color:#87ceeb}"); styleSheet.addRule(".typ{color:#98fb98}"); styleSheet.addRule(".lit{color:#cd5c5c}"); styleSheet.addRule(".pun{color:#ffffff}"); styleSheet.addRule(".pln{color:#ffffff}"); styleSheet.addRule(".tag{color:#f0e68c;font-weight:bold}"); styleSheet.addRule(".atn{color:#bdb76b;font-weight:bold}"); styleSheet.addRule(".atv{color:#ffa0a0}"); styleSheet.addRule(".dec{color:#98fb98}"); return styleSheet; } }} * Explanation [#explanation] - `OS`が`Windows`の場合、個人用設定の色をライト、ダークで切り替えても`Swing`アプリ側でそのイベントを取得できない -- `Windows 7`などでは[[DesktopPropertyの変更を監視する>Swing/DesktopProperty]]のように`Toolkit`に`PropertyChangeListener`を追加することで画面の配色変更を取得可能だったが、`Windows 10`や`Windows 11`では動作しない? -- このサンプルでは、起動時や`JRadioButtonMenuItem`でテーマを手動切り替えしたときに、レジストリから`HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize`の値を取得して`0`の場合は`Dark`テーマと判断し、`StyleSheet`の切り替えを実行 -- [https://gist.github.com/HanSolo/7cf10b86efff8ca2845bf5ec2dd0fe1d Detector: A plain Java class that offers some utility methods to detect dark theme on MacOS and Windows · GitHub] - `OS`が`Linux(Ubuntu+gnome)`の場合、設定の外観、スタイルをデフォルト(ライト)、ダークで切り替えると、`Swing`アプリ側でもそのイベントを取得可能 -- `GTKLookAndFeel`はデフォルトでスタイル切り替えが発生すると`SynthTheme`を切り替えて各コンポーネントの配色を変更している -- 以下のように、`Toolkit`にデスクトッププロパティを`gnome.Net/ThemeName`として`PropertyChangeListener`を追加すればスタイル切り替えイベントを取得可能なので、テーマ名に`dark`が含まれる場合は`Dark`テーマと判断し、`StyleSheet`の切り替えを実行 #code{{ String key = "gnome.Net/ThemeName"; Toolkit.getDefaultToolkit().addPropertyChangeListener(key, e -> { if (sys.isSelected()) { boolean isDark = Objects.toString(e.getNewValue()).contains("dark"); ThemeUtils.updateTheme(editor, isDark); loadHtml(editor); } }); }} - `OS`が`Mac`の場合、このサンプルでは未対応 - `OS`が`Mac`の場合には、このサンプルは未対応だが、以下のサイトの方法で対応可能 -- [https://github.com/Dansoftowner/jSystemThemeDetector Dansoftowner/jSystemThemeDetector: Java library for detecting that the (desktop) operating system uses dark UI theme or not] -- [https://gist.github.com/HanSolo/7cf10b86efff8ca2845bf5ec2dd0fe1d Detector: A plain Java class that offers some utility methods to detect dark theme on MacOS and Windows · GitHub] * Reference [#reference] - [https://github.com/Dansoftowner/jSystemThemeDetector Dansoftowner/jSystemThemeDetector: Java library for detecting that the (desktop) operating system uses dark UI theme or not] - [https://gist.github.com/HanSolo/7cf10b86efff8ca2845bf5ec2dd0fe1d Detector: A plain Java class that offers some utility methods to detect dark theme on MacOS and Windows · GitHub] -- via: [https://harmoniccode.blogspot.com/2021/02/poor-mans-dark-mode-detection.html Harmonic Code: "Poor man's" dark mode detection] - [https://raw.githack.com/google/code-prettify/master/styles/index.html Prettify Themes Gallery] - [[DesktopPropertyの変更を監視する>Swing/DesktopProperty]] * Comment [#comment] #comment #comment