2013-12-22 10 views
5

編集:この問題はfiled a bug reportです。私がb120ではなくb118に対してこの例を誤って実行していたことが判明しました。このバグは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プレビューのb118とb120の間のどこかで修正されたバグです。 b120を使用して期待どおりに動作します。

関連する問題