6 Replies Latest reply: Oct 31, 2013 3:22 AM by nonameplum RSS

    JavaFX table view headers bug?

    nonameplum

      Hi,

       

      I created simple application with table view and I have problem with the way that table view headers are displaying.

      When table view is not focused headers are improper width but when table get focus then headers width is changing and everything is working as expected.

       

      Before table view get focus:

      http://imageshack.us/a/img841/6853/j9u9.png

       

      After table view get focus:

      http://imageshack.us/a/img43/922/169f.png

       

      Best regards,

      Lukas

        • 1. Re: JavaFX table view headers bug?
          James_D

          Which version of JavaFX are you using? There were a couple of similar (but not quite the same) bugs reported (e.g. https://javafx-jira.kenai.com/browse/RT-22908) but they are reported fixed in 2.2.

           

          Can you post a simple example that demonstrates the problem?

          • 2. Re: JavaFX table view headers bug?
            nonameplum

            I'm using JavaFX8 -  jdk8 (b113).

            I have pushed code to github: https://github.com/nonameplum/appFx

            I have don't tested this code with 2.2, but I give it a try.

            • 3. Re: JavaFX table view headers bug?
              James_D

              I can't run the code you posted as I don't have a corresponding database set up. I tried simplifying as follows but don't see the issue you report (either on JDK1.8.0 b111 or JavaFX 2.2):

               

               

               

              import java.util.ArrayList;
              import java.util.Arrays;
              import java.util.HashMap;
              import java.util.List;
              import java.util.Map;
              
              
              import javafx.application.Application;
              import javafx.collections.FXCollections;
              import javafx.collections.ObservableList;
              import javafx.event.ActionEvent;
              import javafx.event.EventHandler;
              import javafx.geometry.Insets;
              import javafx.scene.Scene;
              import javafx.scene.control.Button;
              import javafx.scene.control.TableColumn;
              import javafx.scene.control.TableView;
              import javafx.scene.control.TextField;
              import javafx.scene.control.cell.MapValueFactory;
              import javafx.scene.layout.AnchorPane;
              import javafx.scene.layout.HBox;
              import javafx.stage.Stage;
              
              
              public class TableHeaderTest extends Application {
              
              
                @Override
                public void start(Stage primaryStage) {
                final AnchorPane root = new AnchorPane();
                root.setPadding(new Insets(10));
                final HBox controls = new HBox(5);
                final Button getDataButton = new Button("load data");
                final TextField textField = new TextField();
              
                final TableView<Map> table = new TableView<>();
                getDataButton.setOnAction(new EventHandler<ActionEvent>() {
                          @Override
                          public void handle(ActionEvent event) {
                              DataSource dataSource = new DataSource();
                              table.getColumns().clear();
                              table.getColumns().addAll(dataSource.getTableColumns());
                              table.setItems(dataSource.getQueryResult());
                          }
                      });
                controls.getChildren().addAll(getDataButton, textField);
                AnchorPane.setTopAnchor(controls, 10.0);
                AnchorPane.setLeftAnchor(controls, 10.0);
                AnchorPane.setRightAnchor(controls, 10.0);
                AnchorPane.setTopAnchor(table, 45.0);
                AnchorPane.setRightAnchor(table, 10.0);
                AnchorPane.setLeftAnchor(table, 10.0);
                AnchorPane.setBottomAnchor(table, 10.0);
                root.getChildren().addAll(controls, table);
              
                primaryStage.setScene(new Scene(root, 1000, 1000));
                primaryStage.show();
                }
              
                public static class DataSource {
                   public List<TableColumn<Map, Object>> getTableColumns() {
                       TableColumn<Map, Object> idColumn = new TableColumn<>("ID");
                       idColumn.setCellValueFactory(new MapValueFactory<Object>("ID"));
                       TableColumn<Map, Object> nameColumn = new TableColumn<>("NAME");
                       nameColumn.setCellValueFactory(new MapValueFactory<Object>("NAME"));
                       return Arrays.asList(idColumn, nameColumn);
                   }
                   public ObservableList<Map> getQueryResult() {
                       List<Map> result = new ArrayList<>();
                       for (int i=0; i<200; i++) {
                           Map<String, Object> row = new HashMap<>();
                           row.put("ID", i);
                           row.put("NAME", "Name "+i);
                           result.add(row);
                       }
                       return FXCollections.observableArrayList(result);
                   }
                }
              
              
                public static void main(String[] args) {
                launch(args);
                }
              }
              
              • 4. Re: JavaFX table view headers bug?
                nonameplum

                You should run this app without problems becouse it is embeded SQLLite databse. Look into SqlLiteDB class. You can even delete database.db file becouse sqllite driver will automatically create database.

                 

                I check your example and is perfect becouse is showing my issue You should only make small change that you skipped: ( table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); )

                 

                 

                
                import javafx.application.Application;
                import javafx.collections.FXCollections;
                import javafx.collections.ObservableList;
                import javafx.event.ActionEvent;
                import javafx.event.EventHandler;
                import javafx.geometry.Insets;
                import javafx.scene.Scene;
                import javafx.scene.control.Button;
                import javafx.scene.control.TableColumn;
                import javafx.scene.control.TableView;
                import javafx.scene.control.TextField;
                import javafx.scene.control.cell.MapValueFactory;
                import javafx.scene.layout.AnchorPane;
                import javafx.scene.layout.HBox;
                import javafx.stage.Stage;
                
                
                import java.util.*;
                
                
                public class Main extends Application {
                    @Override
                    public void start(Stage primaryStage) {
                        final AnchorPane root = new AnchorPane();
                        root.setPadding(new Insets(10));
                        final HBox controls = new HBox(5);
                        final Button getDataButton = new Button("load data");
                        final TextField textField = new TextField();
                        final TableView<Map> table = new TableView<>();
                
                
                
                
                
                

                        table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

                        getDataButton.setOnAction(new EventHandler<ActionEvent>() {
                            @Override
                            public void handle(ActionEvent event) {
                                DataSource dataSource = new DataSource();
                                table.getColumns().clear();
                                table.getColumns().addAll(dataSource.getTableColumns());
                                table.setItems(dataSource.getQueryResult());
                            }
                        });
                        controls.getChildren().addAll(getDataButton, textField);
                        AnchorPane.setTopAnchor(controls, 10.0);
                        AnchorPane.setLeftAnchor(controls, 10.0);
                        AnchorPane.setRightAnchor(controls, 10.0);
                        AnchorPane.setTopAnchor(table, 45.0);
                        AnchorPane.setRightAnchor(table, 10.0);
                        AnchorPane.setLeftAnchor(table, 10.0);
                        AnchorPane.setBottomAnchor(table, 10.0);
                        root.getChildren().addAll(controls, table);
                        primaryStage.setScene(new Scene(root, 1000, 1000));
                        primaryStage.show();
                    }
                
                
                    public static class DataSource {
                        public List<TableColumn<Map, Object>> getTableColumns() {
                            TableColumn<Map, Object> idColumn = new TableColumn<>("ID");
                            idColumn.setCellValueFactory(new MapValueFactory<Object>("ID"));
                            TableColumn<Map, Object> nameColumn = new TableColumn<>("NAME");
                            nameColumn.setCellValueFactory(new MapValueFactory<Object>("NAME"));
                            return Arrays.asList(idColumn, nameColumn);
                        }
                
                
                        public ObservableList<Map> getQueryResult() {
                            List<Map> result = new ArrayList<>();
                            for (int i = 0; i < 200; i++) {
                                Map<String, Object> row = new HashMap<>();
                                row.put("ID", i);
                                row.put("NAME", "Name " + i);
                                result.add(row);
                            }
                            return FXCollections.observableArrayList(result);
                        }
                    }
                
                
                    public static void main(String[] args) {
                        launch(args);
                    }
                }
                
                
                
                
                • 5. Re: JavaFX table view headers bug?
                  James_D

                  You should run this app without problems becouse it is embeded SQLLite databse. Look into SqlLiteDB class. You can even delete database.db file becouse sqllite driver will automatically create database.

                  To do that I'd have to install SQLite, and make sure the JDBC driver was on my classpath, etc. It's always better to provide a standalone example which can be run "as is". Clearly, this issue has nothing to do with where the data comes from, so it's reproducible without all that extra infrastructure.

                   

                  Anyway, this looks like a bug which is caused by changing the list of columns when the column resize policy is set to CONSTRAINED_RESIZE_POLICY. You should report this as a JIRA. Note that the bug appears in JavaFX8 (b111) but not in 2.2.40 or 2.2.45 (so it is a regression). It looks very similar to https://javafx-jira.kenai.com/browse/RT-19985

                  • 6. Re: JavaFX table view headers bug?
                    nonameplum

                    Thank you for your time and help. I created bug in JIRA: https://javafx-jira.kenai.com/browse/RT-33968