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.
> 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>
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/>