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

Last change on this file since 6340 was 6316, checked in by Don-vip, 11 years ago

Sonar/FindBugs - Loose coupling

  • Property svn:eol-style set to native
File size: 5.8 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.ArrayList;
12import java.util.HashMap;
13import java.util.List;
14import java.util.Map;
15import java.util.Observable;
16import java.util.Observer;
17
18import javax.swing.JCheckBox;
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 List<Adjustable> synchronizedAdjustables;
31 private final Map<Adjustable, Boolean> enabledMap;
32
33 private final Observable observable;
34
35 /**
36 * Constructs a new {@code AdjustmentSynchronizer}
37 */
38 public AdjustmentSynchronizer() {
39 synchronizedAdjustables = new ArrayList<Adjustable>();
40 enabledMap = new HashMap<Adjustable, Boolean>();
41 observable = new Observable();
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 adjustable participates in adjustment synchronization or not
75 *
76 * @param adjustable the adjustable
77 */
78 protected void setParticipatingInSynchronizedScrolling(Adjustable adjustable, boolean isParticipating) {
79 CheckParameterUtil.ensureParameterNotNull(adjustable, "adjustable");
80 if (! synchronizedAdjustables.contains(adjustable))
81 throw new IllegalStateException(tr("Adjustable {0} not registered yet. Cannot set participation in synchronized adjustment.", adjustable));
82
83 enabledMap.put(adjustable, isParticipating);
84 observable.notifyObservers();
85 }
86
87 /**
88 * Returns true if an adjustable is participating in synchronized scrolling
89 *
90 * @param adjustable the adjustable
91 * @return true, if the adjustable is participating in synchronized scrolling, false otherwise
92 * @throws IllegalStateException thrown, if adjustable is not registered for synchronized scrolling
93 */
94 protected boolean isParticipatingInSynchronizedScrolling(Adjustable adjustable) throws IllegalStateException {
95 if (! synchronizedAdjustables.contains(adjustable))
96 throw new IllegalStateException(tr("Adjustable {0} not registered yet.", adjustable));
97
98 return enabledMap.get(adjustable);
99 }
100
101 /**
102 * Wires a {@link JCheckBox} to the adjustment synchronizer, in such a way that:
103 * <li>
104 * <ol>state changes in the checkbox control whether the adjustable participates
105 * in synchronized adjustment</ol>
106 * <ol>state changes in this {@link AdjustmentSynchronizer} are reflected in the
107 * {@link JCheckBox}</ol>
108 * </li>
109 *
110 * @param view the checkbox to control whether an adjustable participates in synchronized adjustment
111 * @param adjustable the adjustable
112 * @exception IllegalArgumentException thrown, if view is null
113 * @exception IllegalArgumentException thrown, if adjustable is null
114 */
115 public void adapt(final JCheckBox view, final Adjustable adjustable) {
116 CheckParameterUtil.ensureParameterNotNull(adjustable, "adjustable");
117 CheckParameterUtil.ensureParameterNotNull(view, "view");
118
119 if (! synchronizedAdjustables.contains(adjustable)) {
120 participateInSynchronizedScrolling(adjustable);
121 }
122
123 // register an item lister with the check box
124 //
125 view.addItemListener(new ItemListener() {
126 @Override
127 public void itemStateChanged(ItemEvent e) {
128 switch(e.getStateChange()) {
129 case ItemEvent.SELECTED:
130 if (!isParticipatingInSynchronizedScrolling(adjustable)) {
131 setParticipatingInSynchronizedScrolling(adjustable, true);
132 }
133 break;
134 case ItemEvent.DESELECTED:
135 if (isParticipatingInSynchronizedScrolling(adjustable)) {
136 setParticipatingInSynchronizedScrolling(adjustable, false);
137 }
138 break;
139 }
140 }
141 });
142
143 observable.addObserver(
144 new Observer() {
145 @Override
146 public void update(Observable o, Object arg) {
147 boolean sync = isParticipatingInSynchronizedScrolling(adjustable);
148 if (view.isSelected() != sync) {
149 view.setSelected(sync);
150 }
151 }
152 }
153 );
154 setParticipatingInSynchronizedScrolling(adjustable, true);
155 view.setSelected(true);
156 }
157}
Note: See TracBrowser for help on using the repository browser.