Javafx NodeOrientation не работает должным образомJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Javafx NodeOrientation не работает должным образом

Сообщение Anonymous »

Я разрабатываю приложение для арабских пользователей, поэтому установил:
root.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);

Это отлично работает, когда текстовые поля содержат текст, написанный справа налево, например на арабском языке. Однако при этом нарушается логика курсора (перемещение курсора с помощью стрелок влево/вправо на клавиатуре), когда поле содержит цифры или латинский текст.
Вот демонстрация:
import javafx.application.Application;
import javafx.geometry.NodeOrientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class NodeOrientationDemo extends Application {
@Override
public void start(Stage primaryStage) {
TextField numbersTextField = new TextField("0123456789");
numbersTextField.setMaxSize(80, 30);

TextField latinTextField = new TextField("Hello");
latinTextField.setMaxSize(80, 30);

TextField arabicTextField = new TextField("مرحبا");
arabicTextField.setMaxSize(80, 30);

VBox root = new VBox(10, numbersTextField, latinTextField, arabicTextField);
root.setAlignment(Pos.CENTER);
root.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);

primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.setTitle("NodeOrientation");
primaryStage.show();
}
}

Это известная ошибка? И как я могу это решить?
Любая помощь приветствуется, заранее спасибо!
Обновление 1:
Я добавил фильтры событий во все текстовые поля, и они работают нормально. Однако инвертируется только навигация по арабскому тексту (слева должна быть справа, правая должна быть слева). Мой план состоит в том, чтобы определить, является ли это арабским текстом, и на основе этого я добавлю/удалю позицию курсора.
import javafx.application.Application;
import javafx.geometry.NodeOrientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
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 NodeOrientationDemo extends Application {
@Override
public void start(Stage primaryStage) {
TextField numbersTextField = new TextField("0123456789");
numbersTextField.setMaxSize(80, 30);
keyboardNavigation(numbersTextField);

TextField latinTextField = new TextField("Hello");
latinTextField.setMaxSize(80, 30);
keyboardNavigation(latinTextField);

TextField arabicTextField = new TextField("مرحبا");
arabicTextField.setMaxSize(80, 30);
keyboardNavigation(arabicTextField);

VBox root = new VBox(10, numbersTextField, latinTextField, arabicTextField);
root.setAlignment(Pos.CENTER);
root.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);

primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.setTitle("NodeOrientation");
primaryStage.show();
}

private void keyboardNavigation(TextField textField) {
textField.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if (event.getCode() == KeyCode.LEFT) {
textField.positionCaret(textField.getCaretPosition() - 1);
event.consume();
} else if (event.getCode() == KeyCode.RIGHT) {
textField.positionCaret(textField.getCaretPosition() + 1);
event.consume();
}
});
}
}

Обновление 2:
Я реализовал план в обновлении 1, и он выглядит хорошо. Однако остается еще одна проблема: когда текстовое поле содержит как арабский текст, так и латинские буквы/цифры, поведение немного непонятно.

import javafx.application.Application;
import javafx.geometry.NodeOrientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
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 NodeOrientationDemo extends Application {
@Override
public void start(Stage primaryStage) {
TextField numbersTextField = new TextField("0123456789");
numbersTextField.setMaxSize(80, 30);
keyboardNavigation(numbersTextField);

TextField latinTextField = new TextField("Hello");
latinTextField.setMaxSize(80, 30);
keyboardNavigation(latinTextField);

TextField arabicTextField = new TextField("مرحبا");
arabicTextField.setMaxSize(80, 30);
keyboardNavigation(arabicTextField);

VBox root = new VBox(10, numbersTextField, latinTextField, arabicTextField);
root.setAlignment(Pos.CENTER);
root.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);

primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.setTitle("NodeOrientation");
primaryStage.show();
}

private void keyboardNavigation(TextField textField) {
textField.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
final int pos = clamp(1, textField.getCaretPosition(), textField.getLength());
final boolean isArabic = isArabicCharacter(textField.getText().charAt(pos - 1));
if (event.getCode() == KeyCode.LEFT) {
textField.positionCaret(textField.getCaretPosition() + (isArabic ? 1 : -1));
event.consume();
} else if (event.getCode() == KeyCode.RIGHT) {
textField.positionCaret(textField.getCaretPosition() + (isArabic ? -1 : 1));
event.consume();
}
});
}

public static boolean isArabicCharacter(char c) {
return Character.UnicodeBlock.of(c) == Character.UnicodeBlock.ARABIC;
}

public static int clamp(int min, int value, int max) {
return value < min ? min : Math.min(value, max);
}
}


Подробнее здесь: https://stackoverflow.com/questions/791 ... s-expected
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»