zoukankan      html  css  js  c++  java
  • swt/jface 自定义 Dialog

    swt/jface 自定义 Dialog

    自定义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);如果想加入其他的图片,调用相应的常量。

    SourceCode
  • 相关阅读:
    Numpy存字符串
    一个类似于postman的协议测试工具
    freetds设置超时
    学习jQuery
    webpy 使用python3开发
    gdb调试coredump文件
    htop和ncdu
    rqalpha-自动量化交易系统(一)
    perl学习-运算符添加引号
    xss 和 csrf攻击详解
  • 原文地址:https://www.cnblogs.com/kentyshang/p/858300.html
Copyright © 2011-2022 走看看