I have made a simple application which display a ListView with custom cells.
Each custom cell is made of 3 ToggleButtons.
Moving the mouse around over each button is fine except when adding css class to button.
In fact, updateItem() is called every time the mouse is moving over the list and memory seems to keep increasing.
This behavior is not excepted because cells are already rendered and updated.
Seems i can't attach files on this JIRA so here is the code :
##################################################### default.css
.button {
-fx-opacity: 0.5;
-fx-background-radius: 0;
-fx-background-color: gray;
}
.button:hover,
.button:selected,
.button:selected:focused {
-fx-opacity: 1;
-fx-background-insets: 0;
-fx-background-color: lightgray;
}
##################################################### CustomCell.java
public class CustomCell extends ListCell<Number[]> {
private final HBox cell;
private final ToggleButton button1;
private final ToggleButton button2;
private final ToggleButton button3;
public CustomCell() {
this.cell = new HBox(4);
cell.setPrefHeight(140);
this.button1 = createButton();
this.button2 = createButton();
this.button3 = createButton();
cell.getChildren().addAll(button1, button2, button3);
}
private ToggleButton createButton() {
ToggleButton button = new ToggleButton();
button.getStyleClass().add("button"); // <- adding this line makes updateItem called to many times
button.setPrefHeight(140);
button.setPrefWidth(65);
return button;
}
protected void updateButtons(Number[] item) {
button1.setText(item[0].toString());
button2.setText(item[1].toString());
button3.setText(item[2].toString());
}
private int i = 0;
@Override
public void updateItem(Number[] item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
System.out.println("UPDATE ITEM: " + i++);
updateButtons(item);
setGraphic(cell);
}
}
}
##################################################### ListViewCellFactoryApp.java
public class ListViewCellFactoryApp extends Application {
public Parent createContent() {
ObservableList<Number[]> data = FXCollections.observableArrayList();
for( int i = 0; i < 400; i++ ) {
data.add(new Number[] {i++,i++,i});
}
final ListView<Number[]> listView = new ListView<>(data);
listView.setCellFactory(new Callback<ListView<Number[]>, ListCell<Number[]>>() {
@Override public ListCell<Number[]> call(ListView<Number[]> list) {
return new CustomCell();
}
});
return listView;
}
@Override
public void start(Stage primaryStage) throws Exception {
Scene scene = new Scene(createContent());
scene.getStylesheets().add("/com/test/default.css");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* Java main for when running without JavaFX launcher
*/
public static void main(String[] args) {
launch(args);
}
}
Each custom cell is made of 3 ToggleButtons.
Moving the mouse around over each button is fine except when adding css class to button.
In fact, updateItem() is called every time the mouse is moving over the list and memory seems to keep increasing.
This behavior is not excepted because cells are already rendered and updated.
Seems i can't attach files on this JIRA so here is the code :
##################################################### default.css
.button {
-fx-opacity: 0.5;
-fx-background-radius: 0;
-fx-background-color: gray;
}
.button:hover,
.button:selected,
.button:selected:focused {
-fx-opacity: 1;
-fx-background-insets: 0;
-fx-background-color: lightgray;
}
##################################################### CustomCell.java
public class CustomCell extends ListCell<Number[]> {
private final HBox cell;
private final ToggleButton button1;
private final ToggleButton button2;
private final ToggleButton button3;
public CustomCell() {
this.cell = new HBox(4);
cell.setPrefHeight(140);
this.button1 = createButton();
this.button2 = createButton();
this.button3 = createButton();
cell.getChildren().addAll(button1, button2, button3);
}
private ToggleButton createButton() {
ToggleButton button = new ToggleButton();
button.getStyleClass().add("button"); // <- adding this line makes updateItem called to many times
button.setPrefHeight(140);
button.setPrefWidth(65);
return button;
}
protected void updateButtons(Number[] item) {
button1.setText(item[0].toString());
button2.setText(item[1].toString());
button3.setText(item[2].toString());
}
private int i = 0;
@Override
public void updateItem(Number[] item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
System.out.println("UPDATE ITEM: " + i++);
updateButtons(item);
setGraphic(cell);
}
}
}
##################################################### ListViewCellFactoryApp.java
public class ListViewCellFactoryApp extends Application {
public Parent createContent() {
ObservableList<Number[]> data = FXCollections.observableArrayList();
for( int i = 0; i < 400; i++ ) {
data.add(new Number[] {i++,i++,i});
}
final ListView<Number[]> listView = new ListView<>(data);
listView.setCellFactory(new Callback<ListView<Number[]>, ListCell<Number[]>>() {
@Override public ListCell<Number[]> call(ListView<Number[]> list) {
return new CustomCell();
}
});
return listView;
}
@Override
public void start(Stage primaryStage) throws Exception {
Scene scene = new Scene(createContent());
scene.getStylesheets().add("/com/test/default.css");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* Java main for when running without JavaFX launcher
*/
public static void main(String[] args) {
launch(args);
}
}