Here is a minimal example.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class DeadKeyTextFieldExample extends Application {
@Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
StackPane root = new StackPane();
root.getChildren().add(textField);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Dead Key TextField Example");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
On Windows, the normal way to type a ñ is AltGr + ~ and n (at least on a Swedish keyboard). But when I do this in the text field the result is ~¨n. What can I do to get the expected behaviour?
EDIT: I am using JavaFX 20, Windows 10. I might add that other dead key characters work as expected: ¨ + e gives ë, ^ + e gives ê, but ~ + e gives ~ë.
This is a limited answer for a Mac with testing using JavaFX 20, it may not be exactly what you are looking for.
As noted by user VGR in comments, behavior will vary based based on your setup and actions. For example, any of these can effect what happens:
I tried this on MacOS 13.4.1. I used a MacBook Pro 2019 internal US keyboard with no special configurations in the OS for alternate input languages.
What I found, is:
Option + n
~ character.n
~ character will change to a ñ character.The native OS X TextEdit application works the same.
For an external windows keyboard attached to the same machine, the Alt key is used rather than the non-existent Option key.
To find out how to do this I followed the "less common method" for Apple laptops. The "most common method" documented there only worked in the native app, not the JavaFX app. The "most common method" involves "Press and hold the letter “n” key and a small popup will appear", which doesn't happen with JavaFX, instead it starts firing the keyboard repeat and writes lots on n characters.
It could be that you are using an unexpected key combination for your platform (from the JavaFX perspective), which JavaFX isn't recognizing. On another platform, with the correct platform-specific key combination used and recognized by JavaFX, the text input controls are able to correctly process the input and map it to the desired characters (as demoed for certain input sequences outlined in this answer).
Other related info
Key combinations are relayed in KEY_TYPED events
There is a (seemingly) related, but not the same, issue which was closed as not an issue: JDK-8172104 Dead keys are not detected, where it indicates that the actual outcome of the key combination comes in a KEY_TYPED event (not a KEY_PRESSED event).
The related issue is just about correctly filtering keys. If the core platform is able to correctly recognized KEY_TYPED strings, then I am not sure why TextField would not use that by default in your case. I did check the JavaFX source code internally and it seems to me that text input controls function based on KEY_TYPED strings.
There are dead keycodes
This means that the JavaFX system and key events can be made aware of dead keys.
If you can't get the default functionality to work as you want, perhaps you could intercept them in a filter, consume the relevant events, store the historic captured key input sequences somewhere, then, if you detect a sequence which should generate something you want, map that sequence to something which does actually generate the required output (such as generating synthetic keypress events based on numerics, which SedJ601 noted in comments seems to work). This seems tricky though, probably should be a better way, so I would only consider such an approach as a last resort. Alternately, you could raise additional feature requests for the JavaFX development team.
Test App
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
public class EnyaApp extends Application {
@Override
public void start(Stage stage) {
Scene scene = new Scene(new TextField());
stage.setScene(scene);
stage.show();
}
}
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