1 | // License: GPL. For details, see LICENSE file.
|
---|
2 | package org.openstreetmap.josm.gui.util;
|
---|
3 |
|
---|
4 | import java.awt.Component;
|
---|
5 | import java.awt.Cursor;
|
---|
6 | import java.util.Iterator;
|
---|
7 | import java.util.LinkedHashMap;
|
---|
8 | import java.util.concurrent.CopyOnWriteArrayList;
|
---|
9 |
|
---|
10 | /**
|
---|
11 | * This class manages multiple cursors for multiple components.
|
---|
12 | * All components share the same cursor that was last set using {@link #setNewCursor(Cursor, Object)}
|
---|
13 | *
|
---|
14 | * @author Michael Zangl
|
---|
15 | */
|
---|
16 | public class CursorManager {
|
---|
17 |
|
---|
18 | private final LinkedHashMap<Object, Cursor> cursors = new LinkedHashMap<>();
|
---|
19 | private final CopyOnWriteArrayList<Component> components = new CopyOnWriteArrayList<>();
|
---|
20 |
|
---|
21 | /**
|
---|
22 | * Creates a new NavigationCursorManager
|
---|
23 | * @param forComponent The initial component the cursor should be managed for.
|
---|
24 | */
|
---|
25 | public CursorManager(Component forComponent) {
|
---|
26 | addComponent(forComponent);
|
---|
27 | }
|
---|
28 |
|
---|
29 | /**
|
---|
30 | * Adds a component that this manager should send cursor changes to.
|
---|
31 | * @param forComponent The component.
|
---|
32 | */
|
---|
33 | public synchronized void addComponent(Component forComponent) {
|
---|
34 | components.addIfAbsent(forComponent);
|
---|
35 | forComponent.setCursor(getCurrentCursor());
|
---|
36 | }
|
---|
37 |
|
---|
38 | /**
|
---|
39 | * Removes a component that this manager should send cursor changes to. The current cursor is not reset.
|
---|
40 | * @param forComponent The component.
|
---|
41 | */
|
---|
42 | public synchronized void removeComponent(Component forComponent) {
|
---|
43 | components.remove(forComponent);
|
---|
44 | }
|
---|
45 |
|
---|
46 | /**
|
---|
47 | * Set new cursor.
|
---|
48 | * @param cursor The new cursor to use.
|
---|
49 | * @param reference A reference object that can be passed to the next set/reset calls to identify the caller.
|
---|
50 | */
|
---|
51 | public synchronized void setNewCursor(Cursor cursor, Object reference) {
|
---|
52 | if (reference == null) {
|
---|
53 | throw new NullPointerException("Cannot register a cursor that can never be removed.");
|
---|
54 | }
|
---|
55 | // re-insert to allow overriding.
|
---|
56 | cursors.remove(reference);
|
---|
57 | cursors.put(reference, cursor);
|
---|
58 | updateCursor();
|
---|
59 | }
|
---|
60 |
|
---|
61 | /**
|
---|
62 | * Remove the new cursor that was set with the given reference object. and reset to previous
|
---|
63 | * @param reference A reference object that can be passed to the next set/reset calls to identify the caller.
|
---|
64 | */
|
---|
65 | public synchronized void resetCursor(Object reference) {
|
---|
66 | if (reference == null) {
|
---|
67 | return;
|
---|
68 | }
|
---|
69 | cursors.remove(reference);
|
---|
70 | updateCursor();
|
---|
71 | }
|
---|
72 |
|
---|
73 | private void updateCursor() {
|
---|
74 | Cursor cursor = getCurrentCursor();
|
---|
75 | for (Component c : components) {
|
---|
76 | c.setCursor(cursor);
|
---|
77 | }
|
---|
78 | }
|
---|
79 |
|
---|
80 | private Cursor getCurrentCursor() {
|
---|
81 | Iterator<Cursor> it = cursors.values().iterator();
|
---|
82 | Cursor cursor = null;
|
---|
83 | while (it.hasNext()) {
|
---|
84 | cursor = it.next();
|
---|
85 | }
|
---|
86 | return cursor;
|
---|
87 | }
|
---|
88 |
|
---|
89 | }
|
---|