今天遇到的一个在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更容易出这个问题。
自定义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更容易出这个问题。
相关文章推荐
- 今天遇到这样一个bug
- 今天遇到一个url转码的bug
- 今天遇到的一个bug,折腾了一早上,不过解决了,还是很高兴
- 今天遇到一个url转码的bug
- 解决工作中遇到的一个"打开,保存"文件框的bug的过程
- 今天改bug遇到一个ie8样式错乱问题
- 今天遇到一个关于STL中排序的问题, 怀疑是sort的bug!
- 今天遇到一个由于内存访问越界而引起的bug
- 今天改bug遇到一个ie8样式错乱问题
- 今天遇到的一个BUG :app:compileDebugJavaWithJavac'. Could not add entry '0' to cache localClassSetAnalysis.b
- 11.22 今天遇到一个奇怪的Warning
- 真的无语, 今天遇到一个奇葩的事情: http 会话劫持
- java swt TitleAreaDialog 添加滚动条
- 今天安装 Atlas 时遇到一个小问题
- 今天遇到的一个小坑,js传参 转义符(\)的问题
- 今天在Mac机器上使用了Flex Builder编辑了一个源代码文件,保存后使用vim命令去打开时发现系统自动在每一行的结尾添加了^M符号,其实^M在Linux/Unix中是非常常见的,也就是我们在Win中见过的/r回车符号。由于编辑软件的编码问题,某些IDE的编辑器在编辑完文件之后会自动加上这个^M符号。看起来对我们的源代码没有任何影响,其实并不然,当我们把源代码文件Check In到svn之类
- 当流行歌曲遇到程序猿——有没有那么一个bug,会让你突然想起我
- 今天遇到了这样一个问题 Exception in thread "main" org.hibernate.LazyInitializationException: could not initiali
- jface TitleAreaDialog 实现 详细编程
- 2013-5-25 1. “已有打开的与此命令相关联的 DataReader,必须首先将它关闭。"问题. 上周在项目开发中,遇到这样的一个问题,在前台展示页,两个WebPart调用后台的AP