JavaFx Control Skin: layout the only child as if my control inherited from it

149 views Asked by At

I have an interface like this, that I use in a lot of places in the project:

public interface ValueHoldingControl<T> {

    T getValue();

    ObjectProperty<T> valueProperty();

    void setValue(T value);
}

I need a version of this DateTimePicker that implements ValueHoldingControl<LocalDateTime>. Since all of the methods declared in my interface are already implemented in the DateTimePicker from the repository, and they have LocalDate as their type, I cannot use inheritance to achieve this.

This is my current version (parts irrelevant to my problem are omitted):

public class ComposedDateTimePicker extends Control implements ValueHoldingControl<LocalDateTime> {

    private static class ComposedDateTimePickerSkin extends SkinBase<ComposedDateTimePicker> {
        private ComposedDateTimePickerSkin(ComposedDateTimePicker control) {
            super(control);
            getChildren().add(control.dateTimePicker);
        }
    }

    private final DateTimePicker dateTimePicker = new DateTimePicker();
     
    @Override
    protected Skin<?> createDefaultSkin() {
        return new ComposedDateTimePickerSkin(this);
    }

    @Override
    public LocalDateTime getValue() {
        return dateTimePicker.getDateTimeValue();
    }

    @Override
    public void setValue(LocalDateTime dateTimeValue) {
        dateTimePicker.setDateTimeValue(dateTimeValue);
    }

    @Override
    public ObjectProperty<LocalDateTime> valueProperty() {
        return dateTimePicker.dateTimeValueProperty();
    }

}

The problem: When I layout my ComposedDateTimePicker from the outside (e.g. composedDateTimePicker.setMaxWidth(Double.POSITIVE_INFINITY)), this does not have any effect on the internal DateTimePicker.

I can solve that for the width if I override layoutChildren of my ComposedDateTimePickerSkin like this:

        @Override
        protected void layoutChildren(double contentX, double contentY, double contentWidth, double contentHeight) {
            ((ComposedDateTimePicker) getNode()).dateTimePicker.setPrefWidth(contentWidth);
            super.layoutChildren(contentX, contentY, contentWidth, contentHeight);
        }

I could do the same for the height. However, I don't like this way of doing it, since it is not a general solution.

I would like to do it in a way that no matter what kind of layouting setting I apply on my ComposedDateTimePicker, it behaves as if it was inherited from DateTimePicker.

Is there any way to achieve that?

0

There are 0 answers