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

Last change on this file since 8066 was 7005, checked in by Don-vip, 10 years ago

see #8465 - use diamond operator where applicable

  • Property svn:eol-style set to native
File size: 5.8 KB
RevLine 
[2512]1// License: GPL. For details, see LICENSE file.
[6147]2package org.openstreetmap.josm.gui.util;
[2512]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;
[6316]13import java.util.List;
14import java.util.Map;
[2512]15import java.util.Observable;
16import java.util.Observer;
17
18import javax.swing.JCheckBox;
19
[2850]20import org.openstreetmap.josm.tools.CheckParameterUtil;
21
[2512]22/**
[6830]23 * Synchronizes scrollbar adjustments between a set of {@link Adjustable}s.
24 * Whenever the adjustment of one of the registered Adjustables is updated
[6147]25 * the adjustment of the other registered Adjustables is adjusted too.
26 * @since 6147
[2512]27 */
28public class AdjustmentSynchronizer implements AdjustmentListener {
29
[6316]30 private final List<Adjustable> synchronizedAdjustables;
31 private final Map<Adjustable, Boolean> enabledMap;
[2512]32
33 private final Observable observable;
34
[6147]35 /**
36 * Constructs a new {@code AdjustmentSynchronizer}
37 */
[2512]38 public AdjustmentSynchronizer() {
[7005]39 synchronizedAdjustables = new ArrayList<>();
40 enabledMap = new HashMap<>();
[2512]41 observable = new Observable();
42 }
43
44 /**
[6147]45 * Registers an {@link Adjustable} for participation in synchronized scrolling.
[2512]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 /**
[6147]60 * Event handler for {@link AdjustmentEvent}s
[2512]61 */
[6084]62 @Override
[2512]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 /**
[6147]74 * Sets whether adjustable participates in adjustment synchronization or not
[2512]75 *
76 * @param adjustable the adjustable
77 */
78 protected void setParticipatingInSynchronizedScrolling(Adjustable adjustable, boolean isParticipating) {
[2850]79 CheckParameterUtil.ensureParameterNotNull(adjustable, "adjustable");
[2512]80 if (! synchronizedAdjustables.contains(adjustable))
[2850]81 throw new IllegalStateException(tr("Adjustable {0} not registered yet. Cannot set participation in synchronized adjustment.", adjustable));
[2512]82
83 enabledMap.put(adjustable, isParticipating);
84 observable.notifyObservers();
85 }
86
87 /**
[6147]88 * Returns true if an adjustable is participating in synchronized scrolling
[2512]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 /**
[6147]102 * Wires a {@link JCheckBox} to the adjustment synchronizer, in such a way that:
[6830]103 * <ol>
104 * <li>state changes in the checkbox control whether the adjustable participates
105 * in synchronized adjustment</li>
106 * <li>state changes in this {@link AdjustmentSynchronizer} are reflected in the
107 * {@link JCheckBox}</li>
108 * </ol>
[2512]109 *
[6147]110 * @param view the checkbox to control whether an adjustable participates in synchronized adjustment
[2512]111 * @param adjustable the adjustable
112 * @exception IllegalArgumentException thrown, if view is null
113 * @exception IllegalArgumentException thrown, if adjustable is null
114 */
[6147]115 public void adapt(final JCheckBox view, final Adjustable adjustable) {
[2850]116 CheckParameterUtil.ensureParameterNotNull(adjustable, "adjustable");
117 CheckParameterUtil.ensureParameterNotNull(view, "view");
[2512]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() {
[6084]126 @Override
[2512]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() {
[6084]145 @Override
[2512]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.