I was wondering if the following is common for "regular" Java applications when receiving callback/events. Those callbacks may be triggered by user input but also by other means so it is not only related to UI events:
public void handleEvent( @NotNull final SomeEvent e ) {
final boolean process;
synchronized ( this ) {
process = !e.equals(filter);
filter = e;
}
if ( process ) {
...
}
}
Basically under some complicated scheme (very complex UI involving several views of a same model and where the user can modify the model from different screens [like in complex 3D programs]) I've got lots of events firing and I've noticed that I could filter out duplicate events using the above snippet. If an event has been processed and the next event to come is exactly identical to the last processed event (saved in the filter
reference), the开发者_如何学Pythonn the event/callback is simply ignored.
It works fine. I was wondering if filtering out duplicate events was a common technique?
Not always, but usually this can be a sign that some elements of the event cascade chain aren't properly detecting that they don't need to send an event. The classic illustration is a bean setter that generates a PropertyChangeEvent even when the value hasn't changed.
While what you've done will filter these events out, it doesn't address what may be a fundamental underlying issue.
The problem is that these "errors" can combine to form infinite loops. Extending the bean example above, say you have a UI that resets its editable value based on that bean field... and resetting the UI value will also call the bean setter because proper dupe checking wasn't done there either. The first time the value is edited and endless loop will occur.
These examples are obvious when they happen but as notification hierarchies get more complicated it becomes harder to track these things down and they potentially occur at more intermittent times.
A good rule of thumb is to make every event generating component as conservative as possible. In the event (heh) you are receiving notifications from components that you can't control, and will be forwarding your own events also then a filter like the one you've setup may be the only option to prevent the spread of a potentially larger problem than just performance.
The only thing I can think of is acting on a ListSelectionEvent
based on whether the selection is still changing (i.e. the user is still clicking and dragging the mouse) or whether the event represents the "final" selection event; e.g.
public class MyListSelectionListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent evt) {
// Finished selecting
if (!evt.getValueIsAdjusting()) {
JOptionPane.showMessageDialog("Selection Complete!");
}
}
}
Looks like you might have a listener registered twice to the same source. That could cause it. Or possibly you've registered a single listener across multiple instances. If you're seeing strangeness, look for infinite event loops which, unfortunately, because of the way Swing program organize themselves, can happen all too easily. You'll want to break those listeners apart.
I've never done this sort of thing or encountered it. As some people point out certain controls will fire events when selections are being adjusted, but there are methods to filter those things out.
The synchronized( this ) block is suspect too since you'll always be called back on the Swing thread. If that's not true in your program then you are violating Swing's threading rule, and that could explain the problem. Bottom line is you don't need the synchronized block because Swing is single threaded.
(I'm assuming this is Swing as some other posters have, but from your code alone it's ambiguous).
精彩评论