org.fxmisc.wellbehaved.event.InputMap Maven / Gradle / Ivy
package org.fxmisc.wellbehaved.event;
import java.util.Arrays;
import java.util.Objects;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import javafx.event.Event;
import javafx.event.EventType;
import org.fxmisc.wellbehaved.event.InputHandler.Result;
/**
*
* @param type of events that this {@linkplain InputMap} may handle.
* That is, {@code InputMap} certainly does not handle any events that
* are not of type {@code E}; it does not mean it handles any
* event of type {@code E}.
*/
@FunctionalInterface
public interface InputMap {
static final InputMap> EMPTY = handlerConsumer -> {};
static InputMap empty() { return (InputMap) EMPTY; }
@FunctionalInterface
static interface HandlerConsumer {
void accept(EventType extends F> t, InputHandler super F> h);
}
void forEachEventType(HandlerConsumer super E> f);
default InputMap orElse(InputMap extends E> that) {
return sequence(this, that);
}
default InputMap without(InputMap> that) {
return this.equals(that) ? empty() : this;
}
/**
* Executes some additional handler if the event was consumed
*/
default InputMap ifConsumed(Consumer super E> postConsumption) {
return handlerConsumer -> InputMap.this.forEachEventType(new HandlerConsumer() {
@Override
public void accept(EventType extends T> t, InputHandler super T> h) {
InputHandler h2 = e -> {
Result res = h.process(e);
if(res == Result.CONSUME) {
postConsumption.accept(e);
}
return res;
};
handlerConsumer.accept(t, h2);
}
});
}
static InputMap upCast(InputMap extends E> inputMap) {
// Unsafe cast is justified by this type-safe equivalent expression:
// InputMap res = f -> inputMap.forEachEventType(f);
@SuppressWarnings("unchecked")
InputMap res = (InputMap) inputMap;
return res;
}
@SafeVarargs
static InputMap sequence(InputMap extends E>... inputMaps) {
return new InputMapChain<>(inputMaps);
}
public static InputMap process(
EventPattern super T, ? extends U> eventPattern,
Function super U, InputHandler.Result> action) {
return new PatternActionMap<>(eventPattern, action);
}
public static InputMap process(
EventType extends T> eventType,
Function super T, InputHandler.Result> action) {
return process(EventPattern.eventType(eventType), action);
}
public static InputMap consume(
EventPattern super T, ? extends U> eventPattern,
Consumer super U> action) {
return process(eventPattern, u -> {
action.accept(u);
return Result.CONSUME;
});
}
public static InputMap consume(
EventType extends T> eventType,
Consumer super T> action) {
return consume(EventPattern.eventType(eventType), action);
}
public static InputMap consume(
EventPattern super T, ? extends U> eventPattern) {
return process(eventPattern, u -> Result.CONSUME);
}
public static InputMap consume(
EventType extends T> eventType) {
return consume(EventPattern.eventType(eventType));
}
public static InputMap consumeWhen(
EventPattern super T, ? extends U> eventPattern,
BooleanSupplier condition,
Consumer super U> action) {
return process(eventPattern, u -> {
if(condition.getAsBoolean()) {
action.accept(u);
return Result.CONSUME;
} else {
return Result.PROCEED;
}
});
}
public static InputMap consumeWhen(
EventType extends T> eventType,
BooleanSupplier condition,
Consumer super T> action) {
return consumeWhen(EventPattern.eventType(eventType), condition, action);
}
public static InputMap consumeUnless(
EventPattern super T, ? extends U> eventPattern,
BooleanSupplier condition,
Consumer super U> action) {
return consumeWhen(eventPattern, () -> !condition.getAsBoolean(), action);
}
public static InputMap consumeUnless(
EventType extends T> eventType,
BooleanSupplier condition,
Consumer super T> action) {
return consumeUnless(EventPattern.eventType(eventType), condition, action);
}
public static InputMap ignore(
EventPattern super T, ? extends U> eventPattern) {
return new PatternActionMap<>(eventPattern, PatternActionMap.CONST_IGNORE);
}
public static InputMap ignore(
EventType extends T> eventType) {
return ignore(EventPattern.eventType(eventType));
}
public static InputMap when(
BooleanSupplier condition, InputMap im) {
return new InputMap() {
@Override
public void forEachEventType(HandlerConsumer super T> f) {
HandlerConsumer g = new HandlerConsumer() {
@Override
public void accept(
EventType extends F> t, InputHandler super F> h) {
f.accept(t, evt -> condition.getAsBoolean() ? h.process(evt) : Result.PROCEED);
}
};
im.forEachEventType(g);
}
};
}
public static InputMap unless(
BooleanSupplier condition, InputMap im) {
return when(() -> !condition.getAsBoolean(), im);
}
}
class PatternActionMap implements InputMap {
static final Function
© 2015 - 2025 Weber Informatics LLC | Privacy Policy