Swt中自定义对话框的总结

在rcp开发中,要自定义对话框,首先要继承org.eclipse.jface.dialogs.Dialog
public class MyDialog extends Dialog
1,定义对话框大小,需要重写getInitialSize方法
@Override
protected Point getInitialSize() {
return new Point(540,480);
}

2,定义对话框界面,需要重写createDialogArea方法.以下是org.eclipse.jface.
dialogs.Dialog的createDialogArea方法的源码,我们可以根据需要在里面添加自己需要的组件
protected Control createDialogArea(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
composite.setLayout(layout);
composite.setLayoutData(new GridData(GridData.FILL_BOTH));
applyDialogFont(composite);
//Group group = new Group(composite,SWT.NONE);
//……添加自己的组件
return composite;
}

3,自定义对话框按钮.需要重写createButton和initializeBounds两个方法.org.ecli
Pse.jface.dialogs.Dialog根据按钮的ID来管理按钮,这个类有两个默认的按钮,OK和CANCEL,ID分别为IDialogConstants.OK_ID, IDialogConstants.CANCEL_ID.我们重载createButton方法,使其失效:
@Override
protected Button createButton(Composite parent, int id, String label,boolean defaultButton) {
return null;
}

这样就不会创建那两个默认的不受我们控制的按钮.然后重载initializeBounds方法,我们在这个方法里面创建我们自己的按钮:
public static final int APPLY_ID = 2;
@Override
protected void initializeBounds() {
//我们可以利用原有的ID创建按钮,也可以用自定义的ID创建按钮
//但是调用的都是父类的createButton方法.
super.createButton((Composite)getButtonBar(), IDialogConstants.OK_ID, "确定", false);
super.createButton((Composite)getButtonBar(), IDialogConstants.CANCEL_ID, "取消", false);
super.createButton((Composite)getButtonBar(), APPLY_ID, "应用", false);
//下面这个方法一定要加上,并且要放在创建按钮之后,否则就不会创建按钮
super.initializeBounds();
}

4,其实, org.eclipse.jface.dialogs.Dialog类中专门有一个Map,叫buttons,用于存放我们在initializeBounds方法中创建的按钮,我们可以通过getButton(int id)方法来取到按钮,对其进行操作,比如:
Button btn = getButton(APPLY_ID);
btn.setEnabled(false);//让按钮失效
btn.removeSelectionListener(this);//移除按钮的监听事件

5,调用super.createButton方法的时候,该方法会自动给已创建的按钮添加选中事件的监听器SelectionListener.我们无法利用该监听器来做事情,但是幸好Dialog给我们提供了一个方法, buttonPressed(int buttonId),从字面上我们就能理解这个方法的作用,我们重载它:
@Override
protected void buttonPressed(int buttonId) {
if (buttonId == IDialogConstants.OK_ID) {
//做我们想做的事情
}
//事后要记得调用父类的buttonPressed方法
super.buttonPressed(buttonId);
}

6,如果我们想从对话框的组件中取值,那是不能直接取到的.如果我们的Dialog中有一个Text组件叫text(要作为类的域对象),要取他的值,需要一个变量(假设为String value)来存储,把这个value作为类的域对象,给它添加get和set方法,然后在buttonPressed方法中这样做:
@Override
protected void buttonPressed(int buttonId) {
if (buttonId == IDialogConstants.OK_ID) {
//如果按了OK按钮,就把text的值放入value对象中
setValue(text.getText());
}
super.buttonPressed(buttonId);
}

我们打开该对话框的代码如下:
MyDialog md = new MyDialog(this.getShell);
md.setValue(“初值”);// 在open之前,把值放入value中
If(md.open() == IDialogConstants.OK_ID){
//如果按了OK按钮,就取出value的值(其实就是text的值)
String str = md.getValue();
}

我们无法直接取到text的值,是因为按了initializeBounds创建的按钮之后,对话框会退出,里面的组件会被销毁,我们再取,就会出错.
7,给对话框组件设置值.同样,我们不能直接设置值.因为在open方法之前,组件还没有创建.
我们可以在open之前,把值放入value中,在createDialogArea方法里面,创建text的时候,把 value放到text中
protected Control createDialogArea(Composite parent) {
//…………………
text = new Text(composite,SWT.NONE);
text.setText(value == null ? "":value);// setText不接受null值,所以......
//…………………
}

你可能感兴趣的:(eclipse)