如何在一个单独的线程完成之前禁用 SWT selectionListener
Posted
技术标签:
【中文标题】如何在一个单独的线程完成之前禁用 SWT selectionListener【英文标题】:How to disable an SWT selectionListener until a separate thread has been completed 【发布时间】:2017-03-11 19:55:36 【问题描述】:我有一个带有 GUI 线程和 SQL 线程的应用程序。 GUI 中显示了一棵树,单击树中的某个项目将启动一个单独的线程,该线程将启动 SQL 查询。查询完成后,树就会更新。
问题是,如果用户在获取线程完成之前再次点击树,树将在它有机会完成获取数据之前更新,并且树将被错误地更新。有什么方法可以在启动另一个线程之前禁用侦听器,然后在线程完成后重新启用它以防止虚假查询?
private SelectionListener getTreeListener()
//main tree listener that populates folder and report objects on the left side of the SashForm
SelectionListener l = new SelectionAdapter()
@Override
public void widgetSelected(SelectionEvent arg0)
Thread runThread = new FetchTreeChildrenThread(_es,_mgr,_PAI,_PE,_SelectedPub,Selected_Tree_Item);
runThread.start();
【问题讨论】:
如果您认为某个答案解决了问题,请单击绿色复选标记将其标记为“已接受”。这有助于将注意力集中在仍然没有答案的旧帖子上。 【参考方案1】:获取代码需要提供在查询完成后从“SQL 线程”中调用的回调。
然后 UI 代码可以注册这样的回调,以便在执行查询后重新启用树。
例如(在widgetSelected
方法中):
Display display = new Display();
Runnable uiUpdateCode = new Runnable()
@Override
public void run()
if( !tree.isDisposed() )
// re-attach selection listner
;
Runnable doneCallback = new Runnable()
@Override
public void run()
if( !display.isDisposed() )
display.asyncExec( uiUpdateCode );
;
Thread backgroundThread = new Thread( new Runnable()
@Override
public void run()
// ... execute query
doneCallback.run();
);
backgroundThread.start();
请注意,SWT 只允许在 UI 线程上执行的代码来操作小部件。因此,display.asyncExec()
安排给定的可运行文件“在下一个合理的机会”在 UI 线程上执行。
另请注意,在调用 runnable 时,具有 的小部件可能已被处理掉。因此,在访问小部件之前,有必要在 runnable 内部检查这种情况。
【讨论】:
【参考方案2】:与其纠结是否启用了侦听器,您可以只跟踪您启动的线程,而不是在前一个线程完成之前启动另一个线程。
见Thread.isAlive()
private SelectionListener getTreeListener()
//main tree listener that populates folder and report objects on the left side of the SashForm
SelectionListener l = new SelectionAdapter()
private Thread runThread;
@Override
public void widgetSelected(SelectionEvent arg0)
if (runThread == null || (!runThread.isAlive()))
runThread = new FetchTreeChildrenThread(_es,_mgr,_PAI,_PE,_SelectedPub,Selected_Tree_Item);
runThread.start();
【讨论】:
以上是关于如何在一个单独的线程完成之前禁用 SWT selectionListener的主要内容,如果未能解决你的问题,请参考以下文章