《Eclipse SWT/JFACE 核心应用》 清华大学出版社 16 JFace对话框
16.1 JFace对话框概述
◆ ErrorDialog:可根据错误级别来显示错误信息,一般用于Eclipse工作台。
◆ MessageDialog:可显示提示信息的对话框,类似于SWT的对话框,但比SWT功能强大。
◆ MessageDialogWithToggle:一般在保存首选项所设置的值时显示是否保存的提示信息。
◆ ProgressMonitorDialog:可以显示后台线程进度的对话框。
◆ InputDialog:用于输入信息的对话框,同时可以验证用户的输入,并可以将验证的信息显示在对话框中。
◆ PreferenceDialog:专门为设置首选项所使用的对话框。
◆ TitleAreaDialog:带有标题、图标和描述信息的对话框。
◆ WizardDialog:向导式对话框。
16.2 信息提示对话框(MessageDialog)
各种类型的信息提示对话框示例:
package www.swt.com.ch16;
import> GridLayout gridLayout = new GridLayout (6,false);
> GridData data = new GridData(GridData.FILL_BOTH);
> console.setLayoutData( data);
Button> openError.setText("错误消息对话框");
> openConfirm.setText("确认消息对话框");
> "确认消息对话框",
"确实要保存文件吗?");
> openInformation.setText("消息对话框");
> openQuestion.setText("询问对话框");
> console.append("\n openQuestion对话框,返回"+b);
}
});
Button> openWarning.setText("警告对话框");
> customMessageDig.setText("自定义对话框");
> "这是对话框的标题",//标题
> console.append("\n 自定义对话框,返回按钮的索引值"+i);
}
});
> test.setBlockOnOpen( true );
>
JFace的本地化
1. 现象:例如,警告对话框中的按钮显示的文字为“OK”,而不是“确定”。
2. 原因:SWT中的对话框是调用本地操作系统的对话框,它显示的按钮是根据本地操作系统的语言设定的。而JFace中的对话框是通过SWT的Shell窗口封装来的,调用的是SWT中的Button控件对象。下面是源码:
public> dialog.open();
return;
}
按钮的文字通过IDialogConstants.OK_LABEL字符常量来设定,而常量在IDialogConstants类中的值为:
public String OK_LABEL = JFaceResources.getString("OK");
在JFaceResources类中可以发现,这个字符是根据org.eclipse.jface包中messages*.properties文件所指定的ResourceBundle文件来获取的,也就是获取的本地的语言包。
private> 当前所运行的JFace环境中没有这个语言包,所以不能显示中文,只能以默认的英文来显示。所以,要使JFace的对话框本地化,要找到语言包然后导入到项目工程中即可。
安装JFace语言包参考:JFace的本地化及安装JFace语言包
本地化后:
注意“OK”和“确定”按钮。
16.3 输入对话框(InputDialog)
输入对话框(InputDialog类)可以提示用户输入一段文本,并且也判断输入字符的有效性,当输入错误时将错误信息返回给用户。
输入对话框:
package www.swt.com.ch16;
import> composite.setLayout( new GridLayout());
Button> button.setText("打开输入对话框");
> "输入电子邮件",//对话框的标题
"请输入电子邮件地址:",//对话框的提示信息
"输入框中默认值
new EmailValidator()//验证输入字符的有效性
);
> if (r==Window.OK)//如果输入有效,则输出输入的值
System.out.println(inputDialog.getValue());
> test.setBlockOnOpen( true );
test.open();
Display.getCurrent().dispose();
}
}
输入对话框内容有效性的验证:
package www.swt.com.ch16;
import> return "错误!请输入有效的电子邮件地址。";
>
16.4 带有提示信息的对话框(TitleAreaDialog)
带有提示信息的对话框(TitleAreaDialog类)可在标题上显示提示的信息,提示信息类别的不同,将显示不同的图标。
带有提示信息的对话框可以根据用户当前的输入提示错误的消息,创建这样的对话框需使用继承的方式,然后覆盖父类的方法。
package www.swt.com.ch16;
import> public InputPasswordDialog(Shell parentShell) {
> composite.setLayout( new GridLayout(2,true));
> userName.addFocusListener( new FocusAdapter(){
//当用户名文本框失去焦点时,判断是否有效
> password.setEchoChar('*');
> confirmPassword.setEchoChar('*');
confirmPassword.addFocusListener( new FocusAdapter(){
//当确认密码文本框失去焦点时,判断是否有效
public void focusLost(FocusEvent e) {
checkValid();
}
});
return parent;
}
//判断是是否输入有效,并提示用户
protected void checkValid() {
if (!password.getText().equals(confirmPassword.getText()))
setMessage("确认密码不一致,请重新输入!",IMessageProvider.WARNING);
else if ( userName.getText().equals(""))
setMessage("用户名不能为空!",IMessageProvider.ERROR);
else
setMessage(DEFAULT_INFO);
}
}
下面是执行代码:
package www.swt.com.ch16;
import> button.setText("打开输入对话框");
> dialog.open();
}
});
> test.setBlockOnOpen( true );
>
密码不一致后:
在使用TitleAreaDialog类时,应注意以下几个问题:
◆ 创建窗口所显示的内容要通过继承TitleAreaDialog类的方式,而不能直接创建。例如,运行以下代码会抛出异常:
TitleAreaDialog> dialog.setMessage("这种方式是错误的!"); // 错误!
dialog.open();
◆ 当继承TitleAreaDialog类时,通常要调用父类的以下几个方法:
◇ Control createContents(Composite parent):该方法创建一个顶级容器来放置显示消息的部分和输入区域的部分。
◇ Control createDialogArea(Composite parent):创建对话框输入区域的控件,一般都要覆盖此方法。
◆ 另外,TitleAreaDialog类还有一些常用的方法可供继承的类调用:
◇ setErrorMessage(String newErrorMessage):设置错误的提示信息。
◇ setMessage(String newMessage):设置显示的提示信息。
◇ setMessage(String newMessage, int newType):可显示不同的图标和提示信息。
◇ setTitle(String newTitle):设置提示信息标题。
◇ setTitleAreaColor(RGB color):设置标题区域的颜色。
◇ setTitleImage(Image newTitleImage):设置右侧的图片。
◆ 在使用setMessage(String newMessage, int newType)方法显示消息时,可根据newType参数选择使用不同的图标:IMessageProvider.ERROR、IMessageProvider.WARNING、IMessageProvider.INFORMATION、IMessageProvider.NONE。
16.5 错误提示对话框(ErrorDialog)
虽然使用MessageDialog.openError()方法也可以弹出错误消息的对话框,但这种错误对话框的功能有限,而ErrorDialog错误对话框能够根据错误的级别来显示错误消息。
package www.swt.com.ch16;
import java.io.FileNotFoundException;
public> public ErrorDialogTest() {
> composite.setLayout( new RowLayout(SWT.VERTICAL));
Button> bt1.setText("打开一个错误对话框");
> //创建错误提示对话框
ErrorDialog dlg = newErrorDialog(Display.getCurrent().getActiveShell(),
"提示错误", //对话框的标题
"装载类时出现错误!",//对话框的描述信息
> bt3.setText("静态方法ErrorDialog.openError");
> //使用静态方法打开
ErrorDialog.openError(Display.getCurrent().getActiveShell(),
"提示错误", //对话框的标题
"装载类时出现错误",//对话框的描述信息
> bt2.setText("打开一个可显示多错误对话框");
> statuses[0] = new Status(IStatus.INFO, dummyPlugin, IStatus.OK, "未找到类错误", new ClassNotFoundException());
> statuses[2] = new Status(IStatus.WARNING, dummyPlugin, IStatus.OK, "运行错误", new RuntimeException());
> MultiStatus multiStatus = new MultiStatus(dummyPlugin, IStatus.OK, statuses, "运行期间错误 ", new Exception());
ErrorDialog dlg = newErrorDialog(Display.getCurrent().getActiveShell(),
"提示错误", //对话框的标题
"运行JFace期间发生的错误",//对话框的描述信息
> test.setBlockOnOpen( true );
>
下面是可以同时显示多个错误的效果:
IStatus.INFO类型的错误不显示,因为显示级别为IStatus.WARNING或IStatus.ERROR的错误。
在创建ErrorDialog对话框时,需要使用IStatus类。该类是一个接口,实现该接口的类有Status和MultiStatus类。Status可以保存一个错误的状态信息,而MultiStatus可以同时保存多个错误状态的信息。
public Status(int severity, String pluginId, int code, String message, Throwable exception)
◇ severity:错误的级别。可取值IStatus.INFO、IStatus.ERROR、IStatus.WARNING、IStatus.OK、IStatus.CANCEL等。
◇ pluginId:主要用于Eclipse平台中识别插件的唯一标识ID,如果不是Eclipse平台下使用,可以随意设置字符。
◇ code:也是与Eclipse平台相关的参数。表示Eclipse插件状态代码,如果不是Eclipse平台下使用,可以随意设置字符。
◇ message:出现该错误时,提示给用户的信息。
◇ exception:异常出现的类型。
MultiStatus对象可以同时存储多个错误对象状态:
public MultiStatus(String pluginId, int code, IStatus[] newChildren, String message, Throwable exception)
16.6 带有进度条的对话框(ProgressMonitorDialog)
package www.swt.com.ch16;
import java.lang.reflect.InvocationTargetException;
public> composite.setLayout(new RowLayout(SWT.VERTICAL));
Button> bt1.setText("打开进度条对话框");
> // 创建后台线程对象
IRunnableWithProgress> // 线程运行的代码部分
> Thread.sleep(500);// 为了模拟耗时的操作,每次循环后让该线程休息半秒钟
> test.setBlockOnOpen(true);
>
在使用带有进度条的对话框时需要注意以下几个问题:
◆ 打开对话框不需要open方法,而是使用run方法。
run(boolean fork, boolean cancelable, IRunnableWithProgress runnable)
◇ fork:是否开辟另外一个线程执行。
◇ cancelable:是否可取消执行的线程。
◇ runnable:线程所执行的具体代码部分。
◆ 在后台运行程序的过程中,后台线程与前台界面的交互是通过IProgressMonitor对象来转化实现的,因为在SWT中是不允许其他线程访问UI线程的,而只能利用UI线程来调用。
◆ ProgressMonitorDialog除了run()方法外,还有一些常用的方法:
◇ aboutToRun():在运行线程之前调用的方法。
◇ finishedRun():在运行的线程完成后调用的方法。
◇ setCancelable(boolean cancelable):设置是否显示“取消”按钮。
◇ setOperationCancelButtonEnabled(boolean b):设置“取消”按钮的状态,可以或不可用。
◇ getProgressMonitor():获得运行时的IProgressMonitor对象。
16.7 自定义对话框
package www.swt.com.ch16;
import> public static final int LOGOUT_ID = 1;
public> public static final String LOGOUT_LABEL = "退出";
//用户名和密码文本框
private Text> Group group = new Group(comp, SWT.NONE);
> layout.marginHeight = 20;
> layout.numColumns = 2;
> new Label(group, SWT.NONE).setText("密码: ");
> password.setEchoChar('*');
> System.out.println("登录!用户名为" + userName.getText() + ",密码为" + password.getText());
//如果此时单击了取消按钮,调用父类的
> close();
}
}
测试:
package www.swt.com.ch16;
import> composite.setLayout( new GridLayout());
Button> button.setText("打开自定义对话框示例");
> dialog.open();
}
});
> test.setBlockOnOpen( true );
>
在创建自定义对话框的过程中,需要注意以下方面:
◆ 要继承自Dialog对象,一个对话框由对话框区域和按钮条组成。对话框区域是放置对话框各控件的区域,按钮条是放置对话框按钮的区域。实现自定义对话框最基本的步骤是要覆盖以下几个方法:
◇ Control>