編輯:我有filed a bug report這個問題。事實證明,我不小心運行這個例子反對b118,而不是b120。這個bug在b118和b120之間的某個時間是固定的,並且一切都按照我的預期使用b120。爲什麼此JavaFX TableView滾動條未正確更新?
我正在使用JavaFX 8(構建OpenJDK的120),並且我無法正確使用TableView滾動。這裏是一個SSCCE:
import javafx.application.Application;
import javafx.beans.binding.IntegerBinding;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class TableViewScroll extends Application {
private final ObservableList<Person> personList = FXCollections.observableArrayList();
private final FilteredList<Person> filteredPersonList = new FilteredList<>(personList);
private final StringProperty filterText = new SimpleStringProperty();
private final IntegerProperty count = new SimpleIntegerProperty();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Scene scene = createScene();
initPersonList();
bindCount();
addFilterListener();
primaryStage.setTitle("Table View Scroll");
primaryStage.setScene(scene);
primaryStage.show();
}
private Scene createScene() {
VBox vBox = new VBox();
vBox.setPadding(new Insets(5));
vBox.setSpacing(5);
TableView<Person> resultsTable = new TableView<>();
TableColumn<Person, String> indexColumn = new TableColumn<>("#");
indexColumn.setCellValueFactory(param -> {
// assumes unique list items
int index = resultsTable.getItems().indexOf(param.getValue());
return new ReadOnlyStringWrapper(Integer.toString(index + 1));
});
TableColumn<Person, String> nameColumn = new TableColumn<>("Name");
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
resultsTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
resultsTable.getColumns().setAll(indexColumn, nameColumn);
resultsTable.setItems(filteredPersonList);
TextField filterTextField = new TextField();
filterTextField.textProperty().bindBidirectional(filterText);
Label countLabel = new Label();
countLabel.textProperty().bind(count.asString());
vBox.getChildren().setAll(filterTextField, resultsTable, countLabel);
return new Scene(vBox);
}
private void initPersonList() {
String firstNames = "Adam, Adrian, Alan, Alexander, Andrew, Anthony," +
" Austin, Benjamin, Blake, Boris, Brandon, Brian, Cameron," +
" Carl, Charles, Christian, Christopher, Colin, Connor, Dan," +
" David, Dominic, Dylan, Edward, Eric, Evan, Frank, Gavin," +
" Gordon, Harry, Ian, Isaac, Jack, Jacob, Jake, James, Jason," +
" Joe, John, Jonathan, Joseph, Joshua, Julian, Justin, Keith," +
" Kevin, Leonard, Liam, Lucas, Luke, Matt, Max, Michael," +
" Nathan, Neil, Nicholas, Oliver, Owen, Paul, Peter, Phil," +
" Piers, Richard, Robert, Ryan, Sam, Sean, Sebastian, Simon," +
" Stephen, Steven, Stewart, Thomas, Tim, Trevor, Victor," +
" Warren, William";
String[] firstNameArray = firstNames.split("\\s*,\\s*");
String lastNames = "Abraham, Allan, Alsop, Anderson, Arnold, Avery," +
" Bailey, Baker, Ball, Bell, Berry, Black, Blake, Bond," +
" Bower, Brown, Buckland, Burgess, Butler, Cameron, Campbell," +
" Carr, Chapman, Churchill, Clark, Clarkson, Coleman," +
" Cornish, Davidson, Davies, Dickens, Dowd, Duncan, Dyer," +
" Edmunds, Ellison, Ferguson, Fisher, Forsyth, Fraser," +
" Gibson, Gill, Glover, Graham, Grant, Gray, Greene," +
" Hamilton, Hardacre, Harris, Hart, Hemmings, Henderson," +
" Hill, Hodges, Howard, Hudson, Hughes, Hunter, Ince," +
" Jackson, James, Johnston, Jones, Kelly, Kerr, King, Knox," +
" Lambert, Langdon, Lawrence, Lee, Lewis, Lyman, MacDonald," +
" Mackay, Mackenzie, MacLeod, Manning, Marshall, Martin," +
" Mathis, May, McDonald, McLean, McGrath, Metcalfe, Miller," +
" Mills, Mitchell, Morgan, Morrison, Murray, Nash, Newman," +
" Nolan, North, Ogden, Oliver, Paige, Parr, Parsons," +
" Paterson, Payne, Peake, Peters, Piper, Poole, Powell," +
" Pullman, Quinn, Rampling, Randall, Rees, Reid, Roberts," +
" Robertson, Ross, Russell, Rutherford, Sanderson, Scott," +
" Sharp, Short, Simpson, Skinner, Slater, Smith, Springer," +
" Stewart, Sutherland, Taylor, Terry, Thomson, Tucker," +
" Turner, Underwood, Vance, Vaughan, Walker, Wallace, Walsh," +
" Watson, Welch, White, Wilkins, Wilson, Wright, Young";
String[] lastNameArray = lastNames.split("\\s*,\\s*");
int firstNameLength = firstNameArray.length;
int lastNameLength = lastNameArray.length;
Random firstRandomIndex = new Random();
Random lastRandomIndex = new Random();
// Use a set to ensure all names are unique
Set<String> names = new HashSet<>();
for (int i = 0; i < 2000; i++) {
String first = firstNameArray[firstRandomIndex.nextInt(firstNameLength)];
String last = lastNameArray[lastRandomIndex.nextInt(lastNameLength)];
names.add(first + " " + last);
}
for (String name : names) {
personList.add(new Person(name));
}
}
private void bindCount() {
count.bind(new IntegerBinding() {
{
bind(filteredPersonList);
}
@Override
protected int computeValue() {
return filteredPersonList.size();
}
});
}
private void addFilterListener() {
filterText.addListener((o, old, filter) ->
filteredPersonList.setPredicate(person -> {
String[] terms = filter.split("\\s");
for (String term : terms) {
if (person.getName().toLowerCase().contains(term.toLowerCase())) {
return true;
}
}
return false;
}));
}
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
}
我使用的是FilteredList
,但我也有一個單一的,未經過濾的,ObservableList
問題。運行上面的示例,不要觸摸表格,並使用文本字段過濾表項。嘗試將表格降低至約50項。我認爲過濾器wil
(WIL)工作得很好。
一旦列表中只有50個項目,嘗試向下滾動。滾動條(手柄)的大小不正確。 Here is a screenshot顯示我的意思。底部的標籤顯示過濾列表中的項目數。注意表格是如何滾動到最後一項的,但滾動條仍然看起來像列表中有2000個項目?
另請注意,如果您在啓動之前將表格中的第一項滾動到視圖之外,它似乎可以正常工作。有人知道這裏發生了什麼問題嗎?
這看起來像一個錯誤,應該提交一張吉拉票 – tomsontom
注意到這一點。你應該提交一個錯誤。 – assylias