|
15 | 15 | */
|
16 | 16 | package rx.swing.sources;
|
17 | 17 |
|
| 18 | +import static org.mockito.Mockito.*; |
| 19 | + |
18 | 20 | import java.awt.Component;
|
| 21 | +import java.awt.Point; |
19 | 22 | import java.awt.event.MouseEvent;
|
20 | 23 | import java.awt.event.MouseListener;
|
21 | 24 | import java.awt.event.MouseMotionListener;
|
22 | 25 |
|
| 26 | +import javax.swing.JPanel; |
| 27 | + |
| 28 | +import org.junit.Test; |
| 29 | +import org.mockito.InOrder; |
| 30 | +import org.mockito.Matchers; |
| 31 | + |
23 | 32 | import rx.Observable;
|
24 | 33 | import rx.Observer;
|
25 | 34 | import rx.Subscription;
|
26 | 35 | import rx.subscriptions.Subscriptions;
|
27 | 36 | import rx.util.functions.Action0;
|
| 37 | +import rx.util.functions.Action1; |
28 | 38 | import rx.util.functions.Func1;
|
| 39 | +import rx.util.functions.Func2; |
29 | 40 |
|
30 | 41 | public enum MouseEventSource { ; // no instances
|
31 | 42 |
|
@@ -103,4 +114,86 @@ public void call() {
|
103 | 114 | }
|
104 | 115 | });
|
105 | 116 | }
|
| 117 | + |
| 118 | + /** |
| 119 | + * @see rx.observables.SwingObservable#fromRelativeMouseMotion |
| 120 | + */ |
| 121 | + public static Observable<Point> fromRelativeMouseMotion(final Component component) { |
| 122 | + class OldAndRelative { |
| 123 | + public final Point old; |
| 124 | + public final Point relative; |
| 125 | + |
| 126 | + private OldAndRelative(Point old, Point relative) { |
| 127 | + this.old = old; |
| 128 | + this.relative = relative; |
| 129 | + } |
| 130 | + } |
| 131 | + |
| 132 | + class Relativize implements Func2<OldAndRelative, MouseEvent, OldAndRelative> { |
| 133 | + @Override |
| 134 | + public OldAndRelative call(OldAndRelative last, MouseEvent event) { |
| 135 | + Point current = new Point(event.getX(), event.getY()); |
| 136 | + Point relative = new Point(current.x - last.old.x, current.y - last.old.y); |
| 137 | + return new OldAndRelative(current, relative); |
| 138 | + } |
| 139 | + } |
| 140 | + |
| 141 | + class OnlyRelative implements Func1<OldAndRelative, Point> { |
| 142 | + @Override |
| 143 | + public Point call(OldAndRelative oar) { |
| 144 | + return oar.relative; |
| 145 | + } |
| 146 | + } |
| 147 | + |
| 148 | + return fromMouseMotionEventsOf(component) |
| 149 | + .scan(new OldAndRelative(new Point(0, 0), new Point(0, 0)), new Relativize()) |
| 150 | + .map(new OnlyRelative()) |
| 151 | + .skip(2); // skip the useless initial value and the invalid first computation |
| 152 | + } |
| 153 | + |
| 154 | + public static class UnitTest { |
| 155 | + private Component comp = new JPanel(); |
| 156 | + |
| 157 | + @Test |
| 158 | + public void testRelativeMouseMotion() { |
| 159 | + @SuppressWarnings("unchecked") |
| 160 | + Action1<Point> action = mock(Action1.class); |
| 161 | + @SuppressWarnings("unchecked") |
| 162 | + Action1<Exception> error = mock(Action1.class); |
| 163 | + Action0 complete = mock(Action0.class); |
| 164 | + |
| 165 | + Subscription sub = fromRelativeMouseMotion(comp).subscribe(action, error, complete); |
| 166 | + |
| 167 | + InOrder inOrder = inOrder(action); |
| 168 | + |
| 169 | + verify(action, never()).call(Matchers.<Point>any()); |
| 170 | + verify(error, never()).call(Matchers.<Exception>any()); |
| 171 | + verify(complete, never()).call(); |
| 172 | + |
| 173 | + fireMouseEvent(mouseEvent(0, 0)); |
| 174 | + verify(action, never()).call(Matchers.<Point>any()); |
| 175 | + |
| 176 | + fireMouseEvent(mouseEvent(10, -5)); |
| 177 | + inOrder.verify(action, times(1)).call(new Point(10, -5)); |
| 178 | + |
| 179 | + fireMouseEvent(mouseEvent(6, 10)); |
| 180 | + inOrder.verify(action, times(1)).call(new Point(-4, 15)); |
| 181 | + |
| 182 | + sub.unsubscribe(); |
| 183 | + fireMouseEvent(mouseEvent(0, 0)); |
| 184 | + inOrder.verify(action, never()).call(Matchers.<Point>any()); |
| 185 | + verify(error, never()).call(Matchers.<Exception>any()); |
| 186 | + verify(complete, never()).call(); |
| 187 | + } |
| 188 | + |
| 189 | + private MouseEvent mouseEvent(int x, int y) { |
| 190 | + return new MouseEvent(comp, MouseEvent.MOUSE_MOVED, 1L, 0, x, y, 0, false); |
| 191 | + } |
| 192 | + |
| 193 | + private void fireMouseEvent(MouseEvent event) { |
| 194 | + for (MouseMotionListener listener: comp.getMouseMotionListeners()) { |
| 195 | + listener.mouseMoved(event); |
| 196 | + } |
| 197 | + } |
| 198 | + } |
106 | 199 | }
|
0 commit comments