浏览 3042 次
该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-01-10
在 Swing技巧4:设置系统窗口,边框,标题,最小化,还原,最大化按钮 和 Swing技巧5:运行中重设LookAndFeel 中,我使用 if(currentLookAndFeel.getSupportsWindowDecorations()){ frame.setUndecorated(true); frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME); } 和 public static void setLookAndFeel(Component target, LookAndFeel lnf){ try{ UIManager.setLookAndFeel(lnf); SwingUtilities.updateComponentTreeUI(target); }catch(Exception e){ System.out.println("ERROR: " + e); } } 达到不但设置LookAndFeel,更使系统窗口,边框,标题,最小化,还原,最大化按钮也有LookAndFeel的目的. 但此种方法缺点也很明显: 1.Matrix网友sslazio21反映新弹出的JFileChooser的系统窗口边框任为System LookAndFeel 2.对没有系统窗口,边框,标题的LookAndFeel,比如Windows,Motif及他们的子类,根JFrame也就没有系统窗口,边框,标题,导致无法最小化,还原,最大,改变大小. 1的解决方法是我在Swing技巧4:设置系统窗口,边框,标题,最小化,还原,最大化按钮中提到的方法1:全局设置 //JFrame,JDialog.setDefaultLookAndFeelDecorated //static global setting //Provides a hint as to whether or not newly created JDialogs and JFrames should have their Window decorations //(such as borders, widgets to close the window, title...) provided by the current look and feel. JFrame.setDefaultLookAndFeelDecorated(true); 完整的初始化是 try{ Class lafClass=Class.forName(currentLookAndFeel); LookAndFeel laf=(LookAndFeel)(lafClass.newInstance()); JFrame.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations()); JDialog.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations()); }catch(Exception e){} 必须对JFrame和JDialog都设置. 注意frame.setUndecorated(true)和JFrame.setDefaultLookAndFeelDecorated(true)必须在窗口显示之前,也就是frame.show()或frame.setVisible(true)之前. 因为setUndecorated的java doc说This method can only be called while the frame is not displayable. setDefaultLookAndFeelDecorated的java doc说newly created JDialogs and JFrames,对新建窗口有效. 对于2,我希望窗口,边框,标题的LookAndFeel随着setLookAndFeel而更改,如果是对没有窗口,边框,标题的LookAndFeel那么就使用System的系统窗口,边框,标题. 除了前面的初始化以外,我还改一下setLookAndFeel: public static void setLookAndFeel(Component target, LookAndFeel lnf){ try{ JFrame.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations()); JDialog.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations()); UIManager.setLookAndFeel(lnf); SwingUtilities.updateComponentTreeUI(target); }catch(Exception e){ System.out.println("ERROR: " + e); } } 对新建窗口(新弹出的JFileChooser)是有效了,但对已经存在的窗口,边框,标题不会改变. 看来对已经存在的窗口,必须使用 frame.setUndecorated(true); frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME); 但有setUndecorated:This method can only be called while the frame is not displayable. 试试 frame.hide(); frame.setUndecorated(true); frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME); frame.show(); 不但没有效果,在setLookAndFeel时还失去响应. 查java doc发现the frame is not displayable的状态只有在frame的第一次show()之前和dispose()以后. 只有dispose()以后了: frame.dispose(); frame.setUndecorated(true); frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME); frame.show(); 这样可以说是Swing LookAndFeel的完美解决方案,最终代码如下: 初始化时,第一个窗口建立之前: try{ Class lafClass=Class.forName(currentLookAndFeel); LookAndFeel laf=(LookAndFeel)(lafClass.newInstance()); JFrame.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations()); JDialog.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations()); }catch(Exception e){} public static void setLookAndFeel(JFrame frame, LookAndFeel lnf){ try{ //改变全局设置 JFrame.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations()); JDialog.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations()); UIManager.setLookAndFeel(lnf); //改变当前frame的窗口,边框,标题 frame.dispose(); frame.setUndecorated(lnf.getSupportsWindowDecorations()); frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME); frame.show(); SwingUtilities.updateComponentTreeUI(frame); }catch(Exception e){ System.out.println("ERROR: " + e); } } 很不幸,对JDialog必须也有一个,虽然只改了一个单词,还是要有. public static void setLookAndFeel(JDialog frame, LookAndFeel lnf){ try{ //改变全局设置 JFrame.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations()); JDialog.setDefaultLookAndFeelDecorated(laf.getSupportsWindowDecorations()); UIManager.setLookAndFeel(lnf); //改变当前frame的窗口,边框,标题 frame.dispose(); frame.setUndecorated(lnf.getSupportsWindowDecorations()); frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME); frame.show(); SwingUtilities.updateComponentTreeUI(frame); }catch(Exception e){ System.out.println("ERROR: " + e); } } 参考资料: 1.Java Docs 2.Swing技巧5:运行中重设LookAndFeel,来自SwingSet2源码 3.Swing技巧4:设置系统窗口,边框,标题,最小化,还原,最大化按钮,中第二种方法,来自BeanBuilder源码 PS: 1.用此种方法改造的SwingSet2: 『 点击下载 』 可以用ant编译. 只改了SwingSet2.java文件,大家可以用Windiff(Vc6中有)或WinMerge与原始文件(在%Java_home%\demo\jfc\SwingSet2\SwingSet2.jar\src\中)比较. 第三方LookAndFeel,可以到 www.javootoo.com 下载,放在%Java_home%\jre\lib\ext\中.中 2.为什么对JFrame和JDialog,有一个完全相同的setLookAndFeel? 因为Swing的继承体系: Window / | Frame | Dialog | | | | JWindow | | | JFrame JDialog setUndecorated只有JFrame和JDialog中有. 很奇怪的继承体系,不是吗?JFrame和JDialog也应该是JWindow的子类,这样才符合直觉.但java是单根继承的,sun又该死的弄了两套gui,awt和swing. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |