分享
 
 
 

[原创]Swing技巧8:完美的LookAndFeel解决方案

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

[原创]Swing技巧8:完美的LookAndFeel解决方案

Swing技巧8:完美的LookAndFeel解决方案

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();

这次在setLookAndFeel时正常退出了.

再查发现java.awt.Window.dispose:When the last displayable window within the Java virtual machine (VM) is disposed of, the VM may terminate.

就是说最后一个窗口dispose后JVM可能退出.

玩个小花招,不让它是the last displayable window:

Frame temp=new Frame();

temp.show();

temp.hide();

frame.dispose();

frame.setUndecorated(true);

frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);

frame.show();

temp.dispose();

成功了,达到我希望的效果:窗口,边框,标题的LookAndFeel随着setLookAndFeel而更改,如果是对没有窗口,边框,标题的LookAndFeel那么就使用System的系统窗口,边框,标题.

这样可以说是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 temp=new Frame();

temp.show();

temp.hide();

frame.dispose();

frame.setUndecorated(lnf.getSupportsWindowDecorations());

frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);

frame.show();

temp.dispose();

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 temp=new Frame();

temp.show();

temp.hide();

frame.dispose();

frame.setUndecorated(lnf.getSupportsWindowDecorations());

frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);

frame.show();

temp.dispose();

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.对setLookAndFeel中的temp,更好应该是在程序开始时

Frame temp=new Frame();

temp.show();

temp.hide();

结束时

temp.dispose();

效果一样,但节约资源,setLookAndFeel中就可以直接

frame.dispose();

frame.setUndecorated(true);

frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);

frame.show();

不过,这样很容易忘了temp,导致无法退出,必须使用System.exit().

3.为什么对JFrame和JDialog,有一个完全相同的setLookAndFeel?

因为Swing的继承体系:

Window

/ | Frame | Dialog

| | |

| JWindow |

| |

JFrame JDialog

setUndecorated只有JFrame和JDialog中有.

很奇怪的继承体系,不是吗?JFrame和JDialog也应该是JWindow的子类,这样才符合直觉.但java是单根继承的,sun又该死的弄了两套gui,awt和swing.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有