首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Swing 外觀切換演示:UIManager 動態更換 LookAndFeel 完整代碼

     編輯:Java 相關知識

前言

Swing 支援即插即用的外觀架構,允許運行時動態切換 LookAndFeel (LAF)。本文演示如何枚舉系統安裝的 LAF、創建按鈕一鍵切換、使用 SwingUtilities.updateComponentTreeUI 遞歸更新組件樹,提供完整可運行代碼。

程序入口:PlafTest

使用 EventQueue.invokeLater 確保 GUI 構建在 EDT 執行,創建並顯示主窗體。

public class PlafTest {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            PlafFrame frame = new PlafFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}

主窗體:PlafFrame

構造函數中獲取所有已安裝 LAF (UIManager.getInstalledLookAndFeels()),為每個 LAF 動態創建按鈕,點擊時切換外觀並更新組件樹。

class PlafFrame extends JFrame {
    private JPanel buttonPanel;

    public PlafFrame() {
        this.setTitle("PlafTest - 外觀切換演示");
        this.setSize(400, 300);

        buttonPanel = new JPanel();
        
        // 獲取所有已安裝的 LookAndFeel
        UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels();
        for (UIManager.LookAndFeelInfo info : infos) {
            makeButton(info.getName(), info.getClassName());
        }

        this.add(buttonPanel);
    }

    private void makeButton(String name, final String className) {
        JButton button = new JButton(name);
        buttonPanel.add(button);

        button.addActionListener(e -> {
            try {
                // 設置新的 LookAndFeel
                UIManager.setLookAndFeel(className);
                // 遞歸更新整個組件樹
                SwingUtilities.updateComponentTreeUI(PlafFrame.this);
            } catch (ClassNotFoundException | InstantiationException
                     | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                ex.printStackTrace();
            }
        });
    }
}

核心 API 解析

API作用關鍵點
UIManager.getInstalledLookAndFeels()獲取系統註冊的所有 LAF返回 LookAndFeelInfo[],含名稱與類全限定名
UIManager.setLookAndFeel(className)設置當前應用的 LAF影響後續創建的組件,現有組件需手動更新
SwingUtilities.updateComponentTreeUI(Component)遞歸更新組件及其子組件 UI調用每個組件的 updateUI() 方法,實現熱切換
EventQueue.invokeLater(Runnable)在 EDT 中異步執行任務保證 Swing 組件創建/修改的線程安全

常見內置 LookAndFeel

  • Metal:javax.swing.plaf.metal.MetalLookAndFeel (跨平台默認)
  • Nimbus:javax.swing.plaf.nimbus.NimbusLookAndFeel (Java 6u10+ 現代風格)
  • Windows:com.sun.java.swing.plaf.windows.WindowsLookAndFeel (僅 Windows)
  • Windows Classic:com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel
  • Mac OS X:com.apple.laf.AquaLookAndFeel (僅 macOS)
  • GTK+:com.sun.java.swing.plaf.gtk.GTKLookAndFeel (Linux)
  • Motif:com.sun.java.swing.plaf.motif.MotifLookAndFeel

進階應用場景

  1. 用戶偏好持久化:將選擇的 LAF 類名存入 Preferences/配置文件,啟動時自動應用
  2. 第三方 LAF 整合:FlatLaf、Substance、Synthetica 等現代美觀主題,需添加依賴並註冊
  3. 高 DPI 適配:Nimbus/FlatLaf 原生支援 HiDPI,Metal 需設置 sun.java2d.uiScale
  4. 運行時主題切換:深色/深色模式切換,結合 FlatLaf 的 FlatLightLaf/FlatDarkLaf
  5. 自定義 LAF 開發:繼承 BasicLookAndFeel 實現企業級統一視覺規範

注意事項與最佳實踐

  • 切換時機:建議在應用啟動早期設置 LAF,避免大量組件創建後批量更新閃爍
  • 異常處理:完整捕獲四種受檢異常,UnsupportedLookAndFeelException 表示當前平台不支援
  • 組件樹更新:updateComponentTreeUI 僅更新已掛載組件,動態添加的新組件自動使用新 LAF
  • 原生對話框:JFileChooser、JColorChooser 等重量級組件可能不受 LAF 影響
  • 性能影響:頻繁切換 LAF 會導致大量 UI 重建,用戶操作間應加防抖
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved