您的位置:首页 > 大数据 > 人工智能

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

2011-11-06 23:56 465 查看
这是在网上找的一个解决方案:主要是java中类的加载先后顺序问题

自定义Dialog很简单,下边我们来一步步实现自定义Dialog

一、写一个类,继承自Dialog


import org.eclipse.jface.dialogs.Dialog;


import org.eclipse.swt.widgets.Shell;






public
class TestDialog
extends Dialog


{






public
TestDialog(Shell parentShell)

{


super(parentShell);


}


}



好了,写好了,如何运行呢?

再写一个类:


import org.eclipse.swt.widgets.Display;


import org.eclipse.swt.widgets.Shell;






public
class Test


{




public
static
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;






public
class TestDialog
extends Dialog


{






public
TestDialog(Shell parentShell)

{


super(parentShell);


}




public
static
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;






public
class Test


{




public
static
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更容易出这个问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐