我面临的问题是当我有输入(TextField,TextArea等)时,我试图插入一些包含重音符号的希腊语单词。像“ ????”(猫)这样的词可以正常工作。不幸的是,我无法键入 “ ?????”(塔希提岛)之类的词。如果我尝试复制并粘贴它或对其进行硬编码,则可以正常工作,但是当我尝试使用以下命令的组合来写单词时
Shift +';' +?
哪个应该产生“?”,而不是我得到“?”
这是一个例子:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Example extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
VBox mainBox = new VBox(10);
mainBox.setPadding(new Insets(20));
mainBox.setAlignment(Pos.CENTER);
// ????? = Tahiti
TextField field1 = new TextField("?????");
TextField field2 = new TextField();
mainBox.getChildren().add(field1);
mainBox.getChildren().add(field2);
field1.setStyle("-fx-font-size:24px");
field2.setStyle("-fx-font-size:24px");
stage.setScene(new Scene(mainBox));
stage.show();
}
}
Run Code Online (Sandbox Code Playgroud)
下图显示了我自己输入单词时的结果
已安装的JRE:jre1.8.0_221
安装的JDK:jdk1.8.0_221
为了排除IDE(Eclipse)导致问题的发生,我仅使用AnchorPane和TextField在SceneBuilder上测试了此行为,并且在那里也遇到了同样的问题。但是为了争辩,我在Eclipse中拥有编辑器和所有设置来使用编码UTF-8。
因此,我想问:这是当前JRE / JDK的错误吗?如果是,是否存在我可以使用的知名解决方案,或者我应该只使用侦听器来捕获输入并自行更正?
编辑:正如塞德里克指出的那样,我可以使用alt + 0 2 3 9的组合,但这将产生另一种与希腊字母相似但不相同的字母。看下面的图片。不幸的是,这不是我的客户想要的行为,因为正确的输入方式是(使用希腊语键盘):Shift +';' +?,在哪里?是英文字母“ i”。
编辑2:同样,我可以使用下面的代码来破解它,但是如果我决定这样做,则必须对我的所有TextField都这样做,这是我想避免的事情。否则,我应该创建一个“虚拟” CustomTextField类,该类将扩展TextField并在那里实现修改,然后可以用CustomTextField替换项目中的所有TextField引用。
field2.setTextFormatter(new TextFormatter<>(c -> {
String text = c.getControlNewText();
if (text.contains("¨?") || text.contains("¨?")) {
// In order to "catch" a word with multiple wrong characters
// for example if someone tries to copy/paste, I will use
// the replaceAll() method
text = text.replaceAll("¨?", "?");
text = text.replaceAll("¨?", "?");
// update the field
field2.setText(text);
// correct the caret and anchor positions
c.setCaretPosition(c.getCaretPosition() - 1);
c.setAnchor(c.getCaretPosition());
c.setText(""); // consume change because we already update it
}
return c;
}));
Run Code Online (Sandbox Code Playgroud)
我可以重现该行为。如果您在舞台上添加一个,EventHandler您可以清楚地看到问题。
stage.addEventFilter(KeyEvent.KEY_TYPED, ev -> {\n System.out.println("Key typed: " + ev.getCharacter());\n});\nRun Code Online (Sandbox Code Playgroud)\n\n输出:
\n\nKey typed: \xc2\xa8\nKey typed: \xce\x99\nKey typed: \xc2\xa8\nKey typed: \xce\xb9\nRun Code Online (Sandbox Code Playgroud)\n\n有一个已解决的票证描述了此问题。如果是Glass Windowing Toolkit问题,我们对此无能为力,只能提交错误报告。
\n\n我不知道您是否可以在KeyEvents发送这些键之前捕获键入的键,但您可以在阶段级别过滤它们。
stage.addEventFilter(KeyEvent.KEY_TYPED, new KeyTypedListener());\nRun Code Online (Sandbox Code Playgroud)\n\n这不是很好,而是一种更“全球”的改变行为的方式。
\n\npublic class KeyTypedListener implements EventHandler<KeyEvent> {\n\n private boolean disabled = false;\n private Map<String, String> charCombinations = new HashMap<>();\n private KeyEvent pendingEvent;\n\n public KeyTypedListener() {\n charCombinations.put("\xc2\xa8\xce\xb9", "\xcf\x8a");\n charCombinations.put("\xc2\xa8\xce\x99", "\xce\xaa");\n }\n\n @Override\n public void handle(final KeyEvent event) {\n\n if (disabled || event.getCharacter() == null\n || event.getCharacter().length() != 1) {\n return;\n }\n\n final String typed = event.getCharacter();\n\n if (pendingEvent == null && isCombiCharacter(typed)) {\n pendingEvent = event.copyFor(event.getSource(), event.getTarget());\n event.consume();\n\n } else if (pendingEvent != null) {\n String combination =\n charCombinations.get(pendingEvent.getCharacter() + typed);\n\n if (combination == null) {\n disabled = true;\n fireEvent(pendingEvent);\n disabled = false;\n pendingEvent = null;\n } else {\n event.consume();\n pendingEvent = null;\n\n Platform.runLater(() -> {\n fireEventWithCharacter(event, combination);\n });\n }\n }\n }\n\n private boolean isCombiCharacter(final String character) {\n return "\xc2\xa8".equals(character);\n }\n\n private void fireEvent(final KeyEvent event) {\n Event.fireEvent(event.getTarget(), event);\n }\n\n private void fireEventWithCharacter(final KeyEvent event,\n final String character) {\n fireEvent(new KeyEvent(event.getSource(), event.getTarget(),\n event.getEventType(), character, "", KeyCode.UNDEFINED,\n event.isShiftDown(), event.isControlDown(), event.isAltDown(),\n event.isMetaDown()));\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n当然你也可以创建一个新的EventDispatcher.
| 归档时间: |
|
| 查看次数: |
419 次 |
| 最近记录: |