This discussion is archived
12 Replies Latest reply: Mar 31, 2013 6:10 AM by James_D RSS

Tableview With CheckBox issue

abhinay_a Newbie
Currently Being Moderated
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 Guru
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    Using
    checkColumn.setCellFactory(CheckBoxTableCell.forTableColumn(checkColumn));
    gives me an uneditable checkBox
  • 3. Re: Tableview With CheckBox issue
    James_D Guru
    Currently Being Moderated
    Did you call setEditable(true) on both the TableColumn and the TableView?
  • 4. Re: Tableview With CheckBox issue
    abhinay_a Newbie
    Currently Being Moderated
    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 Guru
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    James !! Man you are something :) :)
  • 7. Re: Tableview With CheckBox issue
    abhinay_a Newbie
    Currently Being Moderated
    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 Guru
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    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 Guru
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    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 Guru
    Currently Being Moderated
    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.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points