changeset 1779:53fbd2add357

RT-35272: JAVAFX TABLEVIEW VALUES STOP UPDATING WHEN VALUES ARE INVALIDATED Reviewed-by: jgiles
author bae
date Mon, 05 May 2014 11:04:16 +0100
parents 845bff23874e
children 861ad6a6305c
files javafx-ui-controls/src/com/sun/javafx/scene/control/skin/VirtualFlow.java javafx-ui-controls/test/javafx/scene/control/TableViewBindingTest.java
diffstat 2 files changed, 181 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/VirtualFlow.java	Tue Apr 29 07:22:34 2014 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/VirtualFlow.java	Mon May 05 11:04:16 2014 +0100
@@ -801,6 +801,11 @@
         if (getScene() != null/* && !isNeedsLayout()*/) {
             getScene().addToDirtyLayoutList(this);
             setNeedsLayout(true);
+        } else {
+            final Parent p = getParent();
+            if (p != null) {
+                p.requestLayout();
+            }
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javafx-ui-controls/test/javafx/scene/control/TableViewBindingTest.java	Mon May 05 11:04:16 2014 +0100
@@ -0,0 +1,176 @@
+package javafx.scene.control;
+
+import com.sun.javafx.pgstub.StubToolkit;
+import com.sun.javafx.tk.Toolkit;
+import javafx.beans.binding.StringBinding;
+import javafx.beans.binding.When;
+import javafx.beans.property.IntegerProperty;
+import javafx.beans.property.SimpleIntegerProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Scene;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.StackPane;
+import javafx.stage.Stage;
+import javafx.util.Callback;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test for RT-35272
+ */
+public class TableViewBindingTest {
+
+    private static final int STEP_COUNT = 3;
+    private static final long MOD_SIZE = 100000L;
+
+    private Stage stage;
+    private BorderPane root;
+
+    private final StubToolkit toolkit;
+
+    private final StringProperty text;
+    private final IntegerProperty step;
+
+    TableView<TestRow> tableView;
+
+    private static class Step {
+        final String value;
+        final boolean doIncrement;
+        final boolean needAssert;
+
+        public Step(String v, boolean i, boolean a) {
+            value = v;
+            doIncrement = i;
+            needAssert = a;
+        }
+    }
+
+    private final Step[] steps;
+
+    public TableViewBindingTest() {
+        toolkit = (StubToolkit)Toolkit.getToolkit();
+
+        text = new SimpleStringProperty("None");
+        step = new SimpleIntegerProperty(0);
+
+        steps = new Step[] {
+                new Step("Apple", false, true),  // make sure that binding works
+                new Step("Orange", true, true),  // remove table from the scene
+                new Step("Banana", true, false), // add the table back to scene
+                new Step("Peach", false, true)   // make sure that the table is updated.
+        };
+    }
+
+    private static class TestRow
+    {
+        public TestRow()
+        {
+        }
+    }
+
+    private TableColumn<TestRow, String> createColumn(double prefWidth)
+    {
+        TableColumn<TestRow, String> column = new TableColumn<TestRow, String>();
+        column.setText("Fruit");
+        column.setPrefWidth(prefWidth);
+        column.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<TestRow, String>, ObservableValue<String>>()
+        {
+            @Override
+            public ObservableValue<String> call(TableColumn.CellDataFeatures<TestRow, String> param)
+            {
+                return new FruitBinding(text);
+            }
+        });
+        return column;
+    }
+
+    private static class FruitBinding extends StringBinding
+    {
+        public static String lastComputedValue;
+
+        private final ObservableValue<String> text;
+
+        public FruitBinding(ObservableValue<String> text)
+        {
+            this.text = text;
+
+            bind(text);
+        }
+
+        @Override
+        protected String computeValue()
+        {
+            lastComputedValue = text.getValue();
+            System.out.println("Computed: " + lastComputedValue);
+            return lastComputedValue;
+        }
+    }
+
+    @Before public void setup() {
+        tableView = new TableView<TestRow>();
+        tableView.getColumns().addAll(createColumn(100));
+        tableView.getItems().addAll(new TestRow());
+
+        tableView.setFocusTraversable(false);
+        tableView.setPrefHeight(180d);
+
+        StackPane stackPane = new StackPane();
+        stackPane.setPadding(new Insets(5d, 0d, 5d, 0d));
+
+
+        HBox bottomPane = new HBox(5d);
+        bottomPane.setMaxWidth(Double.MAX_VALUE);
+        bottomPane.setAlignment(Pos.BASELINE_RIGHT);
+
+        BorderPane.setMargin(tableView, new Insets(10d, 0d, 10d, 0d));
+        root = new BorderPane();
+        root.setPadding(new Insets(10d));
+        root.setTop(stackPane);
+        root.setBottom(bottomPane);
+
+        root.centerProperty().bind(new When(step.isNotEqualTo(1))
+                .then(tableView)
+                .otherwise((TableView) null));
+
+        stage = new Stage();
+
+        stage.setTitle("Table Row Value Bug");
+        stage.setScene(new Scene(root));
+        stage.centerOnScreen();
+        stage.show();
+    }
+
+    private void stepForward() {
+        int nextStep = step.get() + 1;
+        step.set(nextStep);
+
+        toolkit.fireTestPulse();
+    }
+
+    @Test
+    public void checkBinding() {
+
+        for (Step s : steps) {
+            text.setValue(s.value);
+
+            toolkit.fireTestPulse();
+
+            if (s.needAssert) {
+                Assert.assertEquals(s.value, FruitBinding.lastComputedValue);
+            }
+
+            if (s.doIncrement) {
+                stepForward();
+            }
+        }
+
+        System.out.println("Test passed.");
+    }
+}