2016-08-26 30 views
1

我有一個Vaadin 7應用程序,它有一個公共佈局,並且在其中有一個按鈕,啓動一個線程,執行一些計算。動態地從線程中刪除和添加組件中的組件

有來自計算接收信息並顯示進度信息等

現在,當我啓動應用程序並執行計算線程的組成部分,一切都很好,並認爲是正確的建設。

當它做,我重新運行它,只需再次按下啓動按鈕,我得到

Exception in thread "Thread-56" java.lang.IllegalStateException: A connector should not be marked as dirty while a response is being written. 
at com.vaadin.ui.ConnectorTracker.markDirty(ConnectorTracker.java:505) 
at com.vaadin.server.AbstractClientConnector.markAsDirty(AbstractClientConnector.java:141) 
at com.vaadin.ui.AbstractComponentContainer.removeComponent(AbstractComponentContainer.java:227) 
at com.vaadin.ui.AbstractOrderedLayout.removeComponent(AbstractOrderedLayout.java:178) 
at com.test.pipeline.view.ResultPanel.rebuildResultLayout(ResultPanel.java:46) 
at com.test.pipeline.view.ResultUIProcessListener.startTests(ResultUIProcessListener.java:40) 
at com.test.pipeline.RanorexClient$RanorexWorker$$Lambda$224/988244250.accept(Unknown Source) 
at java.util.ArrayList.forEach(ArrayList.java:1249) 
at com.test.pipeline.RanorexClient$RanorexWorker.inform(RanorexClient.java:99) 
at com.test.pipeline.RanorexClient$RanorexWorker.run(RanorexClient.java:64) 

RanorexoClient$RanorexWorkerThread做計算。 有聽衆註冊到工作人員得到通知。

所以我有一個鏈表來改變UI的線程。

rebuildResultLayout看起來像這樣

void rebuildResultLayout() { 
    mainLayout.removeComponent(resultLayout); 
    resultLayout = new VerticalLayout(); 
    mainLayout.addComponent(resultLayout); 
} 

因此刪除佈局,則創建一個新的,然後重新添加。這是擺脫以前運行的信息 - 我也試圖簡單地resultLayout.removeAllComponents(),但這會導致相同的錯誤。

我讀的地方給調用UI同步,所以目前我inform方法看起來像這樣

private void inform(Consumer<TestProcessListener> action) { 
    synchronized (UI.getCurrent()) { 
     processListeners.forEach(action); 
    } 
} 

有什麼不對?必須做些什麼來避免這種異常?

+0

哎呀 - 我可能已經找到了答案:https://vaadin.com/docs/-/part/framework/advanced /advanced-push.html。使用'ui.access'解決了我的問題。任何人都可以證實,這個觀察現在不僅僅是運氣嗎? –

+1

是的,這就是要求。只要確保在後臺線程中有一個有效的UI參考。使用分離線程時,UI.getCurrent()並不總是存在 –

回答