I have a JFace editor that is mostly made up of a TreeViewer
. This is hooked up to a ContentOutlinePage
to bring the Outline view to life.
我有一个JFace编辑器,主要由TreeViewer组成。它连接到ContentOutlinePage以使Outline视图生动。
When either one receives a SelectionChangedEvent
they call the others setSelection()
method ... and therein lies the problem. setSelection()
generates another SelectionChangedEvent
... and thus the infinite loop is joined.
当任何一个收到SelectionChangedEvent时,他们会调用其他的setSelection()方法......其中就存在问题。 setSelection()生成另一个SelectionChangedEvent ...因此连接了无限循环。
Is there a means of telling if the SelectionChangedEvent
was created by actual user interaction rather than by another object calling setSelection()
?
有没有办法告诉SelectionChangedEvent是由实际用户交互而不是由另一个调用setSelection()的对象创建的?
Is there a better means still of stopping this sort of deadly-embrace?
有没有更好的手段来阻止这种致命的拥抱?
Clues welcomed.
2 个解决方案
#1
Generally, you would check a flag in the beginning of the routine to check to see if you are in the middle of the event handler. If the flag is set, then you exit without processing.
通常,您将检查例程开头的标志,以检查您是否在事件处理程序的中间。如果设置了标志,则退出而不进行处理。
If the flag is not set, you set the flag, process, then set the flag back.
如果未设置该标志,则设置标志,进程,然后将标志设置回。
#2
Another pattern that works is to remove the event listener, make the selection, add the eventlistener back again. This ensures that there is a single place in the code where you have to worry about this - with a flag you would have to simultaneously maintain two places.
另一个有效的模式是删除事件侦听器,进行选择,再次添加eventlistener。这样可以确保代码中只有一个地方您需要担心这一点 - 使用标记您必须同时维护两个地方。
Also, the SelectionChangedChanged is possibly (not sure though) put on top of the event stack (ie executed asynchronously). In which case, you also minimise the period during which the viewer does not propagate notification.
此外,SelectionChangedChanged可能(不确定)放在事件堆栈之上(即异步执行)。在这种情况下,您还可以最小化查看器不传播通知的时间段。
Overall, I find it disappointing that the SelectionChangedEvent generated is the same, regardless of whether a mouse was clicked. I suppose it's not as easy to do that as one would hope. I once had to modify a text editor class behaviour so that it new about two kinds of insert events (user generated and network generated) in order to make that text editor class shared. I'd love to see more discussion of this.
总的来说,无论是否点击了鼠标,我都发现生成的SelectionChangedEvent是相同的,这令人失望。我想这并不像人们希望的那样容易。我曾经不得不修改一个文本编辑器类的行为,以便它新出现两种插入事件(用户生成和网络生成),以便共享该文本编辑器类。我很乐意看到对此的更多讨论。
#1
Generally, you would check a flag in the beginning of the routine to check to see if you are in the middle of the event handler. If the flag is set, then you exit without processing.
通常,您将检查例程开头的标志,以检查您是否在事件处理程序的中间。如果设置了标志,则退出而不进行处理。
If the flag is not set, you set the flag, process, then set the flag back.
如果未设置该标志,则设置标志,进程,然后将标志设置回。
#2
Another pattern that works is to remove the event listener, make the selection, add the eventlistener back again. This ensures that there is a single place in the code where you have to worry about this - with a flag you would have to simultaneously maintain two places.
另一个有效的模式是删除事件侦听器,进行选择,再次添加eventlistener。这样可以确保代码中只有一个地方您需要担心这一点 - 使用标记您必须同时维护两个地方。
Also, the SelectionChangedChanged is possibly (not sure though) put on top of the event stack (ie executed asynchronously). In which case, you also minimise the period during which the viewer does not propagate notification.
此外,SelectionChangedChanged可能(不确定)放在事件堆栈之上(即异步执行)。在这种情况下,您还可以最小化查看器不传播通知的时间段。
Overall, I find it disappointing that the SelectionChangedEvent generated is the same, regardless of whether a mouse was clicked. I suppose it's not as easy to do that as one would hope. I once had to modify a text editor class behaviour so that it new about two kinds of insert events (user generated and network generated) in order to make that text editor class shared. I'd love to see more discussion of this.
总的来说,无论是否点击了鼠标,我都发现生成的SelectionChangedEvent是相同的,这令人失望。我想这并不像人们希望的那样容易。我曾经不得不修改一个文本编辑器类的行为,以便它新出现两种插入事件(用户生成和网络生成),以便共享该文本编辑器类。我很乐意看到对此的更多讨论。