У меня сложный пользовательский интерфейс, определенный в файле fxml. Существует множество фондов TextField
, которые я хотел бы изменить на более продвинутые версии (очищаемое текстовое поле), предоставляемые библиотекой ControlsFX .
Проблема:
ControlsFX использует CustomTextField
для предоставления расширенных функций, но его можно инициализировать только с помощью TextFields.createClearableTextField()
, который можно вызвать только из кода.
Я ищу способ поменять TextField
s, инициализированный через FXML, на CustomTextField
s, инициализированный из кода, чтобы эти новые элементы управления сохранили все свойства макета, определенные в FXML.
Определение CustomTextField
в FXML также не полезно, потому что по умолчанию оно бесполезно.
CustomTextField
получает свои функции через private static void setupClearButtonField(TextField inputField, ObjectProperty<Node> rightProperty)
, который я не могу назвать, потому что это личное.
ControlSFX код:
/**
* Creates a TextField that shows a clear button inside the TextField (on
* the right hand side of it) when text is entered by the user.
*/
public static TextField createClearableTextField() {
CustomTextField inputField = new CustomTextField();
setupClearButtonField(inputField, inputField.rightProperty());
return inputField;
}
/**
* Creates a PasswordField that shows a clear button inside the PasswordField
* (on the right hand side of it) when text is entered by the user.
*/
public static PasswordField createClearablePasswordField() {
CustomPasswordField inputField = new CustomPasswordField();
setupClearButtonField(inputField, inputField.rightProperty());
return inputField;
}
private static void setupClearButtonField(TextField inputField, ObjectProperty<Node> rightProperty) {
inputField.getStyleClass().add("clearable-field"); //$NON-NLS-1$
Region clearButton = new Region();
clearButton.getStyleClass().addAll("graphic"); //$NON-NLS-1$
StackPane clearButtonPane = new StackPane(clearButton);
clearButtonPane.getStyleClass().addAll("clear-button"); //$NON-NLS-1$
clearButtonPane.setOpacity(0.0);
clearButtonPane.setCursor(Cursor.DEFAULT);
clearButtonPane.setOnMouseReleased(e -> inputField.clear());
clearButtonPane.managedProperty().bind(inputField.editableProperty());
clearButtonPane.visibleProperty().bind(inputField.editableProperty());
rightProperty.set(clearButtonPane);
final FadeTransition fader = new FadeTransition(FADE_DURATION, clearButtonPane);
fader.setCycleCount(1);
inputField.textProperty().addListener(new InvalidationListener() {
@Override public void invalidated(Observable arg0) {
String text = inputField.getText();
boolean isTextEmpty = text == null || text.isEmpty();
boolean isButtonVisible = fader.getNode().getOpacity() > 0;
if (isTextEmpty && isButtonVisible) {
setButtonVisible(false);
} else if (!isTextEmpty && !isButtonVisible) {
setButtonVisible(true);
}
}
private void setButtonVisible( boolean visible ) {
fader.setFromValue(visible? 0.0: 1.0);
fader.setToValue(visible? 1.0: 0.0);
fader.play();
}
});
}