[8556] | 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 | }
|
---|