-
Bug
-
Resolution: Not an Issue
-
P4
-
8u60
-
x86_64
-
windows_7
FULL PRODUCT VERSION :
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Windows 7 Enterprise SP1
ver: Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
In our application we manage the different views by removing/adding them from/to scene graph dynamically. Some of the views contain the TableViews with non-trivial number of columns (50+). We noticed, that call node.getChildren().add(view) for such views takes 5+ seconds. Since this happens in javafx thread, this makes the whole application freeze for this duration.
I managed to extract a self containing test case demonstrating the issue. Just keep clicking on the + button to remove/add the TableView with 288 columns. Adding the TableView takes 3 seconds on a modern Intel Core i7 processor.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Start the test case
2) click + to hide the TableView
3) click + to show the TableView, timing information appear in stdout
repeat steps 2-3 if you like
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Nearly-instanteous appearance of TableView in the scenegraph, no freezing of the application
ACTUAL -
Application freeze for few seconds during addition
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.Arrays;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class FXTableViewExample extends Application {
public static class Book {
private SimpleStringProperty title;
private SimpleStringProperty author;
public Book() {
}
public Book(String s1, String s2) {
title = new SimpleStringProperty(s1);
author = new SimpleStringProperty(s2);
}
public String getTitle() {
return title.get();
}
public void setTitle(String s) {
title.set(s);
}
public String getAuthor() {
return author.get();
}
public void setAuthor(String s) {
author.set(s);
}
}
public static void main(String [] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Table View Example 1");
// Books label
Button showhide = new Button("+");
HBox hb = new HBox();
hb.setAlignment(Pos.CENTER);
hb.getChildren().add(showhide);
// Table view, data, columns and properties
TableView<Book> table = new TableView<>();
table.setItems(FXCollections.observableList(Arrays.asList(new Book("A", "B"))));
String[] columns = {
"title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
};
for (String prop : columns) {
TableColumn<Book, String> col = new TableColumn<>(prop);
col.setCellValueFactory(new PropertyValueFactory<>(prop));
table.getColumns().add(col);
}
table.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY);
AnchorPane tmp = new AnchorPane(table);
for (int i=0; i<50; i++) {
tmp = new AnchorPane(tmp);
AnchorPane.setTopAnchor(tmp, 0.0);
AnchorPane.setRightAnchor(tmp, 0.0);
AnchorPane.setBottomAnchor(tmp, 0.0);
AnchorPane.setLeftAnchor(tmp, 0.0);
}
final AnchorPane paneForTable = tmp;
final VBox vbox = new VBox(20);
vbox.getChildren().addAll(hb, paneForTable);
showhide.setOnAction((event) -> {
if (!vbox.getChildren().remove(paneForTable)) {
long started = System.currentTimeMillis();
vbox.getChildren().add(paneForTable);
long duration = System.currentTimeMillis() - started;
System.out.println(String.format("Add took %d ms for %d columns", duration, table.getColumns().size()));
}
});
// Scene
Scene scene = new Scene(vbox, 500, 475);
primaryStage.setScene(scene);
primaryStage.show();
}
}
---------- END SOURCE ----------
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Windows 7 Enterprise SP1
ver: Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
In our application we manage the different views by removing/adding them from/to scene graph dynamically. Some of the views contain the TableViews with non-trivial number of columns (50+). We noticed, that call node.getChildren().add(view) for such views takes 5+ seconds. Since this happens in javafx thread, this makes the whole application freeze for this duration.
I managed to extract a self containing test case demonstrating the issue. Just keep clicking on the + button to remove/add the TableView with 288 columns. Adding the TableView takes 3 seconds on a modern Intel Core i7 processor.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Start the test case
2) click + to hide the TableView
3) click + to show the TableView, timing information appear in stdout
repeat steps 2-3 if you like
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Nearly-instanteous appearance of TableView in the scenegraph, no freezing of the application
ACTUAL -
Application freeze for few seconds during addition
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.Arrays;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class FXTableViewExample extends Application {
public static class Book {
private SimpleStringProperty title;
private SimpleStringProperty author;
public Book() {
}
public Book(String s1, String s2) {
title = new SimpleStringProperty(s1);
author = new SimpleStringProperty(s2);
}
public String getTitle() {
return title.get();
}
public void setTitle(String s) {
title.set(s);
}
public String getAuthor() {
return author.get();
}
public void setAuthor(String s) {
author.set(s);
}
}
public static void main(String [] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Table View Example 1");
// Books label
Button showhide = new Button("+");
HBox hb = new HBox();
hb.setAlignment(Pos.CENTER);
hb.getChildren().add(showhide);
// Table view, data, columns and properties
TableView<Book> table = new TableView<>();
table.setItems(FXCollections.observableList(Arrays.asList(new Book("A", "B"))));
String[] columns = {
"title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
, "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author", "title", "author"
};
for (String prop : columns) {
TableColumn<Book, String> col = new TableColumn<>(prop);
col.setCellValueFactory(new PropertyValueFactory<>(prop));
table.getColumns().add(col);
}
table.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY);
AnchorPane tmp = new AnchorPane(table);
for (int i=0; i<50; i++) {
tmp = new AnchorPane(tmp);
AnchorPane.setTopAnchor(tmp, 0.0);
AnchorPane.setRightAnchor(tmp, 0.0);
AnchorPane.setBottomAnchor(tmp, 0.0);
AnchorPane.setLeftAnchor(tmp, 0.0);
}
final AnchorPane paneForTable = tmp;
final VBox vbox = new VBox(20);
vbox.getChildren().addAll(hb, paneForTable);
showhide.setOnAction((event) -> {
if (!vbox.getChildren().remove(paneForTable)) {
long started = System.currentTimeMillis();
vbox.getChildren().add(paneForTable);
long duration = System.currentTimeMillis() - started;
System.out.println(String.format("Add took %d ms for %d columns", duration, table.getColumns().size()));
}
});
// Scene
Scene scene = new Scene(vbox, 500, 475);
primaryStage.setScene(scene);
primaryStage.show();
}
}
---------- END SOURCE ----------