-
Bug
-
Resolution: Unresolved
-
P4
-
8u5
I have following problem, in my ListView the scrollbar fills 100% of its container so that it is impossible to use. This happens when the ListView has only one cell which is also bigger than its viewport. I wrote a small example to show it:
public class ExtendedScrollbarWrongHeight2 extends Application {
private BorderPane borderPane;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
final Parent parent = createParent();
final Scene scene = new Scene(parent, 640, 480);
primaryStage.setScene(scene);
primaryStage.show();
}
protected Parent createParent() {
final ObservableList<String> items = FXCollections.observableArrayList();
items.add("Scroll Down 1");
// items.add("Scroll Down 2"); // uncomment and bug is fixed
final ListView<String> listView = new ListView<>();
listView.setItems(items);
listView.setCellFactory(param -> {
return new CellCenter();
});
return listView;
}
private static class CellCenter extends ListCell<String> {
private final Label label = new Label();
@Override
protected void updateItem(String item, boolean empty) {
if (item == null || empty) {
setGraphic(null);
} else {
label.setMaxHeight(USE_PREF_SIZE);
label.setMaxWidth(USE_PREF_SIZE);
label.setMinHeight(USE_PREF_SIZE);
label.setMinWidth(USE_PREF_SIZE);
label.setPrefHeight(700);
label.setPrefWidth(640);
label.setStyle("-fx-background-color: indianred; -fx-border-color: darkred;-fx-border-width: 1px;-fx-font-size: 40px;");
label.setText("ScrollDown");
setGraphic(label);
}
}
}
}
When I add a second item to the ListView the scrollbar thumb has the correct size, but I also need it for single cells. I used the debugger and found a method updateScrollBarsAndCells() in VirtualFlow which is responsible for the calculation. It seems that the bug is known, see the comments in the last if case, but I found only one similar issue here (RT-29624) and I was not sure if it is the same problem.
if (recreate && (lengthBar.isVisible() || BehaviorSkinBase.IS_TOUCH_SUPPORTED)) {
int numCellsVisibleOnScreen = 0;
for (int i = 0, max = cells.size(); i < max; i++) {
T cell = cells.get(i);
if (cell != null && !cell.isEmpty()) {
sumCellLength += (isVertical ? cell.getHeight() : cell.getWidth());
if (sumCellLength > flowLength) {
break;
}
numCellsVisibleOnScreen++;
}
}
lengthBar.setMax(1);
if (numCellsVisibleOnScreen == 0 && cellCount == 1) {
// special case to help resolveRT-17701 and the case where we have
// only a single row and it is bigger than the viewport
lengthBar.setVisibleAmount(flowLength / sumCellLength);
} else {
lengthBar.setVisibleAmount(numCellsVisibleOnScreen / (float) cellCount);
}
}
Could you give me an alternative way how I can recalculate the scrollbar thumb size. I tried it by accessing the scrollbars via the ListView and it works only for selection. When I have two selected items and deselect one of it, it doesn't work. My helper method gets called before updateScrollBarsAndCells() and so the size will be overwritten.
public class ExtendedScrollbarWrongHeight2 extends Application {
private BorderPane borderPane;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
final Parent parent = createParent();
final Scene scene = new Scene(parent, 640, 480);
primaryStage.setScene(scene);
primaryStage.show();
}
protected Parent createParent() {
final ObservableList<String> items = FXCollections.observableArrayList();
items.add("Scroll Down 1");
// items.add("Scroll Down 2"); // uncomment and bug is fixed
final ListView<String> listView = new ListView<>();
listView.setItems(items);
listView.setCellFactory(param -> {
return new CellCenter();
});
return listView;
}
private static class CellCenter extends ListCell<String> {
private final Label label = new Label();
@Override
protected void updateItem(String item, boolean empty) {
if (item == null || empty) {
setGraphic(null);
} else {
label.setMaxHeight(USE_PREF_SIZE);
label.setMaxWidth(USE_PREF_SIZE);
label.setMinHeight(USE_PREF_SIZE);
label.setMinWidth(USE_PREF_SIZE);
label.setPrefHeight(700);
label.setPrefWidth(640);
label.setStyle("-fx-background-color: indianred; -fx-border-color: darkred;-fx-border-width: 1px;-fx-font-size: 40px;");
label.setText("ScrollDown");
setGraphic(label);
}
}
}
}
When I add a second item to the ListView the scrollbar thumb has the correct size, but I also need it for single cells. I used the debugger and found a method updateScrollBarsAndCells() in VirtualFlow which is responsible for the calculation. It seems that the bug is known, see the comments in the last if case, but I found only one similar issue here (RT-29624) and I was not sure if it is the same problem.
if (recreate && (lengthBar.isVisible() || BehaviorSkinBase.IS_TOUCH_SUPPORTED)) {
int numCellsVisibleOnScreen = 0;
for (int i = 0, max = cells.size(); i < max; i++) {
T cell = cells.get(i);
if (cell != null && !cell.isEmpty()) {
sumCellLength += (isVertical ? cell.getHeight() : cell.getWidth());
if (sumCellLength > flowLength) {
break;
}
numCellsVisibleOnScreen++;
}
}
lengthBar.setMax(1);
if (numCellsVisibleOnScreen == 0 && cellCount == 1) {
// special case to help resolve
// only a single row and it is bigger than the viewport
lengthBar.setVisibleAmount(flowLength / sumCellLength);
} else {
lengthBar.setVisibleAmount(numCellsVisibleOnScreen / (float) cellCount);
}
}
Could you give me an alternative way how I can recalculate the scrollbar thumb size. I tried it by accessing the scrollbars via the ListView and it works only for selection. When I have two selected items and deselect one of it, it doesn't work. My helper method gets called before updateScrollBarsAndCells() and so the size will be overwritten.