我使用LongUIOperation自定义实现,但有时候,使用
Executions.deactivate(getNativeDesktop());
我在屏幕上收到消息框并且:
dic 11,2017 11:09:42 AM org.zkoss.zk.ui.impl.UiEngineImpl handleError GRAVE:java.lang.NullPointerException at org.apache.catalina.connector.Request.notifyAttributeAssigned(Request.java:1528) 在 org.apache.catalina.connector.Request.setAttribute(Request.java:1514) 在 org.apache.catalina.connector.RequestFacade.setAttribute(RequestFacade.java:540) 在 org.zkoss.zk.ui.http.ExecutionImpl.setAttribute(ExecutionImpl.java:497) 在org.zkoss.zk.ui.impl.Utils.getComponentInfos(Utils.java:120)at org.zkoss.zk.ui.impl.Utils.setComponentInfo(Utils.java:129)at org.zkoss.zk.ui.impl.AbstractUiFactory.newComponent(AbstractUiFactory.java:137) 在 org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild0(UiEngineImpl.java:919) 在 org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:889) 在 org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:776) 在org.zkoss.zk.ui.impl.UiEngineImpl.access $ 800(UiEngineImpl.java:128) 在 org.zkoss.zk.ui.impl.UiEngineImpl $ TemplateImpl.create(UiEngineImpl.java:2318) 在 org.zkoss.bind.impl.BindListitemRenderer.render(BindListitemRenderer.java:79) 在org.zkoss.zul.Listbox $ Renderer.render(Listbox.java:2769)at at org.zkoss.zul.Listbox.doInitRenderer(Listbox.java:2584)at org.zkoss.zul.Listbox.onInitRender(Listbox.java:2537)at sun.reflect.GeneratedMethodAccessor2366.invoke(未知来源)at sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源)at java.lang.reflect.Method.invoke(未知来源)at org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:3146) 在 org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:3077) 在 org.zkoss.zk.ui.impl.EventProcessor.process(EventProcessor.java:138) 在 org.zkoss.zk.ui.impl.UiEngineImpl.processEvent(UiEngineImpl.java:1846) 在org.zkoss.zk.ui.impl.UiEngineImpl.process(UiEngineImpl.java:1618) 在org.zkoss.zk.ui.impl.UiEngineImpl.endUpdate(UiEngineImpl.java:1222) 在 org.zkoss.zkex.ui.comet.CometServerPush.deactivate(CometServerPush.java:522) 在 org.zkoss.zk.ui.impl.DesktopImpl.deactivateServerPush(DesktopImpl.java:1596) 在org.zkoss.zk.ui.Executions.deactivate(Executions.java:1011)at at com.ims.web.ui.GenericViewModel.deactivateNativeDesktop(GenericViewModel.java:193) 在 com.ims.web.zk.ui.DesktopVMLongUIOperation.run(DesktopVMLongUIOperation.java:186) 在java.lang.Thread.run(未知来源)
用例示例:
@Command
@Override
public void editBaseItem() throws Exception {
super.editBaseItem();
if(selectedBaseItem.getOid() == null){
initNewItem();
}
final String sessionID = getSessionID();
final StaffDailyAvailabilityVM instanceVM = this;
new DesktopVMLongUIOperation(this,win,Labels.getLabel("def.msg.refreshdata","Refresh data...")) {
@Override
protected void execute() throws InterruptedException {
try {
StaffDailyAvailabilityManager.evaluateStaffDailyAvailabilitySynch(selectedBaseItem, sessionID);
} catch (Exception e) {
logger.error(e,e);
}
}
protected void onCleanup() {
try {
//refresh clock time list
selectedBaseItem.getLastStaffDailyTimestampDTO();
if(selectedBaseItem.isErrorDetected()){
selectedBaseItem.setCertified(false);
}
BindUtils.postNotifyChange(null, null, instanceVM.getSelectedBaseItem(),"lastStaffDailyTimestampDTO");
BindUtils.postNotifyChange(null, null, instanceVM, "selectedBaseItem");
} catch (Exception e) {
logger.error(e,e);
}
};
}.start();
}
这里是代码:
公共抽象类DesktopVMLongUIOperation实现Runnable { protected static final Logger logger = Logger.getLogger(DesktopVMLongUIOperation.class); 私有线程线程; private AtomicBoolean canceled = new AtomicBoolean(false); 私人窗口胜利; private GenericViewModel genericViewModel;
public DesktopVMLongUIOperation(GenericViewModel genericViewModel){
this(genericViewModel,null,"");
}
public DesktopVMLongUIOperation(GenericViewModel genericViewModel, Window win, String busyMsg){
this.win = win;
this.genericViewModel = genericViewModel;
try {
this.genericViewModel.enableServerPush(null);
if(win != null){
Clients.showBusy(win,busyMsg);
}
} catch (Exception e) {
logger.error(e,e);
}
}
/**
* asynchronous callback for your long operation code
* @throws InterruptedException
*/
protected abstract void execute() throws InterruptedException;
/**
* optional callback method when the task has completed successfully
*/
protected void onFinish() {};
/**
* optional callback method when the task has been cancelled or was interrupted otherwise
*/
protected void onCancel() {};
/**
* optional callback method when the task has completed with an uncaught RuntimeException
* @param exception
*/
protected void onException(RuntimeException exception) {
logger.error(exception,exception);
};
/**
* optional callback method when the task has completed (always called)
*/
protected void onCleanup() {};
/**
* set the cancelled flag and try to interrupt the thread
*/
public final void cancel() {
try {
cancelled.set(true);
if(thread != null){
thread.interrupt();
}
} catch (Throwable e) {
logger.error(e,e);
}
}
/**
* check the cancelled flag
* @return
*/
public final boolean isCancelled() {
return cancelled.get();
}
/**
* Checks if the task thread has been interrupted. Use this to check whether or not to exit a busy operation in case.
* @throws InterruptedException when the current task has been cancelled/interrupted
*/
protected final void checkCancelled() throws InterruptedException {
try {
if(Thread.currentThread() != this.thread) {
throw new IllegalStateException("this method can only be called in the worker thread (i.e. during execute)");
}
boolean interrupted = Thread.interrupted();
if(interrupted || cancelled.get()) {
cancelled.set(true);
throw new InterruptedException();
}
} catch (Throwable e) {
logger.error(e,e);
}
}
/**
* launch the long operation
*/
public final void start() {
try {
thread = new Thread(this);
thread.start();
} catch (Throwable e) {
logger.error(e,e);
}
}
@Override
public final void run() {
try {
try {
checkCancelled(); //avoid unnecessary execution
execute();
checkCancelled(); //final cancelled check before calling onFinish
genericViewModel.activateNativeDesktop();
logger.error("ACTIVATE: RUN");
onFinish();
} catch (InterruptedException e) {
try {
cancelled.set(true);
genericViewModel.activateNativeDesktop();
logger.error("ACTIVATE: INTERRUPT");
onCancel();
} catch (InterruptedException e1) {
throw new RuntimeException("interrupted onCancel handling", e1);
} catch (Exception e1) {
logger.error(e1,e1);
} finally {
try {
genericViewModel.deactivateNativeDesktop();
logger.error("DEACTIVATE: INTERRUPT");
} catch (Exception e1) {
logger.error(e1,e1);
}
}
} catch (RuntimeException rte) {
try {
genericViewModel.activateNativeDesktop();
logger.error("ACTIVATE: EXCEPTION");
onException(rte);
} catch (InterruptedException e1) {
throw new RuntimeException("interrupted onException handling", e1);
} catch (Exception e) {
logger.error(e,e);
} finally {
try {
genericViewModel.deactivateNativeDesktop();
logger.error("ACTIVATE: EXCEPTION");
} catch (Exception e) {
logger.error(e,e);
}
}
throw rte;
} catch (Exception e) {
logger.error(e,e);
} finally {
try {
genericViewModel.deactivateNativeDesktop();
logger.error("DEACTIVATE: RUN");
} catch (Exception e) {
logger.error(e,e);
}
}
} finally {
try {
genericViewModel.activateNativeDesktop();
logger.error("ACTIVATE: CLEANUP");
try {
if(win != null){
Clients.clearBusy(win);
}
} catch (Exception e) {
logger.error(e,e);
}
onCleanup();
} catch (InterruptedException e1) {
throw new RuntimeException("interrupted onCleanup handling", e1);
} catch (Exception e1) {
logger.error(e1,e1);
} finally {
try {
genericViewModel.deactivateNativeDesktop();
logger.error("DEACTIVATE: CLEANUP");
} catch (Exception e) {
logger.error(e,e);
}
}
}
}
}
并从genericViewModel激活停用代码:
...... public GenericViewModel(){nativeDesktop = Executions.getCurrent()。getDesktop(); }
......
public GenericViewModel(){
nativeDesktop = Executions.getCurrent().getDesktop();
}
public boolean activateNativeDesktop() throws Exception{
boolean res = false;
if(getNativeDesktop() != null && getNativeDesktop().isAlive()){
try {
Executions.activate(getNativeDesktop());
res = true;
} catch (Throwable e) {
logger.error(e,e);
throw(e);
}
}else{
throw new Exception("ZK native Desktop is null");
}
return res;
}
public boolean deactivateNativeDesktop() throws Exception{
boolean res = false;
if(getNativeDesktop() != null && getNativeDesktop().isAlive()){
try {
Executions.deactivate(getNativeDesktop());
res = true;
} catch (Throwable e) {
logger.error(e,e);
throw(e);
}
}else{
throw new Exception("ZK native Desktop is null");
}
return res;
}