Skip to content

Instantly share code, notes, and snippets.

@stnwtr
Last active March 1, 2019 18:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stnwtr/54a4e9c67835dc7c5a6c1b677ed14712 to your computer and use it in GitHub Desktop.
Save stnwtr/54a4e9c67835dc7c5a6c1b677ed14712 to your computer and use it in GitHub Desktop.
HiddenKeyListener for JavaFX
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
class HiddenKeyListener<T extends Event> implements EventHandler<T> {
public interface Callback {
void action();
}
private final String pattern = "[A-Za-z_0-9]+";
private final char[] code;
private final Callback callback;
private boolean repeatable;
private boolean enter;
private int timeout;
private Set<KeyCode> skippedKeys;
private int position;
private long millis;
public HiddenKeyListener(String code, Callback callback, boolean repeatable, boolean enter, int timeout, Set<KeyCode> skippedKeys) {
Optional.ofNullable(code)
.filter(s -> s.matches(pattern))
.orElseThrow(() -> new IllegalArgumentException("Code must match " + pattern));
Optional.ofNullable(callback)
.orElseThrow(() -> new IllegalArgumentException("Callback cannot be null"));
this.code = code.toCharArray();
this.callback = callback;
this.repeatable = repeatable;
this.enter = enter;
this.timeout = timeout <= 0 ? 30000 : timeout * 1000;
this.skippedKeys = skippedKeys == null ? Collections.emptySet() : skippedKeys;
this.position = 0;
this.millis = 0;
}
public HiddenKeyListener(String code, Callback callback) {
this(code, callback, true, false, 30, Collections.emptySet());
}
@Override
public void handle(T t) {
if (t instanceof KeyEvent) {
KeyEvent keyEvent = (KeyEvent) t;
if (skippedKeys.contains(keyEvent.getCode()))
return;
if (code.length == 1) {
if (keyEvent.getText().charAt(0) == code[0]) {
callback.action();
return;
}
}
if (millis + timeout <= System.currentTimeMillis())
position = 0;
if (keyEvent.getText().matches(pattern))
check(keyEvent.getText().charAt(0));
else if (keyEvent.getCode().equals(KeyCode.ENTER))
check('\n');
else if (!keyEvent.isShiftDown())
position = 0;
}
}
private void check(char input) {
if (position == 0) {
if (input == code[0]) {
position = 1;
millis = System.currentTimeMillis();
}
} else if (position > 0 && position < code.length) {
if (input == code[position++]) {
if (position == code.length && !enter) {
action();
}
} else {
position = 0;
check(input);
}
} else if (position == code.length) {
if (input == '\n') {
action();
} else {
position = 0;
check(input);
}
}
}
private void action() {
if (repeatable)
position = 0;
else
position++;
callback.action();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment