同时扩展Textfields和Textareas的功能

时间:2017-12-01 09:03:52

标签: java javafx

我想制作一个自定义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类。

在这两种情况下,我觉得我做错了什么!所以我的问题是实现我想要的最恰当的方式是什么?

1 个答案:

答案 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方法,这一切都不会起作用。