我有一个由fxml文件定义的复杂UI。我想将许多库存TextField
更改为ControlsFX库提供的更高级的版本(可清除的文本字段)。
问题:
ControlsFX使用CustomTextField
提供高级功能,但只能通过TextFields.createClearableTextField()
进行初始化,而只能通过代码进行调用。
我正在寻找一种方法,以将通过FXML初始化的TextField
与通过代码初始化的CustomTextField
交换,以便这些新控件保留FXML中定义的所有布局属性。
在FXML中定义CustomTextField
也没有帮助,因为默认情况下它是无用的。
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();
}
});
}
答案 0 :(得分:2)
您可以按照Introduction to FXML中的说明使用fx:factory
。
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.StackPane?>
<?import org.controlsfx.control.textfield.TextFields?>
<StackPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml"
fx:controller="com.example.Controller">
<TextFields fx:id="field" fx:factory="createClearableTextField"/>
</StackPane>
然后在控制器中使用它:
package com.example;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
public class Controller {
@FXML private TextField field;
}
注意:如果您使用的是IntelliJ,它将发出错误消息:
无法将org.controlsfx.control.textfield.TextFields设置为字段'field'
在FXML文件中,但是当我运行测试项目时,一切正常。