This is an issue that a lot of us Swing programmers have to face: multiple controls modifying the same data, with the update then reflected in each control. At some point, something has to have the ultimate veto on what updates will be applied to the model: whatever that something is needs to be able to handle multiple (potentially redundant or even contradictory) updates and decide what to do with them. This could happen in the model layer, but ideally it should be the controller that does this - this piece, after all, is most likely where the business logic resides.
The problem with Swing, in this regard, is that the controller piece of MVC is often split somewhat between the view component and the model so it can be difficult to have that logic centralised. To some extent the Action
interface rectifies this for actionPerformed() events by putting the logic in one place and allowing it to be shared by different components, but this doesn't help for the other types of event, or when there are multiple different classes of event that need to be coordinated.
The answer, then, is to follow a pattern that's hinted at in Swing but not made explicit: only perform the requested update if the state will actually change, otherwise do nothing. An example of this is in the JList
itself: if you attempt to set the selected index of a JList
to the same index that's already selected nothing will happen. No events will be fired, no updates will occur: the update request is effectively ignored. This is a good thing. This means that you can, for example, have a listener on your JList
that will respond to a newly selected item, and then in turn ask the same JList
to reselect that same item and you won't get stuck in a pathologically recursive loop. If all the model-controllers in an application do this then there's no problem with multiple, repeated events firing off all over the place - each component will only update itself (and subsequently fire off events) if it needs to, and if it does update then it can fire off all the update events it wants, but only those components that haven't already got the message will do anything about it.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…