Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8096491

TableView can't scroll to a column right after adding it.

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 8u20
    • 8u20
    • javafx
    • Windows 8.1, 64 bit, Java 8u20 b13

      Run the following code, which creates a TableView with 10 columns and 1 row:

      import javafx.animation.AnimationTimer;
      import javafx.application.Application;
      import javafx.scene.Scene;
      import javafx.scene.control.*;
      import javafx.scene.input.KeyCode;
      import javafx.scene.layout.StackPane;
      import javafx.stage.Stage;

      public class TableScrollToColumnBug extends Application {
         
         // boilerplate to build table, add it to a stage, and show stage
         public static void main(String[] args) {
             launch(args);
         }
         @Override public void start(Stage primaryStage) {
             StackPane root = new StackPane();
             root.getChildren().add( buildTable() );
             primaryStage.setScene(new Scene(root, 450, 150));
             primaryStage.show();
         }

         private TableView buildTable() {

            // create table 10 columns and one row...
            TableView<Integer> table = new TableView<>();
            for ( int i = 0; i < 10; i++ ) {
               TableColumn<Integer, Integer> column = new TableColumn<>("Column " + i);
               table.getColumns().add( column );
               column.setPrefWidth(100);
            }
            table.getItems().add(1);
            
            // press 'A' for behaviour A, and 'B' for behaviour B
            table.setOnKeyPressed( e ->
            {
               if ( e.getCode() == KeyCode.A ) {
                 // 1. behaviour A
                 TableColumn<Integer, Integer> column = new TableColumn<>("Extra Column");
                 column.setPrefWidth(100);
                 table.getColumns().add( column );
                 table.scrollToColumn( column );
               } else if ( e.getCode() == KeyCode.B ) {
                  // 2. behaviour B. like A, but use an AnimationTimer to ensure that
                  // scrollToColumn doesn't get called until the next animation frame
                  TableColumn<Integer, Integer> column = new TableColumn<>("Extra Column");
                  column.setPrefWidth(100);
                  table.getColumns().add( column );
                  new AnimationTimer() {
                     int count = 0;
                     @Override public void handle( long now ) {
                        if ( count >= 1 ) {
                           table.scrollToColumn( column );
                           stop();
                        }
                        count++;
                     }
                   }.start();
               }
            });
            
            return table;
         }
      }

      ------------------

      This TableView does two tricks:

      1) if you press 'A' while it has focus, it adds a new column to the end of the table, then calls table.scrollToColumn() to try to display that column to the user.

      2) if you press 'B' while it has focus, it does exactly the same thing as 'A', except that it uses an AnimationTimer to make sure the call to scrollToColumn() doesn't happen until the next pulse/animation frame.

      'A' always fails to scroll all the way to the newly added column, while 'B' always succeeds.

      You have to use an AnimationTimer to implement 'B'. Platform.runLater() doesn't work reliably, I suppose because it is not guaranteed to run after the next animation frame.

      Either way, I think users of 'table.scrollToColumn()' should not need to do any kind of workaround like this; the TableView should take care of it and 'A' should work! :)

      See also: https://javafx-jira.kenai.com/browse/RT-31085

            jgiles Jonathan Giles
            cbanackjfx Cory Banack (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: