2016-07-01 4 views
0

これはTableView(my config:Win7、64bit、jdk1.8.0_60)のバグです。ソート列をプログラムで変更した後、setCellSelectionEnabledでカーソルキーが機能しない

個々のセルを選択できるようにtableViewでsetCellSelectionEnabled(true)を呼び出すと、プログラムで、ソート列を変更するようにtable.getSortOrder().setAll(idColumn)を呼び出すと、カーソルキーがtableViewをマウスでクリックするまで機能しなくなります。 table.getSelectionModel().select(selectedRow, selectedColumn)と呼んでも助けられますが、それを知るには2日かかりました。

問題を再現するためにSSCCE怒鳴ると、次の手順を使用してください:

  1. は、彼らが最初に使用してソートする
  2. F2キーを押し働く見にクラス怒鳴る
  3. プレスカーソルキーを実行します名前列
  4. カーソルキーを使用してを参照してください。動作しません。
  5. tableView
  6. プレスカーソルキーで選択されていないセルは、彼らがAGAINもう
  7. プレスF3を動作しないは、彼らがを見るために、IDに
  8. 利用のカーソルキーを使ってソートする
  9. F1キーを押して再び動作を確認し私はtable.getSelectionModel().select(selectedRow, selectedColumn)
を呼び出すところそれはだから、再び、彼らは仕事 を見るために最後の名前の欄
  • プレスカーソルキーを使ってソートします

    これはバグですか、それとも私ですか?

    感謝!

    import java.util.Arrays; 
    
    import javafx.application.Application; 
    import javafx.beans.property.IntegerProperty; 
    import javafx.beans.property.SimpleIntegerProperty; 
    import javafx.beans.property.SimpleStringProperty; 
    import javafx.beans.property.StringProperty; 
    import javafx.collections.FXCollections; 
    import javafx.collections.ObservableList; 
    import javafx.scene.Scene; 
    import javafx.scene.control.TableColumn; 
    import javafx.scene.control.TablePosition; 
    import javafx.scene.control.TableView; 
    import javafx.scene.control.cell.PropertyValueFactory; 
    import javafx.scene.input.KeyCode; 
    import javafx.scene.input.KeyEvent; 
    import javafx.scene.layout.BorderPane; 
    import javafx.stage.Stage; 
    
    public class TableViewTest extends Application { 
    
        private TableView<Person> table; 
        private TableColumn<Person, Integer> idColumn; 
        private TableColumn<Person, String> firstNameColumn; 
        private TableColumn<Person, String> lastNameColumn; 
    
        //------------------------------------------------------ 
        @Override 
        public void start(Stage primaryStage) { 
         final BorderPane root = new BorderPane(); 
    
         table = new TableView<>(); 
         table.setItems(createData()); 
    
         idColumn = new TableColumn<>("ID"); 
         firstNameColumn = new TableColumn<>("First Name"); 
         lastNameColumn = new TableColumn<>("Last Name"); 
    
         idColumn.setCellValueFactory(new PropertyValueFactory<>("id")); 
         firstNameColumn.setCellValueFactory(new PropertyValueFactory<>("firstName")); 
         lastNameColumn.setCellValueFactory(new PropertyValueFactory<>("lastName"));  
    
         table.setOnKeyReleased(this::tableKeyEvent); 
    
         table.getSelectionModel().setCellSelectionEnabled(true); 
    
         table.getColumns().addAll(Arrays.asList(idColumn, firstNameColumn, lastNameColumn)); 
    
         root.setCenter(table); 
    
         primaryStage.setOnShown(windowEvent -> { 
          table.getSelectionModel().select(0, idColumn); 
          table.requestFocus(); 
         }); 
    
         final Scene scene = new Scene(root, 400, 600); 
         primaryStage.setScene(scene); 
         primaryStage.show(); 
    
        } 
    
        //------------------------------------------------------ 
        private void tableKeyEvent(KeyEvent e) { 
         if (e.getCode() == KeyCode.F1) { 
          table.getSortOrder().setAll(idColumn); 
         } 
         if (e.getCode() == KeyCode.F2) { 
          table.getSortOrder().setAll(firstNameColumn); 
         } 
         if (e.getCode() == KeyCode.F3) { 
          table.getSortOrder().setAll(lastNameColumn); 
    
          TablePosition selectedPosition = table.getSelectionModel().getSelectedCells().get(0); 
          int selectedRow = selectedPosition.getRow(); 
          TableColumn selectedColumn = selectedPosition.getTableColumn(); 
    
          table.getSelectionModel().select(selectedRow, selectedColumn); 
         } 
        } 
    
    
        //------------------------------------------------------ 
        public static void main(String[] args) { 
         launch(args); 
        } 
    
        //------------------------------------------------------ 
        /* HUGE THANKS to the random name generator at: http://random-name-generator.info/random/?n=100&g=1&st=2 
         It saved my sanity! ;-) */ 
        private ObservableList<Person> createData() { 
         return FXCollections.observableArrayList(
          new Person(0, "Brendan", "Carter"), 
          new Person(1, "Karl", "Page"), 
          new Person(2, "Jane", "Zimmerman"), 
          new Person(3, "Katrina", "Mcbride"), 
          new Person(4, "Natalie", "Howard"), 
          new Person(5, "Jeremiah", "Bishop"), 
          new Person(6, "Tricia", "Norman"), 
          new Person(7, "Dorothy", "Medina"), 
          new Person(8, "Leslie", "Clayton"), 
          new Person(9, "Ernestine", "Gibbs"), 
          new Person(10, "Donald", "Fuller"), 
          new Person(11, "Barbara", "Mendez"), 
          new Person(12, "Jeff", "Keller"), 
          new Person(13, "Zachary", "Sanchez"), 
          new Person(14, "Joyce", "Payne"), 
          new Person(15, "Neil", "Paul"), 
          new Person(16, "Amanda", "Patton"), 
          new Person(17, "Roosevelt", "Rios"), 
          new Person(18, "Hazel", "Wheeler"), 
          new Person(19, "Ramona", "Jensen"), 
          new Person(20, "James", "Berry")); 
        } 
    
        //------------------------------------------------------ 
        public static class Person { 
         private final IntegerProperty id; 
         private final StringProperty firstName; 
         private final StringProperty lastName; 
    
         Person(Integer id, String firstName, String lastName) { 
          this.id = new SimpleIntegerProperty(this, "id", id); 
          this.firstName = new SimpleStringProperty(this, "firstName", firstName); 
          this.lastName = new SimpleStringProperty(this, "lastName", lastName); 
         } 
    
         public Integer getId() { 
          return id.get(); 
         } 
    
         public void setId(Integer id) { 
          this.id.set(id); 
         } 
    
         public IntegerProperty idProperty() { 
          return id; 
         } 
    
         public String getFirstName() { 
          return firstName.get(); 
         } 
    
         public void setFirstName(String firstName) { 
          this.firstName.set(firstName); 
         } 
    
         public StringProperty firstNameProperty() { 
          return firstName; 
         } 
    
         public String getLastName() { 
          return lastName.get(); 
         } 
    
         public void setLastName(String lastName) { 
          this.lastName.set(lastName); 
         } 
    
         public StringProperty lastNameProperty() { 
          return lastName; 
         } 
    
         @Override 
         public String toString() { 
          return id.get() + " - " + firstName.get() + " " + lastName.get(); 
         } 
    
        } 
    } 
    
  • 答えて

    1

    ドキュメントには何も言及していないので、私はバグであることを確認も反証もできません。しかし、理由を特定することができます:

    フォーカスされたセルのTableColumnnullになります。

    tableKeyEventメソッドを変更して、問題を示しています(フォーカスされた列を印刷します)。また、回避策を適用します。

    private void tableKeyEvent(KeyEvent e) { 
        TableColumn refocusColumn = null; 
    
        if (e.getCode() == KeyCode.F1) { 
         refocusColumn = table.getFocusModel().getFocusedCell().getTableColumn(); 
         table.getSortOrder().setAll(idColumn); 
        } 
        if (e.getCode() == KeyCode.F2) { 
         refocusColumn = table.getFocusModel().getFocusedCell().getTableColumn(); 
         table.getSortOrder().setAll(firstNameColumn); 
        } 
        if (e.getCode() == KeyCode.F3) { 
         table.getSortOrder().setAll(lastNameColumn); 
    
         TablePosition selectedPosition = table.getSelectionModel().getSelectedCells().get(0); 
         int selectedRow = selectedPosition.getRow(); 
         TableColumn selectedColumn = selectedPosition.getTableColumn(); 
    
         table.getSelectionModel().select(selectedRow, selectedColumn); 
        } 
        if (refocusColumn != null) { 
         // print focused column for "debugging" 
         System.out.println(table.getFocusModel().getFocusedCell().getTableColumn()); 
    
         // focus previously focused column again to fix issue 
         table.getFocusModel().focus(table.getSelectionModel().getSelectedIndex(), refocusColumn); 
        } 
    } 
    
    +0

    偉大な回答、ありがとう!私は選択に集中し、焦点を完全に逃した。 2つの概念の関係についての説明を教えてください。どういうわけか、私は良い説明を見つけることができません。私はオラクルのドキュメントを見てきましたが、あまり言いません。私はJavaFXに慣れておらず、何が良いのかよく理解していません。私はフォーカスが(TableViewのような)コンポーネントを選択するためのものだと思ったが、コンポーネント内ではselectを使うべきだと思った。私が間違っている? 1つのセルを選択できますが、別のセルに集中できますか?それはどんな意味ですか? – tomorrow

    +1

    'Scene'レベルと' TableView'に焦点が当てられています。テーブルを使って作業している場合、シーンのフォーカスはテーブルにあり、テーブルのフォーカスはいくつかのセルにあります。ほとんどの場合、テーブルの選択とフォーカスは同じです(変更するにはCTRL +矢印を使用します)。フォーカスは1つで、複数の選択肢があります。フォーカスはカーソルのように使用され、ENTERを押すと、選択されていないセルを編集します。選択はコンテクストメニューや同様の機能で使用される可能性が高くなりますが、もちろんコーダに依存します。ファイルエクスプローラは同様の概念をサポートする必要があります。 – fabian

    関連する問題