SWT对话框系列:倒计时关闭对话框?? ? 其实你也可以通过SWT的对话框来实现这个功能,如果你真的够无聊的话,
SWT对话框系列:倒计时关闭对话框
??
? 其实你也可以通过SWT的对话框来实现这个功能,如果你真的够无聊的话,可以用来吓唬一下你的用户,当然你的确定你的人缘很好才行.
下面是完整的类
????package?com.cnex.oss.managerupdate.tools;
????
????import?java.beans.PropertyChangeListener;
????import?java.beans.PropertyChangeSupport;
????import?java.util.Timer;
????import?java.util.TimerTask;
????
????import?org.eclipse.jface.dialogs.IDialogConstants;
????import?org.eclipse.jface.layout.GridDataFactory;
????import?org.eclipse.jface.window.Window;
????import?org.eclipse.swt.SWT;
????import?org.eclipse.swt.graphics.Image;
????import?org.eclipse.swt.widgets.Composite;
????import?org.eclipse.swt.widgets.Control;
????import?org.eclipse.swt.widgets.Display;
????import?org.eclipse.swt.widgets.Label;
????import?org.eclipse.swt.widgets.Shell;
????
????/**
?????*?定时执行对话框?。?
?????*?@author?刘尧兴
?????*?<p>2009-12-7</p>
?????*/
????public?class?TimerMessageDialog?extends?MessageDialog2?{
????
??????/**?标签文本?????*/
??????protected?static?Label?localMessageLabel;
??????
??????/**?属性修改支持实现类?????*/
??????private?PropertyChangeSupportImpl?instance?=?new?PropertyChangeSupportImpl();
????
??????/**?定时器?????*/
??????private?Timer?timer;
??????
??????/**
???????*?构造函数。
???????*?@param?parentShell
???????*?@param?dialogTitle
???????*?@param?dialogMessage
???????*/
??????public?TimerMessageDialog(Shell?parentShell,?String?dialogTitle,?String?dialogMessage)?{
????????super(parentShell,?dialogTitle,?null,?dialogMessage,?INFORMATION,?new?String[]?{"立即重启","隐藏"},?0);
????????setShellStyle(SWT.BORDER?|?SWT.MIN);
??????}
????
??????protected?Control?createMessageArea(Composite?composite)?{
????????//?create?composite
????????//?create?image
????????Image?image?=?getImage();
????????if?(image?!=?null)?{
??????????imageLabel?=?new?Label(composite,?SWT.NULL);
??????????image.setBackground(imageLabel.getBackground());
??????????imageLabel.setImage(image);
????//??????addAccessibleListeners(imageLabel,?image);
??????????GridDataFactory.fillDefaults().align(SWT.CENTER,?SWT.BEGINNING)
??????????????.applyTo(imageLabel);
????????}
????????//?create?message
????????if?(message?!=?null)?{
??????????messageLabel?=?new?Label(composite,?getMessageLabelStyle());
??????????TimerMessageDialog.localMessageLabel?=?messageLabel;
??????????messageLabel.setText(message);
??????????GridDataFactory
??????????????.fillDefaults()
??????????????.align(SWT.FILL,?SWT.BEGINNING)
??????????????.grab(true,?false)
??????????????.hint(
??????????????????convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH),
??????????????????SWT.DEFAULT).applyTo(messageLabel);
????????}
????????return?composite;
??????}
??????
??????/**
???????*?打开定时关闭对话框,顾名思义,就是在指定的时间自动关闭??。
???????*?@author?刘尧兴
???????*?@param?second
???????*?@param?message?
???????*/
??????public?void?open(final?int?second,final?String?message)?{
????????setBlockOnOpen(false);
????????open();
????????
????//????final?MessageFormat?format?=?new?MessageFormat("系统检查到重要插件的更新,系统将会在?{0}?秒后自动重启,请注意保存文件");
????????
????????timer?=?new?Timer("检查更新");
????????final?TimerTask?task?=?new?TimerTask()?{
??????????int?count?=?second;
??????????public?void?run()?{
????????????Display?display?=?Display.getDefault();
????????????if?(display?==?null)?{
??????????????return;
????????????}
????????????display.asyncExec(new?Runnable()?{
??????????????public?void?run()?{
????????????????try?{
????
??????????????????if?(count?==?0)?{
????????????????????cancel();
????????????????????buttonPressed(Window.OK);
??????????????????}?else?{
????????????????????count?-=?1;
????????????????????if?(!localMessageLabel.isDisposed()&&localMessageLabel?!=?null)?{
??????????????????????localMessageLabel.setText(message+"系统将在:"?+?count?+?"秒后自动重启");
????//????????????????localMessageLabel.setText(format.format(new?Object[]{new?Integer(count)}));
????????????????????}
??????????????????}
????????????????
????????????????}catch?(Exception?e)?{
??????????????????e.printStackTrace();
????????????????}
??????????????}
????????????});
??????????}
????????};
????????timer.schedule(task,?1000,?1000);
??????}
??????
??????protected?void?buttonPressed(int?buttonId)?{
????????if(buttonId?==?Window.OK)?{
??????????timer.cancel();
??????????firePropertyChange(IPropery.RESTART_OK_PRESSED,?false,?true);
????????}?else?if(buttonId?==?Window.CANCEL)?{
??????????close();
????????}
??????}
??????
??????/**
???????*?添加属性事件??。
???????*?@author?刘尧兴
???????*?@param?l
???????*/
??????public?void?addPropertyChangeListener(PropertyChangeListener?l)?{
????????instance.addPropertyChangeListener(l);
??????}
??????
??????/**
???????*?删除属性修改事件??。
???????*?@author?刘尧兴
???????*?@param?l
???????*/
??????public?void?removePropertyChangeListener(PropertyChangeListener?l)?{
????????instance.removePropertyChangeListener(l);
??????}
??????
??????/**
???????*?通知属性修改事件(通知前台代码修改)??。
???????*?@author?刘尧兴
???????*?@param?prop
???????*?@param?old
???????*?@param?newValue
???????*/
??????public?void?firePropertyChange(String?prop,?Object?old,?Object?newValue)?{
????????instance.firePropertyChange(prop,?old,?newValue);
??????}
??????
??????/**
???????*?属性修改支持实现类??。?
???????*?@author?刘尧兴
???????*?<p>2009-8-18</p>
???????*/
??????public?class?PropertyChangeSupportImpl?{
????????
????????/**?属性修改支持?????*/
????????PropertyChangeSupport?listeners?=?new?PropertyChangeSupport(this);
????
????????/**
?????????*?添加属性修改事件??。
?????????*?@author?刘尧兴
?????????*?@param?l
?????????*/
????????public?void?addPropertyChangeListener(PropertyChangeListener?l)?{
??????????listeners.addPropertyChangeListener(l);
????????}
????
????????/**
?????????*?通知修改事件发生??。
?????????*?@author?刘尧兴
?????????*?@param?prop
?????????*?@param?old
?????????*?@param?newValue
?????????*/
????????public?void?firePropertyChange(String?prop,?Object?old,?Object?newValue)?{
??????????listeners.firePropertyChange(prop,?old,?newValue);
????????}
????
????????/**
?????????*?通知事件修改??。
?????????*?@author?刘尧兴
?????????*?@param?prop
?????????*?@param?child
?????????*/
????????protected?void?fireStructureChange(String?prop,?Object?child)?{
??????????listeners.firePropertyChange(prop,?null,?child);
????????}
????
????????/**
?????????*?删除属性修改事件??。
?????????*?@author?刘尧兴
?????????*?@param?l
?????????*/
????????public?void?removePropertyChangeListener(PropertyChangeListener?l)?{
??????????listeners.removePropertyChangeListener(l);
????????}
??????}
????
????} protected?Control?createMessageArea(Composite?composite)?{
????//?create?composite
????//?create?image
????Image?image?=?getImage();
????if?(image?!=?null)?{
??????imageLabel?=?new?Label(composite,?SWT.NULL);
??????image.setBackground(imageLabel.getBackground());
??????imageLabel.setImage(image);
//??????addAccessibleListeners(imageLabel,?image);
??????GridDataFactory.fillDefaults().align(SWT.CENTER,?SWT.BEGINNING)
??????????.applyTo(imageLabel);
????}
????//?create?message
????if?(message?!=?null)?{
??????messageLabel?=?new?Label(composite,?getMessageLabelStyle());
??????TimerMessageDialog.localMessageLabel?=?messageLabel;
??????messageLabel.setText(message);
??????GridDataFactory
??????????.fillDefaults()
??????????.align(SWT.FILL,?SWT.BEGINNING)
??????????.grab(true,?false)
??????????.hint(
??????????????convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH),
??????????????SWT.DEFAULT).applyTo(messageLabel);
????}
????return?composite;
??}
?? 然后我们添加一个打开对话框的方法: ?open(final?int?second,final?String?message) ,second表示倒计时时间,message表示提示信息,在open方法中新建一个 Timer 对象。对了,为了让MessageDialog弹出后不阻塞线程的执行,需要在调用对话框的open方法之前调用 setBlockOnOpen(false); 方法,下面是我的实现,大家可以参考一下:
/**
???*?打开定时关闭对话框,顾名思义,就是在指定的时间自动关闭??。
???*?@author?刘尧兴
???*?@param?second
???*?@param?message?
???*/
??public?void?open(final?int?second,final?String?message)?{
????setBlockOnOpen(false);
????open();
????
//????final?MessageFormat?format?=?new?MessageFormat("系统检查到重要插件的更新,系统将会在?{0}?秒后自动重启,请注意保存文件");
????
????timer?=?new?Timer("检查更新");
????final?TimerTask?task?=?new?TimerTask()?{
??????int?count?=?second;
??????public?void?run()?{
????????Display?display?=?Display.getDefault();
????????if?(display?==?null)?{
??????????return;
????????}
????????display.asyncExec(new?Runnable()?{
??????????public?void?run()?{
????????????try?{
??????????????if?(count?==?0)?{
????????????????cancel();
????????????????buttonPressed(Window.OK);
??????????????}?else?{
????????????????count?-=?1;
????????????????if?(!localMessageLabel.isDisposed()&&localMessageLabel?!=?null)?{
??????????????????localMessageLabel.setText(message+"系统将在:"?+?count?+?"秒后自动重启");
//????????????????localMessageLabel.setText(format.format(new?Object[]{new?Integer(count)}));
????????????????}
??????????????}
????????????
????????????}catch?(Exception?e)?{
??????????????e.printStackTrace();
????????????}
??????????}
????????});
??????}
????};
????timer.schedule(task,?1000,?1000);
??}
?
?? 这里的Timer是每一秒钟执行一次,在定时器执行完成后应该让对话框自动关闭,然后可以通知事件发起人来执行对应的操作,从这样设计的角度上看,我们的需要在用户点击确认或者取消或者关闭对话框时响应用户的操作,这样我们的重载父类的 buttonPressed(int?buttonId) 方法,在这个方法中执行对应的操作.比如这样:
?
protected?void?buttonPressed(int?buttonId)?{
????if(buttonId?==?Window.OK)?{
??????timer.cancel();
??????firePropertyChange(IPropery.RESTART_OK_PRESSED,?false,?true);
????}?else?if(buttonId?==?Window.CANCEL)?{
??????close();
????}
??} <!--endfragment--><!--endfragment--><!--endfragment--><!--endfragment-->
?? 这里我使用了java.util包中的 PropertyChangeListener 来监听属性值的修改。这里的对话框应该算是事件源,由这个发起属性事件的修改通知,其他监听类根据接收到的信息作出相应的响应。我在TimerMessageDialog实现了一个内部类: PropertyChangeSupportImpl ,这个类管理通知的对象:?
? <!--endfragment-->
/**
???*?属性修改支持实现类??。?
???*?@author?刘尧兴
???*?<p>2009-8-18</p>
???*/
??public?class?PropertyChangeSupportImpl?{
????
????/**?属性修改支持?????*/
????PropertyChangeSupport?listeners?=?new?PropertyChangeSupport(this);
????/**
?????*?添加属性修改事件??。
?????*?@author?刘尧兴
?????*?@param?l
?????*/
????public?void?addPropertyChangeListener(PropertyChangeListener?l)?{
??????listeners.addPropertyChangeListener(l);
????}
????/**
?????*?通知修改事件发生??。
?????*?@author?刘尧兴
?????*?@param?prop
?????*?@param?old
?????*?@param?newValue
?????*/
????public?void?firePropertyChange(String?prop,?Object?old,?Object?newValue)?{
??????listeners.firePropertyChange(prop,?old,?newValue);
????}
????/**
?????*?通知事件修改??。
?????*?@author?刘尧兴
?????*?@param?prop
?????*?@param?child
?????*/
????protected?void?fireStructureChange(String?prop,?Object?child)?{
??????listeners.firePropertyChange(prop,?null,?child);
????}
????/**
?????*?删除属性修改事件??。
?????*?@author?刘尧兴
?????*?@param?l
?????*/
????public?void?removePropertyChangeListener(PropertyChangeListener?l)?{
??????listeners.removePropertyChangeListener(l);
????}
??}
?? 在完成这些之后,在监听类中注册一个属性修改的事件,比如在UpdatePlan这个类中执行TimerMessageDialog的打开操作,那就的让UpdatePlan这个类实现 PropertyChangeListener 这个接口并实现 propertyChange(final?PropertyChangeEvent?evt) 这个方法,这个方法可以根据传过来的属性名称和属性值执行相应的操作。UpdatePlan属性注册方式是:
Display.getDefault().asyncExec(new?Runnable()?{
??????@Override
??????public?void?run()?{
????????try?{
??????????TimerMessageDialog?dialog?=?new?TimerMessageDialog(Display.getDefault().getActiveShell(),"系统信息","系统将要自动重启");
??????????dialog.addPropertyChangeListener(this);
??????????dialog.open(30,"");
????????}
????????catch?(Exception?e)?{
??????????e.printStackTrace();
????????}
??????}
????});