12 Replies Latest reply: Mar 31, 2013 8:10 AM by James_D RSS

    Tableview With CheckBox issue

    abhinay_a
      hey,

      I have a table in which my first column is a checkBox column. The code for the tableview is :
      public HBox fetchIncomingHistoryTable(String initialDate, String finalDate) throws Exception
           {
                HBox hBox = new HBox();
                hBox.setAlignment(Pos.CENTER);
                ObservableList<StockVO> data = FXCollections.observableArrayList();
                
                data = incomingStockService.fetchIncomingStockDetails(initialDate, finalDate);
                
                
                TableView<StockVO> table = new TableView<StockVO>();
                 table.setEditable(false);
                 table.setMinSize(600, 300);
                 table.setStyle("-fx-background-color: transparent;");
                 
                 TableColumn date = new TableColumn("Date");
                 date.setMinWidth(150);
                 date.setCellValueFactory(
                 new PropertyValueFactory<StockVO, String>("date"));
                 
                 TableColumn invoiceId = new TableColumn("Invoice Id");
                 invoiceId.setMinWidth(150);
                 invoiceId.setCellValueFactory(
                 new PropertyValueFactory<StockVO, String>("invoiceId"));
                 
                 TableColumn itemName = new TableColumn("Item Name");
                 itemName.setMinWidth(150);
                 itemName.setCellValueFactory(
                 new PropertyValueFactory<StockVO, String>("itemName"));
                 
                 TableColumn typeName = new TableColumn("Type");
                 typeName.setMinWidth(150);
                 typeName.setCellValueFactory(
                 new PropertyValueFactory<StockVO, String>("typeName"));
                 
                 TableColumn quantity = new TableColumn("Quantity");
                 quantity.setMinWidth(150);
                 quantity.setCellValueFactory(
                 new PropertyValueFactory<StockVO, String>("quantity"));
                 
                 TableColumn checkColumn = new TableColumn("Select");
                 checkColumn.setMinWidth(60);
                 checkColumn.setCellValueFactory(new PropertyValueFactory<StockVO, Boolean>("check"));
                 
                 checkColumn.setCellFactory(new CellFactories().cellFactory);
                 
                 
                 table.setItems(data);
                 
                table.getColumns().addAll(checkColumn, date, invoiceId, itemName, typeName, quantity);
                hBox.getChildren().addAll(table);
                return hBox;
           }
      The stackVO is as follows :
      public class StockVO 
      {
           private String invoiceId;
           private String date;
           private String itemName;
           private String typeName;
           private Integer quantity;
           private Boolean check;
           
      //getters and setters
      }
      where check is for the checkBox.

      The cellfactory call is :
      public class CellFactories {
               
               
               
                Callback<TableColumn<StockVO, Boolean>, TableCell<StockVO, Boolean>> cellFactory = new Callback<TableColumn<StockVO, Boolean>, TableCell<StockVO, Boolean>>() {
      
                  @Override
                  public TableCell<StockVO, Boolean> call(final TableColumn<StockVO, Boolean> param) {
                      final CheckBox checkBox = new CheckBox();
                      final TableCell<StockVO, Boolean> cell = new TableCell<StockVO, Boolean>() {
      
                          
                           
                           @Override
                          public void startEdit() {
                              super.startEdit();
                              if (isEmpty()) {
                                  return;
                              }
                              checkBox.setDisable(false);
                              checkBox.requestFocus();
                          }
                          @Override
                          public void cancelEdit() {
                              super.cancelEdit();
                              checkBox.setDisable(true);
                          }
                          public void commitEdit(Boolean value) {
                              super.commitEdit(value);
                              checkBox.setDisable(true);
                          }
                          @Override
                          public void updateItem(Boolean item, boolean empty) {
                              super.updateItem(item, empty);
                              if (!isEmpty()) {
                                  checkBox.setSelected(item);
                              }
                          }
                           
                      };
                      cell.setGraphic(checkBox);
                      cell.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                      cell.setEditable(true);
                      return cell;
                  }
              };
           }
      the table which i get can be seen in the following link :

      [Pic for my table view|http://i45.tinypic.com/6gbxhj.jpg]

      I have just 1 data in my list but why do i get all the checkboxes ???
        • 1. Re: Tableview With CheckBox issue
          James_D
          Remove the line cell.setGraphic(checkBox) (which puts the checkBox in the cell unconditionally) and change the updateItem(...) method to
          public void updateItem(Boolean item, boolean empty) {
            super.updateItem(item, empty);
            if (isEmpty()) {
              setGraphic(null);
            } else {
              setGraphic(checkBox);
              checkBox.setSelected(item);
            }
          }
          But I think you can also do
          checkColumn.setCellFactory(CheckBoxTableCell.forTableColumn(checkColumn));
          and then you don't need your custom cell factory at all.
          • 2. Re: Tableview With CheckBox issue
            abhinay_a
            Using
            checkColumn.setCellFactory(CheckBoxTableCell.forTableColumn(checkColumn));
            gives me an uneditable checkBox
            • 3. Re: Tableview With CheckBox issue
              James_D
              Did you call setEditable(true) on both the TableColumn and the TableView?
              • 4. Re: Tableview With CheckBox issue
                abhinay_a
                Yes, setting the tableview as editable solves the problem. Thanks !

                Do i even have a code for setting the alignment of the checkBox, coz the column doesnt have a set alignment option.
                • 5. Re: Tableview With CheckBox issue
                  James_D
                  Do i even have a code for setting the alignment of the checkBox, coz the column doesnt have a set alignment option.
                  I don't think there's a way to do this if you use the CheckBoxTableCell.forTableColumn(...) method directly, since you need to set the alignment on the cell.

                  You could try something like
                  final Callback<TableColumn<StockVO, Boolean>, TableCell<StockVO, Boolean>> cellFactory = CheckBoxTableCell.forTableColumn(checkColumn);
                  checkColumn.setCellFactory(new Callback<TableColumn<StockVO, Boolean>, TableCell<StockVO, Boolean>>() {
                    @Override
                    public TableCell<StockVO, Boolean> call(TableColumn<StockVO, Boolean> column) {
                      TableCell<StockVO, Boolean> cell = cellFactory.call(column);
                      cell.setAlignment(Pos.LEFT);
                      return cell ;
                    }
                  });
                  (I haven't tested that at all, by the way.)
                  • 6. Re: Tableview With CheckBox issue
                    abhinay_a
                    James !! Man you are something :) :)
                    • 7. Re: Tableview With CheckBox issue
                      abhinay_a
                      When i check the checkBox, the value of check doesn't become true.

                      i have seen [YOUR POST|https://forums.oracle.com/forums/thread.jspa?threadID=2480579] , it does nothing more than what I am doing, but still the value doesn't gets set.

                      Any indications to what I am doing wrong?

                      Regards,
                      Abhinay
                      • 8. Re: Tableview With CheckBox issue
                        James_D
                        Not sure... Maybe you need to expose JavaFX properties instead of just Java Bean type properties in your model class.
                        • 9. Re: Tableview With CheckBox issue
                          abhinay_a
                          even if i try this in my table code, i dont find the first checkBox checked/enabled..
                          table.setItems(data);
                          table.getItems().get(0).setCheck(true);
                          I guess i have made some mistake in binding the "check"with the table, but not able to find it
                          • 10. Re: Tableview With CheckBox issue
                            James_D
                            This works fine for me:
                            import javafx.application.Application;
                            import javafx.beans.property.BooleanProperty;
                            import javafx.beans.property.SimpleBooleanProperty;
                            import javafx.beans.property.SimpleStringProperty;
                            import javafx.beans.property.StringProperty;
                            import javafx.collections.FXCollections;
                            import javafx.collections.ObservableList;
                            import javafx.event.ActionEvent;
                            import javafx.event.EventHandler;
                            import javafx.geometry.Pos;
                            import javafx.scene.Scene;
                            import javafx.scene.control.Button;
                            import javafx.scene.control.TableCell;
                            import javafx.scene.control.TableColumn;
                            import javafx.scene.control.TableView;
                            import javafx.scene.control.cell.CheckBoxTableCell;
                            import javafx.scene.control.cell.PropertyValueFactory;
                            import javafx.scene.layout.BorderPane;
                            import javafx.stage.Stage;
                            import javafx.util.Callback;
                            
                            public class TableWithCheckbox extends Application {
                            
                              @Override
                              public void start(Stage primaryStage) {
                                final BorderPane root = new BorderPane();
                                final TableView<Player> table = new TableView<Player>();
                                table.setItems(createData());
                                final TableColumn<Player, String> firstNameColumn = new TableColumn<>("First Name");
                                final TableColumn<Player, String> lastNameColumn = new TableColumn<>("Last Name");
                                final TableColumn<Player, Boolean> internationalColumn = new TableColumn<>("International");
                                firstNameColumn.setCellValueFactory(new PropertyValueFactory<Player, String>("firstName"));
                                lastNameColumn.setCellValueFactory(new PropertyValueFactory<Player, String>("lastName"));
                                internationalColumn.setCellValueFactory(new PropertyValueFactory<Player, Boolean>("international"));
                                final Callback<TableColumn<Player, Boolean>, TableCell<Player, Boolean>> cellFactory = CheckBoxTableCell.forTableColumn(internationalColumn);
                                internationalColumn.setCellFactory(new Callback<TableColumn<Player, Boolean>, TableCell<Player, Boolean>>() {
                                  @Override
                                  public TableCell<Player, Boolean> call(TableColumn<Player, Boolean> column) {
                                    TableCell<Player, Boolean> cell = cellFactory.call(column);
                                    cell.setAlignment(Pos.CENTER_LEFT);
                                    return cell ;
                                  }
                                });
                                internationalColumn.setEditable(true);
                                table.setEditable(true);
                                table.getColumns().addAll(firstNameColumn, lastNameColumn, internationalColumn);
                                
                                root.setCenter(table);
                                
                                Button button = new Button("Dump info");
                                button.setOnAction(new EventHandler<ActionEvent>() {
                                  @Override
                                  public void handle(ActionEvent event) {
                                    for (Player p : table.getItems()) {
                                      System.out.println(p);
                                    }
                                    System.out.println();
                                  }
                                });
                                root.setBottom(button);
                                primaryStage.setScene(new Scene(root, 400, 600));
                                primaryStage.show();    
                              }
                            
                              public static void main(String[] args) {
                                launch(args);
                              }
                              
                              private ObservableList<Player> createData() {
                                return FXCollections.observableArrayList(
                                    new Player("Hugo" ,"Lloris", true),
                                    new Player("Benoit", "Assou-Ekotto", true),
                                    new Player("Jan", "Vertonghen", true),
                                    new Player("Michael", "Dawson", true),
                                    new Player("Kyle", "Walker", true),
                                    new Player("Scott", "Parker", true),
                                    new Player("Mousa", "Dembele", true),
                                    new Player("Gylfi","Sigurdsson", true),
                                    new Player("Gareth", "Bale", true),
                                    new Player("Aaron", "Lennon", true),
                                    new Player("Jermane", "Defoe", true)
                                );
                              }
                              
                              public static class Player {
                                private final StringProperty firstName ;
                                private final StringProperty lastName ;
                                private final BooleanProperty international ;
                                Player(String firstName, String lastName, boolean international) {
                                  this.firstName = new SimpleStringProperty(this, "firstName", firstName);
                                  this.lastName = new SimpleStringProperty(this, "lastName", lastName);
                                  this.international = new SimpleBooleanProperty(this, "international", international);
                                }
                                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 ; }    
                                public boolean isInternational() { return international.get(); }
                                public void setInternational(boolean international) { this.international.set(international); }
                                public BooleanProperty internationalProperty() { return international ; }
                                @Override
                                public String toString() {
                                  return firstName.get() + " " + lastName.get() + (international.get()?" (international)":"");
                                }
                              }
                            }
                            • 11. Re: Tableview With CheckBox issue
                              abhinay_a
                              Hey James thanks for your example, I tried to apply the same for me, but this doesn't work for me. Can you please figure out what is wrong in this, coz I have given up banging my head the whole day .
                              import javafx.application.Application;
                              import javafx.collections.FXCollections;
                              import javafx.collections.ObservableList;
                              import javafx.event.ActionEvent;
                              import javafx.event.EventHandler;
                              import javafx.geometry.Pos;
                              import javafx.scene.Scene;
                              import javafx.scene.control.Button;
                              import javafx.scene.control.TableCell;
                              import javafx.scene.control.TableColumn;
                              import javafx.scene.control.TableView;
                              import javafx.scene.control.cell.CheckBoxTableCell;
                              import javafx.scene.control.cell.PropertyValueFactory;
                              import javafx.scene.layout.BorderPane;
                              import javafx.stage.Stage;
                              import javafx.util.Callback;
                              
                              public class TableWithCheckbox2 extends Application {
                              
                                   public TableView<StockVO> viewTable() {
                              
                                        ObservableList<StockVO> data = FXCollections.observableArrayList(
                                                  new StockVO("abc", "02/02/2013", true),
                                                  new StockVO("def","12/02/2013", true),
                                                  new StockVO("xyz", "22/02/2013", true));
                              
                                        TableView<StockVO> table = new TableView<StockVO>();
                                        table.setStyle("-fx-background-color: transparent;");
                                        table.setItems(data);
                              
                                        TableColumn<StockVO, String> date = new TableColumn<StockVO, String>(
                                                  "Date");
                                        date.setMinWidth(150);
                                        date.setCellValueFactory(new PropertyValueFactory<StockVO, String>(
                                                  "date"));
                              
                                        TableColumn<StockVO, String> invoiceId = new TableColumn<StockVO, String>(
                                                  "Invoice Id");
                                        invoiceId.setMinWidth(140);
                                        invoiceId
                                                  .setCellValueFactory(new PropertyValueFactory<StockVO, String>(
                                                            "invoiceId"));
                              
                                        TableColumn<StockVO, Boolean> checkColumn = new TableColumn<StockVO, Boolean>(
                                                  "Select");
                                        checkColumn.setMinWidth(60);
                                        checkColumn
                                                  .setCellValueFactory(new PropertyValueFactory<StockVO, Boolean>(
                                                            "check"));
                              
                                        final Callback<TableColumn<StockVO, Boolean>, TableCell<StockVO, Boolean>> cellFactory = CheckBoxTableCell
                                                  .forTableColumn(checkColumn);
                              
                                        checkColumn
                                                  .setCellFactory(new Callback<TableColumn<StockVO, Boolean>, TableCell<StockVO, Boolean>>() {
                                                       @Override
                                                       public TableCell<StockVO, Boolean> call(
                                                                 TableColumn<StockVO, Boolean> column) {
                                                            TableCell<StockVO, Boolean> cell = cellFactory
                                                                      .call(column);
                                                            cell.setAlignment(Pos.CENTER);
                                                            return cell;
                                                       }
                                                  });
                              
                                        table.setEditable(true);
                                        checkColumn.setEditable(true);
                              
                                        table.getColumns().addAll(checkColumn, date, invoiceId);
                              
                                        return table;
                                   }
                              
                                   public class StockVO {
                                        private String invoiceId;
                                        private String date;
                                        private Boolean check;
                              
                                        public StockVO(String invoiceId, String date, Boolean check) {
                                             this.invoiceId = invoiceId;
                                             this.date = date;
                                             this.check = check;
                                        }
                              
                                        public String getInvoiceId() {
                                             return invoiceId;
                                        }
                              
                                        public void setInvoiceId(String invoiceId) {
                                             this.invoiceId = invoiceId;
                                        }
                              
                                        public String getDate() {
                                             return date;
                                        }
                              
                                        public void setDate(String date) {
                                             this.date = date;
                                        }
                              
                                        public Boolean getCheck() {
                                             return check;
                                        }
                              
                                        public void setCheck(Boolean check) {
                                             this.check = check;
                                        }
                                   }
                              
                                   public static void main(String args[]) {
                                        launch(args);
                                   }
                              
                                   @Override
                                   public void start(Stage primaryStage) {
                                        final BorderPane root = new BorderPane();
                                        try {
                                             final TableView<StockVO> table = viewTable();
                                             Button button = new Button("View Check");
                                             button.setOnAction(new EventHandler<ActionEvent>() {
                              
                                                  @Override
                                                  public void handle(ActionEvent paramT) {
                                                       for (StockVO s : table.getItems()) {
                                                            System.out.println(s.getCheck());
                                                       }
                              
                                                  }
                                             });
                              
                                             root.setCenter(table);
                                             root.setBottom(button);
                                        } catch (Exception e) {
                                             // TODO Auto-generated catch block
                                             e.printStackTrace();
                                        }
                              
                                        primaryStage.setScene(new Scene(root, 400, 600));
                                        primaryStage.show();
                                   }
                              }
                              Thanks in advance..
                              • 12. Re: Tableview With CheckBox issue
                                James_D
                                You need to use FX properties in your StockVO class in order for the [url http://docs.oracle.com/javafx/2/api/javafx/scene/control/cell/PropertyValueFactory.html]PropertyValueFactory to work with the correct bindings. Compare it to the Player class in my example.