Let's say a have a TextField
TextField tf = new TextField();
and I want to simulate the user pressing a key.
KeyEvent ke = new KeyEvent(KeyEvent.KEY_RELEASED,
KeyCode.A.toString(), KeyCode.A.toString(),
KeyCode.A, false, false, false, false);
tf.fireEvent(ke);
if I examine the text contents of tf, I will see this state hold true
tf.getText() == ""
What happened to my KeyEvent and why didn't the text equal "a"? I have tried this with KEY_RELEASED, KEY_PRESSED, and KEY_TYPED
Contained Example:
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import java.util.concurrent.CountDownLatch;
import javax.swing.SwingUtilities;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public class TextFieldExample {
@Rule public JavaFXThreadingRule javafxRule = new JavaFXThreadingRule();
@Test
public void onlyAcceptValidInputs() {
TextField tf = new TextField();
KeyEvent ke = new KeyEvent(KeyEvent.KEY_RELEASED,
KeyCode.A.toString(), KeyCode.A.toString(),
KeyCode.A, false, false, false, false);
tf.fireEvent(ke);
Assert.assertEquals("A", tf.getText());
}
}
class JavaFXThreadingRule implements TestRule {
/**
* Flag for setting up the JavaFX, we only need to do this once for all tests.
*/
private static boolean jfxIsSetup;
@Override
public Statement apply(Statement statement, Description description) {
return new OnJFXThreadStatement(statement);
}
private static class OnJFXThreadStatement extends Statement {
private final Statement statement;
private OnJFXThreadStatement(Statement aStatement) {
statement = aStatement;
}
private Throwable rethrownException = null;
@Override
public void evaluate() throws Throwable {
if(!jfxIsSetup) {
setupJavaFX();
jfxIsSetup = true;
}
final CountDownLatch countDownLatch = new CountDownLatch(1);
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
statement.evaluate();
} catch (Throwable e) {
rethrownException = e;
}
countDownLatch.countDown();
}});
countDownLatch.await();
// if an exception was thrown by the statement during evaluation,
// then re-throw it to fail the test
if(rethrownException != null) {
throw rethrownException;
}
}
protected void setupJavaFX() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// initializes JavaFX environment
new JFXPanel();
latch.countDown();
}
});
latch.await();
}
}
}
It seems the text field is listening for KEY_TYPED events. Note that for KEY_TYPED events, the text should be the empty string, and the code should be KeyCode.UNDEFINED.
Note also that in your test case, the text field is never added to a live scene. Because of this, it doesn't install its skin, which contains the logic for actually processing events. So you need to force the installation of the skin by calling setSkin(...), passing in the result of the protected method createDefaultSkin():
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TextFieldFireEvent extends Application {
@Override
public void start(Stage primaryStage) {
TextField tf = new TextField() {
{
setSkin(createDefaultSkin());
}
};
Button button = new Button("A");
button.setOnAction(e -> {
KeyEvent ke = new KeyEvent(KeyEvent.KEY_TYPED,
"a", "",
KeyCode.UNDEFINED, false, false, false, false);
tf.fireEvent(ke);
System.out.println(tf.getText());
});
VBox root =new VBox(10, /*tf,*/ button);
root.setAlignment(Pos.CENTER);
primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With