1

For the smallest example, I have three Swing JComponent elements that need to interact with each other: a JSlider, and two JTextFields. The JSlider goes from 0 to 50, one of the JTextFields shows the value of the JSlider and the second JTextField shows the percentage of the total value (i.e. 2 in the JSlider would update 4% in the second JTextField).

A change in any one of the three elements should update all the others. So a ChangeEvent in the JSlider should trigger setText() events in the JTextFields. However, setText() triggers ActionEvents in the TextFields which should, in this case, trigger a change in value for the JSlider.

I've been tackling this problem with a "refreshing" boolean flag, where the boolean would be checked before processing the ActionEvent / ChangeEvent. but I'd like to know if there's any more programmatic or cleaner way of preventing the ActionEvent / ChangeEvent loop.

I'd appreciate any insights!


Edit

I'm attempting to make this work with histogram information, where the percentage values will not exactly match the slider values (i.e. there will be rounding errors). The suggested SpinSliders relies on the setText() method being able to "settle" on a final value. In other words, if the value input to setText() is the same as the text it already holds, it does not fire an ActionEvent, effectively ending the loop. If the rounding is off, the setValue() of the JSlider and the setText() of the JTextField will never reach an "equilibrium" state due to rounding. I hope that describes the problem succinctly.

Community
  • 1
  • 1
ddukki
  • 189
  • 2
  • 13
  • 1
    You could compute the new value in each component's listener. This computation is straightforward in the slider and the absolute value text field. In the percentage text field, you'll have to do a product. Then you can call an `update` function that updates all three fields (yeah, even the one that just got changed). So make sure you have a means to discern programmatic vs user-initiated events in the change listeners. Another option is to use the [mediator pattern](http://en.wikipedia.org/wiki/Mediator_pattern) – Mister Smith Dec 03 '13 at 16:38
  • 1
    [`SpinSlider`](http://stackoverflow.com/a/6067986/230513) may be a useful example. – trashgod Dec 03 '13 at 17:32
  • @MisterSmith I've been looking into the programmatic vs user-initiated events for the change listeners, but I've come up empty. That distinction would make the most sense, but there's nothing in the Java API that I could find. – ddukki Dec 03 '13 at 17:55
  • @trashgod That is exactly the functionality I'm looking for. However, in my toy example, the percentages are able to map one-to-one with the slider values. However, I'm trying to make a histogram map, where the percentages may not coincide and the integer and percentage values end up fluctuating because of a rounding error. I need, therefore, `setValue()` to be triggered a maximum of once. – ddukki Dec 03 '13 at 17:58
  • 1
    You may be able to leverage `getValueIsAdjusting()`. – trashgod Dec 03 '13 at 18:06
  • 1
    @trashgod That did it! Thanks! I made sure that the slider only updated if it was `getValueAdusting()` and the textfields only updated on the opposite condition. Though, I had to modularize the updating so that the slider and the two textfields each had their own update method. I'd be happy to mark this as the answer if you want to add one. – ddukki Dec 03 '13 at 18:45

1 Answers1

1

SpinSlider may be a useful starting point. As you must be able to "settle" on a final value, use getValueIsAdjusting() to update once the final value is available.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045