I think this is not a particular problem for me; everyone could face this problem earlier. To illustrate this correctly, here is a simple interface:

As you can see, these two counters control one variable - "A". The only difference is that they control it using different views.
Since the displayed values โโof these two counters are synchronized, a cyclic event appears.
If I change the upper counter, โAโ will change and the value of the lower counter will also be updated accordingly. However, updating a lower counter call (such as setValue) will also trigger another event instructing the upper counter to update based on the value of the lower counter. This creates the wrong loop, which could ultimately throw a StackOverFlow exception.
My earlier decision was rather cumbersome: I placed a protective boolean value to indicate whether a second update call should be made.
Now I would like to ask: " How can I handle this situation elegantly? ( In general, not only for spinners )"
thanks
Update:
Since I have 2 answers suggesting I use the observer structure, I have to say something about this.
Like what I said, it's great, but far from perfect. Not only because of its inherent complexity, but also because of the inability to solve the problem .
What for? To see the reason, you must implement the close relationship of View and Model-Controller in Java Swing. Let's take my counter user interface as an example. Assume that the variable A is actually an Observer object. Then, after the first state change event is triggered from the upper counter, observer "A" will update its value and fire the PropertyChange event to notify the lower counter. Then comes the 2nd update, which updates the look of the lower counter. However, a change in the appearance of the lower counter inevitably causes an excess event, in which it will again try to set the value to "A". After that, the death cycle will be fully created, and a stack overflow will be generated.
Theoretically, the Observer model attempts to solve a direct cycle by introducing 2 independent feedback paths. The chained update chances (in response event codes) implicitly form a bridge connecting the two paths, again looping.