-
Bug
-
Resolution: Unresolved
-
P4
-
jfx11
-
x86_64
-
windows_10
A DESCRIPTION OF THE PROBLEM :
When comboboxes have many items, or complex cells, layouts can take a long time. The layout time dramatically improves once the combobox is even slightly scrolled because a single cell gets added to the pile in the virtualflow.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached code. Open the combobox and hover over the items. Each one takes a long time to render. If you scroll slightly, then the hover actions happen immediately.
Each time you move the mouse to a new cell, the cell selection triggers a layout which is slow because it recalculates the combobox width. Once you scroll the combobox however, one or more cells are added to the pile in virtualflow, and those are used to determine the combobox width which massively improves performance.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Combobox layout should be fast after the initial slow layout.
ACTUAL -
All layouts are slow until the combobox is scrolled slightly.
---------- BEGIN SOURCE ----------
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class ComboBoxTest extends Application {
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
Scene scene = new Scene(root, 800, 600);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
ComboBox<String> comboBox = new ComboBox();
comboBox.setEditable(true);
comboBox.setItems(getItems());
comboBox.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
@Override
public ListCell<String> call(ListView<String> arg0) {
return new ListCell<String>() {
{
this.setOnMouseEntered((MouseEvent e) -> {
comboBox.getSelectionModel().select(this.getIndex());
});
}
@Override
protected void updateItem(String text, boolean empty) {
super.updateItem(text, empty);
setText(text);
}
};
}
});
root.getChildren().add(comboBox);
primaryStage.show();
}
public ObservableList<String> getItems() {
ObservableList<String> list = FXCollections.observableArrayList();
for (int i = 0; i < 500000; i++) {
list.add("" + Math.random());
}
return list;
}
}
---------- END SOURCE ----------
FREQUENCY : always
When comboboxes have many items, or complex cells, layouts can take a long time. The layout time dramatically improves once the combobox is even slightly scrolled because a single cell gets added to the pile in the virtualflow.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached code. Open the combobox and hover over the items. Each one takes a long time to render. If you scroll slightly, then the hover actions happen immediately.
Each time you move the mouse to a new cell, the cell selection triggers a layout which is slow because it recalculates the combobox width. Once you scroll the combobox however, one or more cells are added to the pile in virtualflow, and those are used to determine the combobox width which massively improves performance.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Combobox layout should be fast after the initial slow layout.
ACTUAL -
All layouts are slow until the combobox is scrolled slightly.
---------- BEGIN SOURCE ----------
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class ComboBoxTest extends Application {
@Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
Scene scene = new Scene(root, 800, 600);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
ComboBox<String> comboBox = new ComboBox();
comboBox.setEditable(true);
comboBox.setItems(getItems());
comboBox.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
@Override
public ListCell<String> call(ListView<String> arg0) {
return new ListCell<String>() {
{
this.setOnMouseEntered((MouseEvent e) -> {
comboBox.getSelectionModel().select(this.getIndex());
});
}
@Override
protected void updateItem(String text, boolean empty) {
super.updateItem(text, empty);
setText(text);
}
};
}
});
root.getChildren().add(comboBox);
primaryStage.show();
}
public ObservableList<String> getItems() {
ObservableList<String> list = FXCollections.observableArrayList();
for (int i = 0; i < 500000; i++) {
list.add("" + Math.random());
}
return list;
}
}
---------- END SOURCE ----------
FREQUENCY : always