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.iteye.com/topic/400574?page=1   这个帖子中楼主的问题。如果有大家有什么更好的方法,请大家不吝赐教!

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

你可能感兴趣的:(java,jdk,swing,sun,seam)