Swing 本地外观与Substance外观之间的切换问题及解决方案

    Swing应用程序如果是在开源的Look&&Feel 之间切换,感觉很容易,但是如果 把应用程序在开源外观下切换到系统默认的或者JDK自带的外观时,问题就来了。 不是没有标题栏,就是标题栏的外观没有改变,用的是系统的窗口装饰。这些是因为在应用程序启动时在main方法里添加了这样一句代码造成的:
   
JFrame.setDefaultLookAndFeelDecorated( true );

目前解决这个问题的办法就是先将 原来的JFrame dispose掉 ,然后在new一个 JFrame ,让原来的frame 指向这个新的JFrame。不多说,看代码比较直观, 核心代码如下:

    初始化应用,initComponents()方法是NetBeans IDE生成的,就不贴了。

  

    private   static  JFrame config;
    
private  Rectangle savedBounds;



    
/**  Creates new form Config  */
    
public  SkinChangeDemo() {
        initComponents();
    }

    
public  SkinChangeDemo( boolean  decor) {
        setUndecorated(decor);
        initComponents();
    }


下面就是核心代码:

  private   void  saharaButtonActionPerformed(java.awt.event.ActionEvent evt) {                                             
        
//  TODO add your handling code here:
        LookAndFeel old  =  UIManager.getLookAndFeel();
        SubstanceSkin skin 
=   new  SaharaSkin();
        
if  (old  instanceof  SubstanceLookAndFeel) {
            SubstanceLookAndFeel.setSkin(skin);
        } 
else  {    // 如果不是Substance的外观则切换为Substance外观
                changSkin(skin);
        }
    }                                            

    
private   void  nimbusButtonActionPerformed(java.awt.event.ActionEvent evt) {                                             
        
try  {
            UIManager.setLookAndFeel(
new  NimbusLookAndFeel());
            savedBounds 
=  getBounds();
            dispose();
            config 
=   null ;
            config 
=   new  SkinChangeDemo( false );
            config.setBounds(savedBounds);
            config.setVisible(
true );
        } 
catch  (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(SkinChangeDemo.
class .getName()).log(Level.SEVERE,  null , ex);
        }
        SwingUtilities.updateComponentTreeUI(
this );

    }                                            

    
private   void  businessButtonActionPerformed(java.awt.event.ActionEvent evt) {                                               
        LookAndFeel old 
=  UIManager.getLookAndFeel();
        SubstanceSkin skin 
=   new  BusinessSkin();
        
if  (old  instanceof  SubstanceLookAndFeel) {
            SubstanceLookAndFeel.setSkin(skin);
        } 
else  {     // 如果不是Substance的外观则切换为Substance外观
            changSkin(skin);
        }
    }                                              

    
/**
     *用于将非Substance 外观的界面该为Substance外观。
     * 
@param  skin
     
*/
    
private   void  changSkin(SubstanceSkin skin) {
        savedBounds 
=  getBounds();
        dispose();
        config 
=   new  SkinChangeDemo( true );
        config.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);  
// 这句是关键代码,自己看API体会吧
        config.setBounds(savedBounds);   // 保持变换皮肤时位置不变
        SubstanceLookAndFeel.setSkin(skin);
        config.setVisible(
true );
        config.getRootPane().updateUI();
        SwingUtilities.updateComponentTreeUI(
this );

    }

main方法:
  public   static   void  main(String args[]) {

        JFrame.setDefaultLookAndFeelDecorated(
true );
        JDialog.setDefaultLookAndFeelDecorated(
true );
        
try  {
            
// 新建一个图片水印,路径可以自己该,使用自己喜欢的图片来做应用程序的水印图片、
            SubstanceImageWatermark watermark  =   new  SubstanceImageWatermark(SkinChangeDemo. class .getResourceAsStream( " /demo/031be.jpg " ));
            watermark.setKind(ImageWatermarkKind.APP_CENTER);
            watermark.setOpacity((
float 0.7 );
            UIManager.setLookAndFeel(
new  SubstanceOfficeBlue2007LookAndFeel());
            SubstanceSkin skin 
=   new  OfficeBlue2007Skin().withWatermark(watermark);

            SubstanceLookAndFeel.setSkin(skin);

        } 
catch  (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(SkinChangeDemo.
class .getName()).log(Level.SEVERE,  null , ex);
        }
        java.awt.EventQueue.invokeLater(
new  Runnable() {

            
public   void  run() {
                config 
=   new  SkinChangeDemo();
                config.setVisible(
true );
                config.setLocationRelativeTo(
null );
            }
        });
    }

点击不同的按钮呈现不同的外观,JDK里的和开源的外观之间切换。



 没水印的效果图:






BTW: 这篇文章里的内容,正好可以回答http://www.javaeye.com/topic/400574?page=1   这个帖子中楼主的问题。

      如果有大家有什么更好的   方法,请大家不吝赐教!

     源代码以上传,有需要的自己下载: Demo3


你可能感兴趣的:(Swing 本地外观与Substance外观之间的切换问题及解决方案)