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

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

see #11390 - sonar - squid:S1604 - Java 8: Anonymous inner classes containing only one method should become lambdas

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