source: josm/trunk/src/org/openstreetmap/josm/gui/util/AdjustmentSynchronizer.java@ 10210

Last change on this file since 10210 was 10210, checked in by Don-vip, 8 years ago

see #11924 - Java 9 - replace calls to deprecated classes java.util.Observable / java.util.Observer by a new class ChangeNotifier + swing's ChangeListener

  • Property svn:eol-style set to native
File size: 5.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.util;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Adjustable;
7import java.awt.event.AdjustmentEvent;
8import java.awt.event.AdjustmentListener;
9import java.awt.event.ItemEvent;
10import java.awt.event.ItemListener;
11import java.util.HashMap;
12import java.util.HashSet;
13import java.util.Map;
14import java.util.Set;
15
16import javax.swing.JCheckBox;
17import javax.swing.event.ChangeEvent;
18import javax.swing.event.ChangeListener;
19
20import org.openstreetmap.josm.tools.CheckParameterUtil;
21
22/**
23 * Synchronizes scrollbar adjustments between a set of {@link Adjustable}s.
24 * Whenever the adjustment of one of the registered Adjustables is updated
25 * the adjustment of the other registered Adjustables is adjusted too.
26 * @since 6147
27 */
28public class AdjustmentSynchronizer implements AdjustmentListener {
29
30 private final Set<Adjustable> synchronizedAdjustables;
31 private final Map<Adjustable, Boolean> enabledMap;
32
33 private final ChangeNotifier observable;
34
35 /**
36 * Constructs a new {@code AdjustmentSynchronizer}
37 */
38 public AdjustmentSynchronizer() {
39 synchronizedAdjustables = new HashSet<>();
40 enabledMap = new HashMap<>();
41 observable = new ChangeNotifier();
42 }
43
44 /**
45 * Registers an {@link Adjustable} for participation in synchronized scrolling.
46 *
47 * @param adjustable the adjustable
48 */
49 public void participateInSynchronizedScrolling(Adjustable adjustable) {
50 if (adjustable == null)
51 return;
52 if (synchronizedAdjustables.contains(adjustable))
53 return;
54 synchronizedAdjustables.add(adjustable);
55 setParticipatingInSynchronizedScrolling(adjustable, true);
56 adjustable.addAdjustmentListener(this);
57 }
58
59 /**
60 * Event handler for {@link AdjustmentEvent}s
61 */
62 @Override
63 public void adjustmentValueChanged(AdjustmentEvent e) {
64 if (!enabledMap.get(e.getAdjustable()))
65 return;
66 for (Adjustable a : synchronizedAdjustables) {
67 if (a != e.getAdjustable() && isParticipatingInSynchronizedScrolling(a)) {
68 a.setValue(e.getValue());
69 }
70 }
71 }
72
73 /**
74 * Sets whether {@code adjustable} participates in adjustment synchronization or not
75 *
76 * @param adjustable the adjustable
77 * @param isParticipating {@code true} if {@code adjustable} participates in adjustment synchronization
78 */
79 protected void setParticipatingInSynchronizedScrolling(Adjustable adjustable, boolean isParticipating) {
80 CheckParameterUtil.ensureParameterNotNull(adjustable, "adjustable");
81 if (!synchronizedAdjustables.contains(adjustable))
82 throw new IllegalStateException(
83 tr("Adjustable {0} not registered yet. Cannot set participation in synchronized adjustment.", adjustable));
84
85 enabledMap.put(adjustable, isParticipating);
86 observable.fireStateChanged();
87 }
88
89 /**
90 * Returns true if an adjustable is participating in synchronized scrolling
91 *
92 * @param adjustable the adjustable
93 * @return true, if the adjustable is participating in synchronized scrolling, false otherwise
94 * @throws IllegalStateException if adjustable is not registered for synchronized scrolling
95 */
96 protected boolean isParticipatingInSynchronizedScrolling(Adjustable adjustable) {
97 if (!synchronizedAdjustables.contains(adjustable))
98 throw new IllegalStateException(tr("Adjustable {0} not registered yet.", adjustable));
99
100 return enabledMap.get(adjustable);
101 }
102
103 /**
104 * Wires a {@link JCheckBox} to the adjustment synchronizer, in such a way that:
105 * <ol>
106 * <li>state changes in the checkbox control whether the adjustable participates
107 * in synchronized adjustment</li>
108 * <li>state changes in this {@link AdjustmentSynchronizer} are reflected in the
109 * {@link JCheckBox}</li>
110 * </ol>
111 *
112 * @param view the checkbox to control whether an adjustable participates in synchronized adjustment
113 * @param adjustable the adjustable
114 * @throws IllegalArgumentException if view is null
115 * @throws IllegalArgumentException if adjustable is null
116 */
117 public void adapt(final JCheckBox view, final Adjustable adjustable) {
118 CheckParameterUtil.ensureParameterNotNull(adjustable, "adjustable");
119 CheckParameterUtil.ensureParameterNotNull(view, "view");
120
121 if (!synchronizedAdjustables.contains(adjustable)) {
122 participateInSynchronizedScrolling(adjustable);
123 }
124
125 // register an item lister with the check box
126 //
127 view.addItemListener(new ItemListener() {
128 @Override
129 public void itemStateChanged(ItemEvent e) {
130 switch(e.getStateChange()) {
131 case ItemEvent.SELECTED:
132 if (!isParticipatingInSynchronizedScrolling(adjustable)) {
133 setParticipatingInSynchronizedScrolling(adjustable, true);
134 }
135 break;
136 case ItemEvent.DESELECTED:
137 if (isParticipatingInSynchronizedScrolling(adjustable)) {
138 setParticipatingInSynchronizedScrolling(adjustable, false);
139 }
140 break;
141 }
142 }
143 });
144
145 observable.addChangeListener(
146 new ChangeListener() {
147 @Override
148 public void stateChanged(ChangeEvent e) {
149 boolean sync = isParticipatingInSynchronizedScrolling(adjustable);
150 if (view.isSelected() != sync) {
151 view.setSelected(sync);
152 }
153 }
154 }
155 );
156 setParticipatingInSynchronizedScrolling(adjustable, true);
157 view.setSelected(true);
158 }
159}
Note: See TracBrowser for help on using the repository browser.