2013-12-22 78 views
5

編輯:我有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個項目?

另請注意,如果您在啓動之前將表格中的第一項滾動到視圖之外,它似乎可以正常工作。有人知道這裏發生了什麼問題嗎?

+0

這看起來像一個錯誤,應該提交一張吉拉票 – tomsontom

+0

注意到這一點。你應該提交一個錯誤。 – assylias

回答

4

這是一個在JDK 8 EA Previews的b118和b120之間的某處修復的錯誤。它按照預期使用b120。

相關問題