swt/jface 自定义 Dialog

系统 1542 0

自定义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天生带的两个按钮不错,但我们有的时候并不想要这两个按钮,怎么办,如何去掉它?
简单,只要我们覆盖父类的createButtonsForButtonBar这个方法就可以了,覆写这个方法,里边什么也不写

protected   void  createButtonsForButtonBar(Composite parent)  {
    }


看一下按钮消失了。
四、加入右上角的最大化和关闭
覆写父类的这个方法:

protected   int  getShellStyle() {
        
return   super .getShellStyle() | SWT.RESIZE | SWT.MAX;
    }


五、改变Dialog的大小
覆写这个方法:

protected  Point getInitialSize() {
        
return   new  Point( 300 , 400 ); // 300是宽400是高
    }

六、加入自己的控件
覆写createDialogArea方法

protected  Control createDialogArea(Composite parent)  {
        Composite container 
=  (Composite)  super .createDialogArea(parent);
        container.setLayout(
new  RowLayout());
        text 
=   new  Text(container, SWT.BORDER);
        text.setLayoutData(
new  RowData( 100 , - 1 ));
        
return  container;
    }


这里使用了RowLayout
七、加入自己的按钮
覆写initializeBounds

protected   void  initializeBounds() {
        Composite comp 
=  (Composite)getButtonBar();
        
super .createButton(comp, IDialogConstants.OK_ID,  " 完成 " true );
    }

好了这里自定义Dialog完成了,然后根据你的需要再Dialog中添加更负载的控件,更多的按钮。最后目的当然是从Dialog取道数值。
八、带提示框的Dialog
使用方法和前边相同,不同的是不是继承自Dialog而是继承自TitleAreaDialog,然后在createDialogArea中加入两行

setTitle( " 标题 " );
setMessage(
" 提示信息 " )
// setMessage可以加上图片,加入的办法是setMessage("提示信息",IMessageProvider.WARNING);如果想加入其他的图片,调用相应的常量。

swt/jface 自定义 Dialog


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论