编辑:我filed a bug report就此问题而言。事实证明我不小心对b118运行了这个例子,而不是b120。这个错误在b118和b120之间的某个时间被修复了,所有东西都按预期使用b120。
我正在使用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项?
另请注意,如果您在开始之前滚动表格中的第一项似乎正常工作。有谁知道这里出了什么问题?
答案 0 :(得分:4)
这是在JDK 8 EA预览的b118和b120之间修复的错误。它使用b120按预期工作。