This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 65ca19a ISIS-2340: fx: bind validation feedback to UI comp. (initial)
65ca19a is described below
commit 65ca19ad1f92f2906473136a9373d39b3a184e6b
Author: Andi Huber <[email protected]>
AuthorDate: Sun Aug 16 19:01:21 2020 +0200
ISIS-2340: fx: bind validation feedback to UI comp. (initial)
---
.../viewer/javafx/model/binding/BindingsFx.java | 22 ++++++++
.../incubator/viewer/javafx/model/util/_fx.java | 61 ++++++++++++++++------
.../ui/components/number/NumberFieldFactory.java | 20 +++++--
3 files changed, 81 insertions(+), 22 deletions(-)
diff --git
a/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/binding/BindingsFx.java
b/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/binding/BindingsFx.java
index debd155..9e28653 100644
---
a/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/binding/BindingsFx.java
+++
b/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/binding/BindingsFx.java
@@ -29,6 +29,7 @@ import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.viewer.common.model.binding.BindingConverter;
import javafx.beans.property.Property;
+import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import lombok.NonNull;
import lombok.val;
@@ -37,6 +38,16 @@ import lombok.experimental.UtilityClass;
@UtilityClass
public class BindingsFx {
+ public static <T> void bind(
+ final @NonNull Property<T> leftProperty,
+ final @NonNull Observable<T> rightObservable) {
+
+ leftProperty.setValue(rightObservable.getValue());
+ rightObservable.addListener((e,o,n)->{
+ leftProperty.setValue(n);
+ });
+ }
+
public static <L> void bind(
final @NonNull Property<L> leftProperty,
final @NonNull Observable<ManagedObject> rightObservable,
@@ -58,6 +69,17 @@ public class BindingsFx {
rightProperty.addListener(binding);
}
+ // -- VALIDATION
+
+ public static void bindValidationFeeback(
+ final @NonNull StringProperty textProperty,
+ final @NonNull Property<Boolean> visibilityProperty,
+ final @NonNull Observable<String> textObservable) {
+
+ bind(textProperty, textObservable);
+ visibilityProperty.bind(textProperty.isNotEmpty());
+ }
+
// -- INTERNAL
private static class InternalBidirBinding<T>
diff --git
a/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/util/_fx.java
b/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/util/_fx.java
index 0106404..31ac904 100644
---
a/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/util/_fx.java
+++
b/incubator/viewers/javafx/model/src/main/java/org/apache/isis/incubator/viewer/javafx/model/util/_fx.java
@@ -22,10 +22,6 @@ import java.util.function.Predicate;
import javax.annotation.Nullable;
-import lombok.NonNull;
-import lombok.val;
-import lombok.experimental.UtilityClass;
-
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.value.ObservableValue;
@@ -65,6 +61,9 @@ import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
+import lombok.NonNull;
+import lombok.val;
+import lombok.experimental.UtilityClass;
@UtilityClass
public final class _fx {
@@ -91,6 +90,21 @@ public final class _fx {
container.getChildren().add(component);
return component;
}
+
+ public static Label newValidationFeedback(Pane container) {
+ val component = new Label();
+ container.getChildren().add(component);
+ visibilityLayoutFix(component);
+ component.setStyle("-fx-color: red");
+ component.visibleProperty().addListener((e, o, visible)->{
+ if(visible) {
+ borderDashed(container, Color.RED);
+ } else {
+ container.setBorder(null);
+ }
+ });
+ return component;
+ }
public static Button newButton(Pane container, String label,
EventHandler<ActionEvent> eventHandler) {
val component = new Button(label);
@@ -200,7 +214,19 @@ public final class _fx {
tableView.getColumns().add(column);
return column;
}
+
+ // -- VISIBILITY
+ /**
+ * Do not consider node for layout calculations, when not visible
+ * @param node
+ * @return
+ */
+ public static Node visibilityLayoutFix(Node node) {
+ node.managedProperty().bind(node.visibleProperty());
+ return node;
+ }
+
// -- ICONS
public static Image imageFromClassPath(@NonNull Class<?> cls, String
resourceName) {
@@ -258,19 +284,20 @@ public final class _fx {
}
}
- private static boolean isEmptyOrHidden(Node component) {
- if(component instanceof Pane) {
- val children = ((Pane) component).getChildrenUnmodifiable();
- if(children.isEmpty()) {
- return true; // empty
- }
- //return true only if all children are empty or hidden
- val atLeastOneIsNonEmptyOrVisible = children.stream()
- .anyMatch(child->!isEmptyOrHidden(child));
- return !atLeastOneIsNonEmptyOrVisible;
- }
- return !component.isVisible();
- }
+//XXX Superseded by visibilityLayoutFix(Node node)
+// private static boolean isEmptyOrHidden(Node component) {
+// if(component instanceof Pane) {
+// val children = ((Pane) component).getChildrenUnmodifiable();
+// if(children.isEmpty()) {
+// return true; // empty
+// }
+// //return true only if all children are empty or hidden
+// val atLeastOneIsNonEmptyOrVisible = children.stream()
+// .anyMatch(child->!isEmptyOrHidden(child));
+// return !atLeastOneIsNonEmptyOrVisible;
+// }
+// return !component.isVisible();
+// }
public static void hideUntilPopulated(Pane component) {
diff --git
a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/number/NumberFieldFactory.java
b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/number/NumberFieldFactory.java
index 0b64556..890e6f2 100644
---
a/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/number/NumberFieldFactory.java
+++
b/incubator/viewers/javafx/ui/src/main/java/org/apache/isis/incubator/viewer/javafx/ui/components/number/NumberFieldFactory.java
@@ -26,12 +26,14 @@ import org.apache.isis.applib.annotation.OrderPrecedence;
import org.apache.isis.core.metamodel.interactions.managed.ManagedParameter;
import org.apache.isis.core.metamodel.interactions.managed.ManagedProperty;
import org.apache.isis.incubator.viewer.javafx.model.binding.BindingsFx;
+import org.apache.isis.incubator.viewer.javafx.model.util._fx;
import
org.apache.isis.incubator.viewer.javafx.ui.components.UiComponentHandlerFx;
import
org.apache.isis.viewer.common.model.binding.NumberConverterForStringComponent;
import
org.apache.isis.viewer.common.model.components.UiComponentFactory.ComponentRequest;
import javafx.scene.Node;
import javafx.scene.control.TextField;
+import javafx.scene.layout.VBox;
import lombok.RequiredArgsConstructor;
import lombok.val;
@@ -48,7 +50,9 @@ public class NumberFieldFactory implements
UiComponentHandlerFx {
@Override
public Node handle(ComponentRequest request) {
- val uiComponent = new TextField();
+ val uiComponent = new VBox();
+ val uiField = _fx.add(uiComponent, new TextField());
+ val uiValidationFeedback = _fx.newValidationFeedback(uiComponent);
val valueSpec = request.getFeatureTypeSpec();
val converter = new NumberConverterForStringComponent(valueSpec);
@@ -57,11 +61,14 @@ public class NumberFieldFactory implements
UiComponentHandlerFx {
val managedParameter =
(ManagedParameter)request.getManagedFeature();
BindingsFx.bindBidirectional(
- uiComponent.textProperty(),
+ uiField.textProperty(),
managedParameter.getValue(),
converter);
-
- //TODO bind parameter validation feedback
+
+ BindingsFx.bindValidationFeeback(
+ uiValidationFeedback.textProperty(),
+ uiValidationFeedback.visibleProperty(),
+ managedParameter.getValidationMessage());
} else if(request.getManagedFeature() instanceof ManagedProperty) {
@@ -69,12 +76,15 @@ public class NumberFieldFactory implements
UiComponentHandlerFx {
// readonly binding
BindingsFx.bind(
- uiComponent.textProperty(),
+ uiField.textProperty(),
managedProperty.getValue(),
converter);
//TODO allow property editing
+ uiField.editableProperty().set(false);
+
//TODO bind property validation feedback
+
}
return uiComponent;