Skip to content

Commit

Permalink
Merge pull request #5 from bdmstyle/0.x
Browse files Browse the repository at this point in the history
Add FocusEvent support and fix build
  • Loading branch information
benjchristensen committed Oct 7, 2014
2 parents b24e09c + 3aea027 commit 415478e
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 1 deletion.
13 changes: 13 additions & 0 deletions src/main/java/rx/observables/SwingObservable.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.FocusEvent;
import java.util.Set;

import javax.swing.AbstractButton;
Expand All @@ -33,6 +34,7 @@
import rx.swing.sources.ComponentEventSource;
import rx.swing.sources.KeyEventSource;
import rx.swing.sources.MouseEventSource;
import rx.swing.sources.FocusEventSource;

/**
* Allows creating observables from various sources specific to Swing.
Expand Down Expand Up @@ -131,6 +133,17 @@ public static Observable<ComponentEvent> fromComponentEvents(Component component
return ComponentEventSource.fromComponentEventsOf(component);
}

/**
* Creates an observable corresponding to focus events.
*
* @param component
* The component to register the observable for.
* @return Observable of focus events.
*/
public static Observable<FocusEvent> fromFocusEvents(Component component) {
return FocusEventSource.fromFocusEventsOf(component);
}

/**
* Creates an observable corresponding to component resize events.
*
Expand Down
81 changes: 81 additions & 0 deletions src/main/java/rx/swing/sources/FocusEventSource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* Copyright 2014 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package rx.swing.sources;

import rx.Observable;
import rx.Observable.OnSubscribe;
import rx.Subscriber;
import rx.functions.Action0;
import rx.functions.Func1;
import rx.observables.SwingObservable;
import rx.subscriptions.SwingSubscriptions;

import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

public enum FocusEventSource { ; // no instances

/**
* @see rx.observables.SwingObservable#fromFocusEvents
*/
public static Observable<FocusEvent> fromFocusEventsOf(final Component component) {
return Observable.create(new OnSubscribe<FocusEvent>() {
@Override
public void call(final Subscriber<? super FocusEvent> subscriber) {
SwingObservable.assertEventDispatchThread();
final FocusListener listener = new FocusListener() {

@Override
public void focusGained(FocusEvent event) {
subscriber.onNext(event);
}

@Override
public void focusLost(FocusEvent event) {
subscriber.onNext(event);
}
};
component.addFocusListener(listener);
subscriber.add(SwingSubscriptions.unsubscribeInEventDispatchThread(new Action0() {
@Override
public void call() {
component.removeFocusListener(listener);
}
}));
}
});
}

/**
* Predicates that help with filtering observables for specific focus events.
*/
public enum Predicate implements Func1<FocusEvent, Boolean> {
FOCUS_GAINED(FocusEvent.FOCUS_GAINED),
FOCUS_LOST(FocusEvent.FOCUS_LOST);

private final int id;

private Predicate(int id) {
this.id = id;
}

@Override
public Boolean call(FocusEvent event) {
return event.getID() == id;
}
}
}
76 changes: 76 additions & 0 deletions src/test/java/rx/swing/sources/FocusEventSourceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* Copyright 2014 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package rx.swing.sources;

import org.junit.Test;
import org.mockito.Matchers;
import rx.Subscription;
import rx.functions.Action0;
import rx.functions.Action1;

import javax.swing.*;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

import static org.mockito.Mockito.*;

public class FocusEventSourceTest {
private Component comp = new JPanel();

@Test
public void testObservingFocusEvents() throws Throwable {
SwingTestHelper.create().runInEventDispatchThread(new Action0() {

@Override
public void call() {
@SuppressWarnings("unchecked")
Action1<FocusEvent> action = mock(Action1.class);
@SuppressWarnings("unchecked")
Action1<Throwable> error = mock(Action1.class);
Action0 complete = mock(Action0.class);

final FocusEvent event = mock(FocusEvent.class);

Subscription sub = FocusEventSource.fromFocusEventsOf(comp)
.subscribe(action, error, complete);

verify(action, never()).call(Matchers.<FocusEvent> any());
verify(error, never()).call(Matchers.<Throwable> any());
verify(complete, never()).call();

fireFocusEvent(event);
verify(action, times(1)).call(Matchers.<FocusEvent> any());

fireFocusEvent(event);
verify(action, times(2)).call(Matchers.<FocusEvent> any());

sub.unsubscribe();
fireFocusEvent(event);
verify(action, times(2)).call(Matchers.<FocusEvent> any());
verify(error, never()).call(Matchers.<Throwable> any());
verify(complete, never()).call();
}

}).awaitTerminal();
}

private void fireFocusEvent(FocusEvent event) {
for (FocusListener listener : comp.getFocusListeners()) {
listener.focusGained(event);
}
}
}
2 changes: 1 addition & 1 deletion src/test/java/rx/swing/sources/KeyEventSourceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public void call() {
.subscribe(action, error, complete);

InOrder inOrder = inOrder(action);
inOrder.verify(action, times(1)).call(
inOrder.verify(action, never()).call(
Collections.<Integer> emptySet());
verify(error, never()).call(Matchers.<Throwable> any());
verify(complete, never()).call();
Expand Down

0 comments on commit 415478e

Please sign in to comment.