![](/img/trans.png)
[英]How to use scanner to read accented characters from file in correct way?
[英]How to correct Greek accented characters in a TextField
我面临的问题是当我有输入(TextField,TextArea等)并且我试图插入一些包含重音字符的希腊语单词时。 像“Γάτα”(cat)这样的单词很好。 不幸的是,我无法输入 “Ταϊτή”(塔希提岛)这样的词。 如果我尝试复制并粘贴它或硬编码它,它工作正常,但当我尝试使用组合
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();
}
}
下面的图片显示了我自己输入单词时的结果
安装JRE:jre1.8.0_221
安装JDK:jdk1.8.0_221
为了排除IDE(Eclipse)作为问题的原因,我在SceneBuilder上仅使用AnchorPane和TextField测试了这种行为,我也遇到了同样的问题。 但是为了争论,我让编辑器和Eclipse中的所有设置都使用UTF-8编码。
所以我想问一下:这是当前JRE / JDK的错误吗?如果有的话,是否有一个我可以使用的着名解决方案,或者我应该使用一个监听器来捕获输入并自行更正?
编辑:正如塞德里克指出的那样,我可以使用alt + 0 2 3 9的组合,但这会产生一种不同类型的字母,类似于希腊字母,但不一样。 看下面的图片。 不幸的是,这不是我的客户想要的行为,因为键入它的正确方法(在希腊语键盘中)是:Shift +';' +ι,其中'ι'是英文字母'i'。
编辑2:我也可以通过使用下面的代码破解我的方式,但如果我决定这样做,我必须为我的所有TextFields这样做,这是我想避免的。 否则我应该创建一个“虚拟”CustomTextField类,它将扩展TextField并在那里实现hack,然后我可以用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;
}));
我可以重现这种行为。 如果您向舞台添加EventHandler
,您可以清楚地看到问题。
stage.addEventFilter(KeyEvent.KEY_TYPED, ev -> {
System.out.println("Key typed: " + ev.getCharacter());
});
输出:
Key typed: ¨
Key typed: Ι
Key typed: ¨
Key typed: ι
有一个已解决的故障单描述了这个问题。 如果它是一个Glass Windowing Toolkit问题,我们无法做很多事情,但提交错误报告。
我不知道你是否可以在发送这些KeyEvents
之前捕获键入的键,但是你可以在阶段级别过滤它们。
stage.addEventFilter(KeyEvent.KEY_TYPED, new KeyTypedListener());
这不是一件好事,而是改变行为的更“全球化”方式。
public class KeyTypedListener implements EventHandler<KeyEvent> {
private boolean disabled = false;
private Map<String, String> charCombinations = new HashMap<>();
private KeyEvent pendingEvent;
public KeyTypedListener() {
charCombinations.put("¨ι", "ϊ");
charCombinations.put("¨Ι", "Ϊ");
}
@Override
public void handle(final KeyEvent event) {
if (disabled || event.getCharacter() == null
|| event.getCharacter().length() != 1) {
return;
}
final String typed = event.getCharacter();
if (pendingEvent == null && isCombiCharacter(typed)) {
pendingEvent = event.copyFor(event.getSource(), event.getTarget());
event.consume();
} else if (pendingEvent != null) {
String combination =
charCombinations.get(pendingEvent.getCharacter() + typed);
if (combination == null) {
disabled = true;
fireEvent(pendingEvent);
disabled = false;
pendingEvent = null;
} else {
event.consume();
pendingEvent = null;
Platform.runLater(() -> {
fireEventWithCharacter(event, combination);
});
}
}
}
private boolean isCombiCharacter(final String character) {
return "¨".equals(character);
}
private void fireEvent(final KeyEvent event) {
Event.fireEvent(event.getTarget(), event);
}
private void fireEventWithCharacter(final KeyEvent event,
final String character) {
fireEvent(new KeyEvent(event.getSource(), event.getTarget(),
event.getEventType(), character, "", KeyCode.UNDEFINED,
event.isShiftDown(), event.isControlDown(), event.isAltDown(),
event.isMetaDown()));
}
}
当然,您也可以创建一个新的EventDispatcher
。
我认为这是希腊键盘的一个问题。 我尝试使用其他文本字段(Opera搜索栏,Google搜索栏等),我无法编写此字符。 你只能用Alt + 0239组合来写这个。 您可以尝试使用“field2.setOnKeyPressed()”创建组合。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.