《Eclipse SWT/JFACE 核心應(yīng)用》 清華大學(xué)出版社 16 JFace對話框
16.1 JFace對話框概述
◆ ErrorDialog:可根據(jù)錯(cuò)誤級別來顯示錯(cuò)誤信息,,一般用于Eclipse工作臺(tái)。
◆ MessageDialog:可顯示提示信息的對話框,,類似于SWT的對話框,,但比SWT功能強(qiáng)大。
◆ MessageDialogWithToggle:一般在保存首選項(xiàng)所設(shè)置的值時(shí)顯示是否保存的提示信息,。
◆ ProgressMonitorDialog:可以顯示后臺(tái)線程進(jìn)度的對話框,。
◆ InputDialog:用于輸入信息的對話框,,同時(shí)可以驗(yàn)證用戶的輸入,并可以將驗(yàn)證的信息顯示在對話框中,。
◆ PreferenceDialog:專門為設(shè)置首選項(xiàng)所使用的對話框,。
◆ TitleAreaDialog:帶有標(biāo)題、圖標(biāo)和描述信息的對話框,。
◆ WizardDialog:向?qū)綄υ捒颉?/p>
16.2 信息提示對話框(MessageDialog)
各種類型的信息提示對話框示例:
package www.swt.com.ch16;
import org.eclipse.jface.dialogs.MessageDialog;
public class MessageDialogTest extends ApplicationWindow {
public MessageDialogTest() {
super(null);
}
protected void configureShell(Shell shell) {
super.configureShell(shell);
shell.setSize(550,300);
shell.setText("消息對話框示例");
}
protected Control createContents(Composite parent) {
//窗口中的區(qū)域由一個(gè)文本框做為消息輸出臺(tái)和幾個(gè)按鈕分別打開不同的對話框
Composite composite = new Composite( parent ,SWT.NONE);
GridLayout gridLayout = new GridLayout (6,false);
composite.setLayout( gridLayout );
final Text console = new Text ( composite ,SWT.NONE|SWT.READ_ONLY|SWT.V_SCROLL);
GridData data = new GridData(GridData.FILL_BOTH);
data.horizontalSpan=6;
console.setLayoutData( data);
Button openError = new Button( composite ,SWT.NONE);
openError.setText("錯(cuò)誤消息對話框");
openError.addSelectionListener( new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
MessageDialog.openError(Display.getCurrent().getActiveShell(),"錯(cuò)誤消息對話框","讀取文件發(fā)生錯(cuò)誤,!");
console.append("\n openError對話框,返回void");
}
});
Button openConfirm = new Button( composite ,SWT.NONE);
openConfirm.setText("確認(rèn)消息對話框");
openConfirm.addSelectionListener( new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
boolean b = MessageDialog.openConfirm(Display.getCurrent().getActiveShell(),
"確認(rèn)消息對話框",
"確實(shí)要保存文件嗎,?");
console.append("\n openConfirm對話框,,返回"+b);
}
});
Button openInformation = new Button( composite ,SWT.NONE);
openInformation.setText("消息對話框");
openInformation.addSelectionListener( new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
MessageDialog.openInformation(Display.getCurrent().getActiveShell(),"消息對話框","確實(shí)要保存文件嗎?");
console.append("\n openInformation對話框,,返回void");
}
});
Button openQuestion = new Button( composite ,SWT.NONE);
openQuestion.setText("詢問對話框");
openQuestion.addSelectionListener( new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
boolean b = MessageDialog.openQuestion(Display.getCurrent().getActiveShell(),"詢問對話框","確實(shí)要保存文件嗎,!");
console.append("\n openQuestion對話框,返回"+b);
}
});
Button openWarning = new Button( composite ,SWT.NONE);
openWarning.setText("警告對話框");
openWarning.addSelectionListener( new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
MessageDialog.openWarning(Display.getCurrent().getActiveShell(),"警告對話框","確實(shí)要保存文件嗎,!");
console.append("\n openWarning對話框,,返回void");
}
});
Button customMessageDig = new Button( composite ,SWT.NONE);
customMessageDig.setText("自定義對話框");
customMessageDig.addSelectionListener( new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
MessageDialog dialog = new MessageDialog(Display.getCurrent().getActiveShell(),//shell窗口
"這是對話框的標(biāo)題",//標(biāo)題
null,//對話框的圖標(biāo),為null則不顯示圖標(biāo)
"這是一個(gè)自定義的對話框,,可以改變按鈕的設(shè)置",//對話框中的提示信息
MessageDialog.INFORMATION,//提示信息的圖標(biāo)
new String[]{"查看","保存","確認(rèn)"},//顯示三個(gè)按鈕
1);//默認(rèn)選擇的按鈕的索引值,這里為1,,表示默認(rèn)選中第二個(gè)按鈕,,也就是保存按鈕
int i = dialog.open();//返回值為按鈕
console.append("\n 自定義對話框,返回按鈕的索引值"+i);
}
});
return parent;
}
public static void main(String[] args) {
MessageDialogTest test = new MessageDialogTest();
test.setBlockOnOpen( true );
test.open();
Display.getCurrent().dispose();
}
}
顯示效果:
JFace的本地化
1. 現(xiàn)象:例如,,警告對話框中的按鈕顯示的文字為“OK”,,而不是“確定”。
2. 原因:SWT中的對話框是調(diào)用本地操作系統(tǒng)的對話框,,它顯示的按鈕是根據(jù)本地操作系統(tǒng)的語言設(shè)定的,。而JFace中的對話框是通過SWT的Shell窗口封裝來的,調(diào)用的是SWT中的Button控件對象,。下面是源碼:
public static void openError(Shell parent, String title, String message) {
MessageDialog dialog = new MessageDialog(parent, title, null, message, ERROR, new String[] {IDialogConstrants.OK_LABEL}, 0);
dialog.open();
return;
}
按鈕的文字通過IDialogConstants.OK_LABEL字符常量來設(shè)定,,而常量在IDialogConstants類中的值為:
public String OK_LABEL = JFaceResources.getString("OK");
在JFaceResources類中可以發(fā)現(xiàn),這個(gè)字符是根據(jù)org.eclipse.jface包中messages*.properties文件所指定的ResourceBundle文件來獲取的,,也就是獲取的本地的語言包,。
private static final ResourceBundle bundle = ResourceBundle.getBundle("org.eclipse.jface.messages");
當(dāng)前所運(yùn)行的JFace環(huán)境中沒有這個(gè)語言包,所以不能顯示中文,,只能以默認(rèn)的英文來顯示,。所以,要使JFace的對話框本地化,,要找到語言包然后導(dǎo)入到項(xiàng)目工程中即可,。
安裝JFace語言包參考:JFace的本地化及安裝JFace語言包
本地化后:
注意“OK”和“確定”按鈕。
16.3 輸入對話框(InputDialog)
輸入對話框(InputDialog類)可以提示用戶輸入一段文本,并且也判斷輸入字符的有效性,,當(dāng)輸入錯(cuò)誤時(shí)將錯(cuò)誤信息返回給用戶,。
輸入對話框:
package www.swt.com.ch16;
import org.eclipse.jface.dialogs.InputDialog;
public class InputDialogTest extends ApplicationWindow{
public InputDialogTest() {
super(null);
}
protected void configureShell(Shell shell) {
super.configureShell( shell );
shell.setText("輸入對話框示例");
}
protected Control createContents(Composite parent) {
Composite composite = new Composite( parent , SWT.NONE);
composite.setLayout( new GridLayout());
Button button = new Button( composite ,SWT.NONE);
button.setText("打開輸入對話框");
button.addSelectionListener( new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
InputDialog inputDialog = new InputDialog(Display.getCurrent().getActiveShell(),
"輸入電子郵件",//對話框的標(biāo)題
"請輸入電子郵件地址:",//對話框的提示信息
"[email protected]",//輸入框中默認(rèn)值
new EmailValidator()//驗(yàn)證輸入字符的有效性
);
int r = inputDialog.open();//打開窗口
if (r==Window.OK)//如果輸入有效,則輸出輸入的值
System.out.println(inputDialog.getValue());
else
System.out.println("取消");
}
});
return parent;
}
public static void main(String[] args) {
InputDialogTest test = new InputDialogTest();
test.setBlockOnOpen( true );
test.open();
Display.getCurrent().dispose();
}
}
輸入對話框內(nèi)容有效性的驗(yàn)證:
package www.swt.com.ch16;
import org.eclipse.jface.dialogs.IInputValidator;
public class EmailValidator implements IInputValidator{
public String isValid(String newText) {
//如果輸如的字符串中不含@字符,,輸入無效
if (newText.indexOf("@")==-1)
return "錯(cuò)誤,!請輸入有效的電子郵件地址。";
return null;
}
}
顯示效果:
16.4 帶有提示信息的對話框(TitleAreaDialog)
帶有提示信息的對話框(TitleAreaDialog類)可在標(biāo)題上顯示提示的信息,,提示信息類別的不同,,將顯示不同的圖標(biāo)。
帶有提示信息的對話框可以根據(jù)用戶當(dāng)前的輸入提示錯(cuò)誤的消息,,創(chuàng)建這樣的對話框需使用繼承的方式,,然后覆蓋父類的方法。
package www.swt.com.ch16;
import org.eclipse.jface.dialogs.IMessageProvider;
public class InputPasswordDialog extends TitleAreaDialog{
private Text userName;
private Text password;
private Text confirmPassword;
public final String DEFAULT_INFO="請輸入要注冊的用戶名的和密碼";
public InputPasswordDialog(Shell parentShell) {
super(parentShell);
}
/* (非 Javadoc)
* @see org.eclipse.jface.dialogs.TitleAreaDialog#createContents(org.eclipse.swt.widgets.Composite)
*/
protected Control createContents(Composite parent) {
super.createContents(parent);
this.getShell().setText("用戶注冊對話框");//設(shè)置對話框標(biāo)題欄
this.setTitle("用戶注冊");//設(shè)置標(biāo)題信息
this.setMessage("請輸入要注冊的用戶名和密碼",IMessageProvider.INFORMATION);//設(shè)置初始化對話框的提示信息
//設(shè)置右側(cè)的圖片,,一般為48*48大小
this.setTitleImage( ImageFactory.loadImage( Display.getCurrent(), ImageFactory.SAMPLE_ICON));
return parent;
}
/* (非 Javadoc)
* @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
* 覆蓋該方法,,可以創(chuàng)建對話框顯示的主體區(qū)域
*/
protected Control createDialogArea(Composite parent) {
super.createDialogArea(parent);
Composite composite = new Composite(parent , SWT.NONE);
composite.setLayout( new GridLayout(2,true));
new Label( composite , SWT.NONE).setText("用戶名:");
userName = new Text(composite ,SWT.BORDER);
userName.addFocusListener( new FocusAdapter(){
//當(dāng)用戶名文本框失去焦點(diǎn)時(shí),判斷是否有效
public void focusLost(FocusEvent e) {
checkValid();
}
});
new Label( composite , SWT.NONE).setText("密碼:");
password = new Text(composite ,SWT.BORDER);
password.setEchoChar('*');
new Label( composite , SWT.NONE).setText("確認(rèn)密碼:");
confirmPassword = new Text(composite ,SWT.BORDER);
confirmPassword.setEchoChar('*');
confirmPassword.addFocusListener( new FocusAdapter(){
//當(dāng)確認(rèn)密碼文本框失去焦點(diǎn)時(shí),,判斷是否有效
public void focusLost(FocusEvent e) {
checkValid();
}
});
return parent;
}
//判斷是是否輸入有效,,并提示用戶
protected void checkValid() {
if (!password.getText().equals(confirmPassword.getText()))
setMessage("確認(rèn)密碼不一致,請重新輸入!",IMessageProvider.WARNING);
else if ( userName.getText().equals(""))
setMessage("用戶名不能為空!",IMessageProvider.ERROR);
else
setMessage(DEFAULT_INFO);
}
}
下面是執(zhí)行代碼:
package www.swt.com.ch16;
import org.eclipse.jface.window.ApplicationWindow;
public class InputPWDialogTest extends ApplicationWindow{
public InputPWDialogTest() {
super(null);
}
protected Control createContents(Composite parent) {
Button button = new Button( parent ,SWT.NONE);
button.setText("打開輸入對話框");
button.addSelectionListener( new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
//調(diào)用該對話框
InputPasswordDialog dialog = new InputPasswordDialog(Display.getCurrent().getActiveShell());
dialog.open();
}
});
return parent;
}
public static void main(String[] args) {
InputPWDialogTest test = new InputPWDialogTest();
test.setBlockOnOpen( true );
test.open();
Display.getCurrent().dispose();
}
}
顯示效果:
密碼不一致后:
在使用TitleAreaDialog類時(shí),,應(yīng)注意以下幾個(gè)問題:
◆ 創(chuàng)建窗口所顯示的內(nèi)容要通過繼承TitleAreaDialog類的方式,,而不能直接創(chuàng)建。例如,,運(yùn)行以下代碼會(huì)拋出異常:
TitleAreaDialog dialog = new TitleAreaDialog(shell);
dialog.setMessage("這種方式是錯(cuò)誤的,!"); // 錯(cuò)誤!
dialog.open();
◆ 當(dāng)繼承TitleAreaDialog類時(shí),,通常要調(diào)用父類的以下幾個(gè)方法:
◇ Control createContents(Composite parent):該方法創(chuàng)建一個(gè)頂級容器來放置顯示消息的部分和輸入?yún)^(qū)域的部分,。
◇ Control createDialogArea(Composite parent):創(chuàng)建對話框輸入?yún)^(qū)域的控件,一般都要覆蓋此方法,。
◆ 另外,,TitleAreaDialog類還有一些常用的方法可供繼承的類調(diào)用:
◇ setErrorMessage(String newErrorMessage):設(shè)置錯(cuò)誤的提示信息。
◇ setMessage(String newMessage):設(shè)置顯示的提示信息,。
◇ setMessage(String newMessage, int newType):可顯示不同的圖標(biāo)和提示信息,。
◇ setTitle(String newTitle):設(shè)置提示信息標(biāo)題。
◇ setTitleAreaColor(RGB color):設(shè)置標(biāo)題區(qū)域的顏色,。
◇ setTitleImage(Image newTitleImage):設(shè)置右側(cè)的圖片,。
◆ 在使用setMessage(String newMessage, int
newType)方法顯示消息時(shí),可根據(jù)newType參數(shù)選擇使用不同的圖標(biāo):IMessageProvider.ERROR,、
IMessageProvider.WARNING,、IMessageProvider.INFORMATION,、
IMessageProvider.NONE。
16.5 錯(cuò)誤提示對話框(ErrorDialog)
雖然使用MessageDialog.openError()方法也可以彈出錯(cuò)誤消息的對話框,,但這種錯(cuò)誤對話框的功能有限,,而ErrorDialog錯(cuò)誤對話框能夠根據(jù)錯(cuò)誤的級別來顯示錯(cuò)誤消息。
package www.swt.com.ch16;
import java.io.FileNotFoundException;
public class ErrorDialogTest extends ApplicationWindow{
final String dummyPlugin = "plugin id";
public ErrorDialogTest() {
super(null);
}
protected Control createContents(Composite parent) {
Composite composite = new Composite ( parent , SWT.NONE);
composite.setLayout( new RowLayout(SWT.VERTICAL));
Button bt1 = new Button(composite ,SWT.NONE);
bt1.setText("打開一個(gè)錯(cuò)誤對話框");
bt1.addSelectionListener( new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
//創(chuàng)建一個(gè)Status對象
Status status = new Status(IStatus.ERROR, dummyPlugin, 1, "未找到該類", new ClassNotFoundException());
//創(chuàng)建錯(cuò)誤提示對話框
ErrorDialog dlg = new ErrorDialog(Display.getCurrent().getActiveShell(),
"提示錯(cuò)誤", //對話框的標(biāo)題
"裝載類時(shí)出現(xiàn)錯(cuò)誤,!",//對話框的描述信息
status, //Status對象
IStatus.ERROR);//只顯示級別為IStatus.ERROR的錯(cuò)誤
dlg.open();
}
});
Button bt3 = new Button(composite ,SWT.NONE);
bt3.setText("靜態(tài)方法ErrorDialog.openError");
bt3.addSelectionListener( new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
//創(chuàng)建一個(gè)Status對象
Status status = new Status(IStatus.ERROR, dummyPlugin, 1, "未找到該類", new ClassNotFoundException());
//使用靜態(tài)方法打開
ErrorDialog.openError(Display.getCurrent().getActiveShell(),
"提示錯(cuò)誤", //對話框的標(biāo)題
"裝載類時(shí)出現(xiàn)錯(cuò)誤",//對話框的描述信息
status,
IStatus.ERROR);
}
});
Button bt2 = new Button(composite ,SWT.NONE);
bt2.setText("打開一個(gè)可顯示多錯(cuò)誤對話框");
bt2.addSelectionListener( new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
IStatus[] statuses = new IStatus[4];
statuses[0] = new Status(IStatus.INFO, dummyPlugin, IStatus.OK, "未找到類錯(cuò)誤", new ClassNotFoundException());
statuses[1] = new Status(IStatus.ERROR, dummyPlugin, IStatus.OK, "未找到文件錯(cuò)誤", new FileNotFoundException());
statuses[2] = new Status(IStatus.WARNING, dummyPlugin, IStatus.OK, "運(yùn)行錯(cuò)誤", new RuntimeException());
statuses[3] = new Status(IStatus.WARNING, dummyPlugin, IStatus.OK, "數(shù)據(jù)庫查詢錯(cuò)誤", new SQLException());
MultiStatus multiStatus = new MultiStatus(dummyPlugin, IStatus.OK, statuses, "運(yùn)行期間錯(cuò)誤 ", new Exception());
ErrorDialog dlg = new ErrorDialog(Display.getCurrent().getActiveShell(),
"提示錯(cuò)誤", //對話框的標(biāo)題
"運(yùn)行JFace期間發(fā)生的錯(cuò)誤",//對話框的描述信息
multiStatus, //Status對象
IStatus.WARNING|IStatus.ERROR);//顯示級別為IStatus.WARNING或IStatus.ERROR的錯(cuò)誤
dlg.open();
}
});
return parent;
}
public static void main(String[] args) {
ErrorDialogTest test = new ErrorDialogTest();
test.setBlockOnOpen( true );
test.open();
Display.getCurrent().dispose();
}
}
顯示效果:
下面是可以同時(shí)顯示多個(gè)錯(cuò)誤的效果:
IStatus.INFO類型的錯(cuò)誤不顯示,,因?yàn)轱@示級別為IStatus.WARNING或IStatus.ERROR的錯(cuò)誤。
在創(chuàng)建ErrorDialog對話框時(shí),,需要使用IStatus類,。該類是一個(gè)接口,實(shí)現(xiàn)該接口的類有Status和MultiStatus類,。Status可以保存一個(gè)錯(cuò)誤的狀態(tài)信息,,而MultiStatus可以同時(shí)保存多個(gè)錯(cuò)誤狀態(tài)的信息。
public Status(int severity, String pluginId, int code, String message, Throwable exception)
◇ severity:錯(cuò)誤的級別,??扇≈礗Status.INFO、IStatus.ERROR,、IStatus.WARNING,、IStatus.OK、IStatus.CANCEL等,。
◇ pluginId:主要用于Eclipse平臺(tái)中識(shí)別插件的唯一標(biāo)識(shí)ID,,如果不是Eclipse平臺(tái)下使用,可以隨意設(shè)置字符,。
◇ code:也是與Eclipse平臺(tái)相關(guān)的參數(shù)。表示Eclipse插件狀態(tài)代碼,,如果不是Eclipse平臺(tái)下使用,,可以隨意設(shè)置字符。
◇ message:出現(xiàn)該錯(cuò)誤時(shí),,提示給用戶的信息,。
◇ exception:異常出現(xiàn)的類型。
MultiStatus對象可以同時(shí)存儲(chǔ)多個(gè)錯(cuò)誤對象狀態(tài):
public MultiStatus(String pluginId, int code, IStatus[] newChildren, String message, Throwable exception)
16.6 帶有進(jìn)度條的對話框(ProgressMonitorDialog)
package www.swt.com.ch16;
import java.lang.reflect.InvocationTargetException;
public class ProgressMonitorDialogTest extends ApplicationWindow {
public ProgressMonitorDialogTest() {
super(null);
}
protected Control createContents(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new RowLayout(SWT.VERTICAL));
Button bt1 = new Button(composite, SWT.NONE);
bt1.setText("打開進(jìn)度條對話框");
bt1.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
showDialog();
}
});
return parent;
}
private void showDialog() {
try {
ProgressMonitorDialog progressDialog = new ProgressMonitorDialog(Display.getCurrent().getActiveShell());
// 創(chuàng)建后臺(tái)線程對象
IRunnableWithProgress runnalble = new IRunnableWithProgress() {
// 線程運(yùn)行的代碼部分
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
// 設(shè)置顯示在UI界面上的線程信息
monitor.beginTask("開始執(zhí)行任務(wù)...", 100);
// 該線程在用戶沒有取消操作的情況下循環(huán)10次
// 并且每次循環(huán)后設(shè)置進(jìn)度增加10,表示一個(gè)任務(wù)已完成
for (int i = 0; i < 10 && !monitor.isCanceled(); i++) {
Thread.sleep(500);// 為了模擬耗時(shí)的操作,,每次循環(huán)后讓該線程休息半秒鐘
monitor.worked(10);// 進(jìn)度增加10
monitor.subTask("已完成第" + i + "個(gè)任務(wù)");// 顯示任務(wù)狀態(tài)
}
// 循環(huán)完成后設(shè)置此任務(wù)已完成
monitor.done();
// 如果此時(shí)為用戶取消的操作
if (monitor.isCanceled())
throw new InterruptedException("用戶已取消了操作");
}
};
progressDialog.run(true, false, runnalble);// 啟動(dòng)線程
} catch (Exception ee) {
ee.printStackTrace();
}
}
public static void main(String[] args) {
ProgressMonitorDialogTest test = new ProgressMonitorDialogTest();
test.setBlockOnOpen(true);
test.open();
Display.getCurrent().dispose();
}
}
顯示效果:
在使用帶有進(jìn)度條的對話框時(shí)需要注意以下幾個(gè)問題:
◆ 打開對話框不需要open方法,,而是使用run方法。
run(boolean fork, boolean cancelable, IRunnableWithProgress runnable)
◇ fork:是否開辟另外一個(gè)線程執(zhí)行,。
◇ cancelable:是否可取消執(zhí)行的線程,。
◇ runnable:線程所執(zhí)行的具體代碼部分。
◆ 在后臺(tái)運(yùn)行程序的過程中,,后臺(tái)線程與前臺(tái)界面的交互是通過IProgressMonitor對象來轉(zhuǎn)化實(shí)現(xiàn)的,,因?yàn)樵赟WT中是不允許其他線程訪問UI線程的,,而只能利用UI線程來調(diào)用。
◆ ProgressMonitorDialog除了run()方法外,,還有一些常用的方法:
◇ aboutToRun():在運(yùn)行線程之前調(diào)用的方法,。
◇ finishedRun():在運(yùn)行的線程完成后調(diào)用的方法。
◇ setCancelable(boolean cancelable):設(shè)置是否顯示“取消”按鈕,。
◇ setOperationCancelButtonEnabled(boolean b):設(shè)置“取消”按鈕的狀態(tài),,可以或不可用。
◇ getProgressMonitor():獲得運(yùn)行時(shí)的IProgressMonitor對象,。
16.7 自定義對話框
package www.swt.com.ch16;
import org.eclipse.jface.dialogs.Dialog;
public class LoginDialog extends Dialog {
//定義按鈕的常量
public static final int LOGIN_ID = 0;
public static final int LOGOUT_ID = 1;
public static final String LOGIN_LABEL = "登錄";
public static final String LOGOUT_LABEL = "退出";
//用戶名和密碼文本框
private Text userName;
private Text password;
public LoginDialog(Shell parentShell) {
super(parentShell);
}
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
newShell.setText("登錄");
}
/*
* (非 Javadoc)
*
* @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
* 覆蓋該方法,,在此方法中創(chuàng)建對話框的內(nèi)容區(qū)域
*/
protected Control createDialogArea(Composite parent) {
Composite comp = (Composite) super.createDialogArea(parent);
Group group = new Group(comp, SWT.NONE);
group.setText("登錄系統(tǒng)");
GridLayout layout = new GridLayout();
layout.marginHeight = 20;
layout.marginWidth = 20;
layout.numColumns = 2;
group.setLayout(layout);
new Label(group, SWT.NONE).setText("用戶名: ");
userName = new Text(group, SWT.BORDER | SWT.SINGLE);
new Label(group, SWT.NONE).setText("密碼: ");
password = new Text(group, SWT.BORDER | SWT.SINGLE);
password.setEchoChar('*');
return parent;
}
/*
* (非 Javadoc)
*
* @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
* 覆蓋該方法,在此方法中創(chuàng)建所需要的按鈕
*/
protected void createButtonsForButtonBar(Composite parent) {
//使用父類中創(chuàng)建按鈕的方法創(chuàng)建登陸和退出按鈕
createButton(parent, LoginDialog.LOGIN_ID, LoginDialog.LOGIN_LABEL, true);
createButton(parent, LoginDialog.LOGOUT_ID, LoginDialog.LOGOUT_LABEL, false);
}
/*
* (非 Javadoc)
*
* @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
* 當(dāng)單擊對話框中的按鈕時(shí),,調(diào)用此方法
*/
protected void buttonPressed(int buttonId) {
//如果此時(shí)單擊了登陸按鈕
if (LoginDialog.LOGIN_ID == buttonId)
System.out.println("登錄,!用戶名為" + userName.getText() + ",密碼為" + password.getText());
//如果此時(shí)單擊了取消按鈕,調(diào)用父類的
else if (LoginDialog.LOGOUT_ID == buttonId)
close();
}
}
測試:
package www.swt.com.ch16;
import org.eclipse.jface.window.ApplicationWindow;
public class LoginDialogTest extends ApplicationWindow{
public LoginDialogTest() {
super(null);
}
protected void configureShell(Shell shell) {
super.configureShell( shell );
shell.setText("自定義對話框示例");
}
protected Control createContents(Composite parent) {
Composite composite = new Composite( parent , SWT.NONE);
composite.setLayout( new GridLayout());
Button button = new Button( composite ,SWT.NONE);
button.setText("打開自定義對話框示例");
button.addSelectionListener( new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
LoginDialog dialog = new LoginDialog( Display.getCurrent().getActiveShell() );
dialog.open();
}
});
return parent;
}
public static void main(String[] args) {
LoginDialogTest test = new LoginDialogTest();
test.setBlockOnOpen( true );
test.open();
Display.getCurrent().dispose();
}
}
顯示效果:
在創(chuàng)建自定義對話框的過程中,,需要注意以下方面:
◆ 要繼承自Dialog對象,,一個(gè)對話框由對話框區(qū)域和按鈕條組成。對話框區(qū)域是放置對話框各控件的區(qū)域,,按鈕條是放置對話框按鈕的區(qū)域,。實(shí)現(xiàn)自定義對話框最基本的步驟是要覆蓋以下幾個(gè)方法:
◇ Control createDialogArea(Composite parent):創(chuàng)建對話框的各種控件。
◇ void createButtonsForButtonBar(Composite parent):創(chuàng)建對話框的按鈕,。
◇ void buttonPressed(int buttonId):處理按鈕單擊事件,。
◆ 在覆蓋createButtonsForButtonBar方法時(shí),創(chuàng)建的按鈕是調(diào)用父類以下所示的方法來創(chuàng)建按鈕的:
Button createButton(Composite parent, int id, String label, boolean defaultButton);
其中,,id表示按鈕所定制的索引值,,label為按鈕所顯示的文本,defaultButton表示是否設(shè)置為默認(rèn)選中狀態(tài),。通常將id和
label設(shè)置為常量,,在JFace中已經(jīng)提供了一些常用的按鈕常量。在
org.eclipse.jface.dialogs.IDialogConstants類中,,例如,,要?jiǎng)?chuàng)建一個(gè)“確定”按鈕的代碼如下:
createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
◆ 要處理單擊不同按鈕后的事件,要在buttonPressed(int buttonId)中處理,,其中buttonId為按鈕的索引值,。