Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Suppresing events to avoid fibrillation

106 views
Skip to first unread message

Roedy Green

unread,
Dec 30, 2009, 6:44:16 PM12/30/09
to
I run into this problem frequently. I call it fibrillation.

Lets say I do a setText on some component. This triggers an event on
it. That event handler then might do setText's on other components.
If you are really unlucky, you get a circularity.

What would like to do is a sneaky programmatic setText that does NOT
trigger any events, other than perhaps a repaint.

What I have been doing is somewhat klutzy. I have some ad hoc
booleans. When I don't want an event to be acted on, I set the
boolean, then detect it in the event handler, and turn it off.

You need one boolean for each possible event that might be triggered.
If it is not triggered, the event improperly stays suppressed.

Is there a clean way to do this?
--
Roedy Green Canadian Mind Products
http://mindprod.com
If you give someone a program, you will frustrate them for a day; if you teach them how to program, you will frustrate them for a lifetime.

John B. Matthews

unread,
Dec 30, 2009, 10:22:07 PM12/30/09
to
In article <h5pnj5t7eqejbsq0h...@4ax.com>,
Roedy Green <see_w...@mindprod.com.invalid> wrote:

> I run into this problem frequently. I call it fibrillation.
>
> Lets say I do a setText on some component. This triggers an event on
> it. That event handler then might do setText's on other components.
> If you are really unlucky, you get a circularity.

Interestingly, one model of cardiac fibrillation involves an analogous
kind of circularity:

<http://en.wikipedia.org/wiki/Cardiac_arrhythmia#Re-entry>

> What would like to do is a sneaky programmatic setText that does NOT
> trigger any events, other than perhaps a repaint.
>
> What I have been doing is somewhat klutzy. I have some ad hoc
> booleans. When I don't want an event to be acted on, I set the
> boolean, then detect it in the event handler, and turn it off.
>
> You need one boolean for each possible event that might be triggered.
> If it is not triggered, the event improperly stays suppressed.
>
> Is there a clean way to do this?

It's no panacea, but assiduously separating the model and views seems to
mitigate this somewhat. Each control updates the model only, never
another view. The model then notifies the views that the model's state
has changed. The views then query the model for the new state and repaint
themselves. I often have the model extend Observable to notify the views,
each of which implements Observer. Observers can compare the model value
to their own state and ignore null changes.

Here's my favorite picture:

<http://java.sun.com/blueprints/patterns/images/mvc-structure-generic.gif>

Of course, sometimes I just have each listener update the other component:

<fragment>
public class SpinSlider extends JPanel {

public SpinSlider() {
this.setLayout(new FlowLayout());
final JSpinner spinner = new JSpinner();
final JSlider slider = new JSlider();
slider.addChangeListener(new ChangeListener() {
//@Override
public void stateChanged(ChangeEvent e) {
JSlider s = (JSlider) e.getSource();
spinner.setValue(s.getValue());
}
});
this.add(slider);
spinner.setModel(new SpinnerNumberModel(50, 0, 100, 1));
spinner.addChangeListener(new ChangeListener() {
//@Override
public void stateChanged(ChangeEvent e) {
JSpinner s = (JSpinner) e.getSource();
slider.setValue((Integer) s.getValue());
}
});
this.add(spinner);
}
}
</fragment>

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

Daniel Pitts

unread,
Dec 30, 2009, 11:06:45 PM12/30/09
to
Roedy Green wrote:
> I run into this problem frequently. I call it fibrillation.
>
> Lets say I do a setText on some component. This triggers an event on
> it. That event handler then might do setText's on other components.
> If you are really unlucky, you get a circularity.
>
> What would like to do is a sneaky programmatic setText that does NOT
> trigger any events, other than perhaps a repaint.
>
> What I have been doing is somewhat klutzy. I have some ad hoc
> booleans. When I don't want an event to be acted on, I set the
> boolean, then detect it in the event handler, and turn it off.
>
> You need one boolean for each possible event that might be triggered.
> If it is not triggered, the event improperly stays suppressed.
>
> Is there a clean way to do this?
Use a shared model amongst all your views. Don't listen for changes on
a particular visual element, but instead have the business logic handled
in your model. This also will help prevent coupling your business model
to GUI.

The other possibility is to check for an actual "difference" in value
before setting off other events.

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

0 new messages