如何在完成单独的线程之前禁用SWT selectionListener

时间:2016-10-28 21:13:13

标签: java multithreading swt listener

我有一个带有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();
        }
    }

}

2 个答案:

答案 0 :(得分: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()会调度给定的runnable在下一个合理的机会'在UI线程上执行'。

另请注意,在调用runnable时,可能已经处理掉了可能的小部件。因此,在访问窗口小部件之前,有必要在runnable中检查这种情况。

答案 1 :(得分:0)

不管是否启用了侦听器,您都可以跟踪您启动的线程,而不是在上一个完成之前启动另一个线程。

请参阅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();
            }
        }
    }
}