我想制作一个自定义textfield/textarea
,当他们获得焦点时,他们的文字会被选中。脑海中浮现出两个想法:
1-制作扩展超类的 CustomTextField / CustomTextArea 类,并在这些类的构造函数中添加我想要的功能[示例代码]:
public class CutstomTextField extends TextField implements Customizable {
private boolean recentlyFocused = false;
public CutstomTextField() {
super();
customize();
}
/**
* @Special_Behaviour: Selects all its text when gets focus
**/
@Override
public void customize() {
this.addEventFilter(MouseEvent.MOUSE_DRAGGED, event -> {
if (recentlyFocused) {
event.consume();
}
});
this.focusedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
// Deselect on focus loss
if (!newValue) {
this.deselect();
recentlyFocused = false;
return;
}
recentlyFocused = true;
// Select all
Platform.runLater(() -> {
if (!this.getText().isEmpty()) {
this.selectAll();
}
});
// Delay to avoid issues
Timeline tl = new Timeline(new KeyFrame(Duration.seconds(0.2), event -> recentlyFocused = false));
tl.play();
});
}
}
但是,我必须基本上复制粘贴相同的代码添加 CustomTextfield和CustomTextarea的功能
2)
CustomTextInputControl
扩展TextInputControl
的课程。CustomTextfield//CustomTextarea
扩展该类。但现在好像我必须复制粘贴Textfield的所有代码 class为CustomTextfield类,以使其工作。同样的 CustomTextarea类。
在这两种情况下,我觉得我做错了什么!所以我的问题是实现我想要的最恰当的方式是什么?
答案 0 :(得分:2)
对于上面的特定情况,您可以在不使用继承的情况下获得所需的功能:
public class CustomTextControl {
private static class BooleanWrapper {
private boolean value ;
}
public static <T extends TextInputControl> T customize(T control) {
BooleanWrapper recentlyFocused = new BooleanWrapper();
control.addEventFilter(MouseEvent.MOUSE_DRAGGED, event -> {
if (recentlyFocused.value) {
event.consume();
}
});
control.focusedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
// Deselect on focus loss
if (!newValue) {
control.deselect();
recentlyFocused.value = false;
return;
}
recentlyFocused.value = true;
// Select all
Platform.runLater(() -> {
if (!control.getText().isEmpty()) {
control.selectAll();
}
});
// Delay to avoid issues
Timeline tl = new Timeline(new KeyFrame(Duration.seconds(0.2), event -> recentlyFocused.value = false));
tl.play();
});
return control ;
}
}
您使用的是:
TextField customTextField = CustomTextControl.customize(new TextField());
TextArea cusomtTextArea = CustomTextControl.customize(new TextArea());
如果您希望能够在FXML中使用它,则需要添加一些无法工厂方法:
public class CustomTextControl {
// existing code...
public static TextField newTextField() {
return customize(new TextField());
}
public static TextArea newTextArea() {
return customize(new TextArea());
}
}
然后你可以这样做:
<CustomTextControl fx:factory="newTextField">
<!-- set text field properties -->
</CustomTextControl>
请注意,如果您想覆盖现有的TextInputControl
方法,这一切都不会起作用。