今天遇到的一个在main函数中打开TitleAreaDialog的bug

来源:互联网 发布:java经典代码大全例子 编辑:程序博客网 时间:2024/04/28 21:46

这是在网上找的一个解决方案:主要是java中类的加载先后顺序问题

自定义Dialog很简单,下边我们来一步步实现自定义Dialog
一、写一个类,继承自Dialog

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.widgets.Shell;

publicclass TestDialogextends Dialog{

    
public TestDialog(Shell parentShell) {
        
super(parentShell);
     }

}

好了,写好了,如何运行呢?
再写一个类:
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

publicclass Test {
    
publicstatic void main(String[] args){
         Shell shell
= new Shell();
         TestDialog td
= new TestDialog(shell);
         td.setBlockOnOpen(
true);
         td.open();
         Display.getCurrent().dispose();
     }

}

好了运行一下看到效果了吧,带有两个button.
二、看到上边的代码是否会想到别的呢?为什么要再写一个类来运行Dialog,不能在内部写个main方法吗?
我们来试一下:
方法一:参考Jface hello world的的写法:
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

publicclass TestDialogextends Dialog{

    
public TestDialog(Shell parentShell) {
        
super(parentShell);
     }

    
publicstatic void main(String[] args){
         TestDialog td
= new TestDialog(new Shell());
         td.setBlockOnOpen(
true);
         td.open();
         Display.getCurrent().dispose();
     }

}


运行一下看看什么效果,提示找不到main方法。且打印出如下Exception
java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
at org.eclipse.jface.resource.JFaceResources.getResources(JFaceResources.java:184)
at org.eclipse.jface.resource.JFaceResources.getImageRegistry(JFaceResources.java:310)
at org.eclipse.jface.dialogs.Dialog.<clinit>(Dialog.java:211)
Exception in thread "main"
为什么呢?我们是有main方法的,跟进Exception去看看吧。
发现问题出现在Dialog类的这段代码上:
static{
         ImageRegistry reg
= JFaceResources.getImageRegistry();
         reg.put(DLG_IMG_MESSAGE_INFO, ImageDescriptor.createFromFile(
                 Dialog.
class,"images/message_info.gif"));//$NON-NLS-1$
         reg.put(DLG_IMG_MESSAGE_WARNING, ImageDescriptor.createFromFile(
                 Dialog.
class,"images/message_warning.gif"));//$NON-NLS-1$
         reg.put(DLG_IMG_MESSAGE_ERROR, ImageDescriptor.createFromFile(
                 Dialog.
class,"images/message_error.gif"));//$NON-NLS-1$
     }

原来在静态代码块上出现了Exception,造成在运行main函数之前就退出了。所以才说没有main函数。
我们知道classload在加载一个类的时候,对于静态代码块会逐行执行,按照出现的先后顺序。同时父类的静态代码块一定比子类的先执行。因为
在load子类之前会先load父类。这就是为什么hello world中不会出现问题,这里会出现问题的原因。因为Dialog比ApplicationWindow多了这段静态代码。

继续追下去为什么这段代码会出现空指针异常呢,原来这段代码依赖于new Shell()必须先运行。而我们的new Shell()写在main方法里边,肯定是在加载类完成后才能运行的。所以在类内部直接写个main方法是不行的。只能单独写个类来调用。
方法二:
单独写个类如下:

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

publicclass Test {
    
publicstatic void main(String[] args){
         TestDialog td
= new TestDialog(new Shell());
         td.setBlockOnOpen(
true);
         td.open();
         Display.getCurrent().dispose();
     }

}

依然是不行的,报同样的错误,为什么?仔细看一下,我们把new Shell()写在构造函数的参数里,其实范了和刚才同样的错误。所以单独提出new Shell(),写在构造函数之前。就得到了文章开始的Test类。平时我们使用的时候为什么不出这个问题呢?因为我们平时使用的时候Dialog从里不是单独存在的,在之前shell早被构造过了。反而是demo更容易出这个问题。
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 红酒木塞丢了怎么办 红酒塞子进去了怎么办 淘金币即将过期怎么办 淘金币过期怎么办2018 换详情排名下降怎么办 长城宽带不用了怎么办 快递到了想退货怎么办 淘宝退货商家拒收怎么办 淘宝运费险失败怎么办 忘记购买运费险怎么办 咸鱼买家申请退款怎么办 熟猪肉有点变味怎么办 和领导意见不一致怎么办 骑手提前点送达怎么办 ubuntu安装报错怎么办 液相色谱两峰分不开怎么办 液相色谱柱老堵怎么办? 没有装usb驱动怎么办 ipad速度越来越慢怎么办 美萍管理软件打不开怎么办 小米4开机黑屏怎么办 小米电脑死机了怎么办 小米8手机死机怎么办 oppa7开不了机怎么办 oppo手机wlan打不开怎么办 三星s6进水黑屏怎么办 银行卡不支持快捷支付怎么办 路由器忘记管理员密码怎么办 云付没有推荐人怎么办 牛呗审核不通过怎么办 华硕笔记本很卡怎么办 淘宝换货没有货怎么办 用手机怎么办网银 手机销号支付宝怎么办 黑狗狗毛发红怎么办 裤子洗掉色了怎么办 没买快递收到怎么办 淘宝介入卖家不举证怎么办 买家拒收快递货怎么办 买家到付拒收怎么办 买家发顺丰到付又拒收怎么办