Skip to content

Commit cbcb6fe

Browse files
author
jmhofer
committed
Added key events as source for Swing observables.
1 parent 0d83626 commit cbcb6fe

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

rxjava-contrib/rxjava-swing/src/main/java/rx/SwingObservable.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616
package rx;
1717

1818
import java.awt.event.ActionEvent;
19+
import java.awt.event.KeyEvent;
1920

2021
import javax.swing.AbstractButton;
22+
import javax.swing.JComponent;
2123

2224
import rx.swing.sources.AbstractButtonSource;
25+
import rx.swing.sources.KeyEventSource;
2326

2427
/**
2528
* Allows creating observables from various sources specific to Swing.
@@ -36,4 +39,15 @@ public enum SwingObservable { ; // no instances
3639
public static Observable<ActionEvent> fromButtonAction(AbstractButton button) {
3740
return AbstractButtonSource.fromActionOf(button);
3841
}
42+
43+
/**
44+
* Creates an observable corresponding to raw key events.
45+
*
46+
* @param component
47+
* The component to register the observable for.
48+
* @return Observable of key events.
49+
*/
50+
public static Observable<KeyEvent> fromKeyEvents(JComponent component) {
51+
return KeyEventSource.fromKeyEventsOf(component);
52+
}
3953
}

rxjava-contrib/rxjava-swing/src/main/java/rx/swing/sources/AbstractButtonSource.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public void testObservingActionEvents() {
5656

5757
final ActionEvent event = new ActionEvent(this, 1, "command");
5858

59+
@SuppressWarnings("serial")
5960
class TestButton extends AbstractButton {
6061
void testAction() {
6162
fireActionPerformed(event);
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package rx.swing.sources;
2+
3+
import static org.mockito.Mockito.*;
4+
5+
import java.awt.event.ActionEvent;
6+
import java.awt.event.KeyEvent;
7+
import java.awt.event.KeyListener;
8+
9+
import javax.swing.JComponent;
10+
import javax.swing.JPanel;
11+
12+
import org.junit.Test;
13+
import org.mockito.Matchers;
14+
15+
import rx.Observable;
16+
import rx.Observer;
17+
import rx.Subscription;
18+
import rx.subscriptions.Subscriptions;
19+
import rx.util.functions.Action0;
20+
import rx.util.functions.Action1;
21+
import rx.util.functions.Func1;
22+
23+
public enum KeyEventSource { ; // no instances
24+
25+
public static Observable<KeyEvent> fromKeyEventsOf(final JComponent component) {
26+
return Observable.create(new Func1<Observer<KeyEvent>, Subscription>() {
27+
@Override
28+
public Subscription call(final Observer<KeyEvent> observer) {
29+
final KeyListener listener = new KeyListener() {
30+
@Override
31+
public void keyPressed(KeyEvent event) {
32+
observer.onNext(event);
33+
}
34+
35+
@Override
36+
public void keyReleased(KeyEvent event) {
37+
observer.onNext(event);
38+
}
39+
40+
@Override
41+
public void keyTyped(KeyEvent event) {
42+
observer.onNext(event);
43+
}
44+
};
45+
component.addKeyListener(listener);
46+
47+
return Subscriptions.create(new Action0() {
48+
@Override
49+
public void call() {
50+
component.removeKeyListener(listener);
51+
}
52+
});
53+
}
54+
});
55+
}
56+
57+
public static class UnitTest {
58+
@Test
59+
public void testObservingActionEvents() {
60+
@SuppressWarnings("unchecked")
61+
Action1<ActionEvent> action = mock(Action1.class);
62+
@SuppressWarnings("unchecked")
63+
Action1<Exception> error = mock(Action1.class);
64+
Action0 complete = mock(Action0.class);
65+
66+
final KeyEvent event = mock(KeyEvent.class);
67+
68+
JComponent comp = new JPanel();
69+
70+
Subscription sub = fromKeyEventsOf(comp).subscribe(action, error, complete);
71+
72+
verify(action, never()).call(Matchers.<ActionEvent>any());
73+
verify(error, never()).call(Matchers.<Exception>any());
74+
verify(complete, never()).call();
75+
76+
fireKeyEvent(comp, event);
77+
verify(action, times(1)).call(Matchers.<ActionEvent>any());
78+
79+
fireKeyEvent(comp, event);
80+
verify(action, times(2)).call(Matchers.<ActionEvent>any());
81+
82+
sub.unsubscribe();
83+
fireKeyEvent(comp, event);
84+
verify(action, times(2)).call(Matchers.<ActionEvent>any());
85+
verify(error, never()).call(Matchers.<Exception>any());
86+
verify(complete, never()).call();
87+
}
88+
89+
private static void fireKeyEvent(JComponent component, KeyEvent event) {
90+
for (KeyListener listener: component.getKeyListeners()) {
91+
listener.keyTyped(event);
92+
}
93+
}
94+
}
95+
}

0 commit comments

Comments
 (0)