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.)
                1 位用户发现它有用
                • 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.