2 Replies Latest reply: May 2, 2013 9:19 AM by 1006718 RSS

    javafx CheckboxTableCell: setOnEditCommit event is not getting fired.

    1006718
      Hi,

      I'm trying to get count of selected rows in a javafx TableView, the issue is setOnEditCommit event is not getting invoked on selection or deselection of checkboxes in the table rows. if anybody faced this kind of issue?! Kindly share your ideas about this issue if you have faced or solved before. Below is the source code snippet for your reference. Thanks in advance!

      ObservableList<TableColumn> columns = custTable.getColumns();
      TableColumn<CustomerUI,Boolean> selCol = columns.get(0);
      selCol.setCellFactory(createCheckboxCallback());

      custTable.setEditable(true);
      PropertyValueFactory<CustomerUI,Boolean> pvf = new PropertyValueFactory<CustomerUI,Boolean>("selected");

      selCol.setCellValueFactory(pvf);
      selCol.setEditable(true);

      selCol.setOnEditCommit(new EventHandler<CellEditEvent<CustomerUI, Boolean>>() {

      @Override
      public void handle(CellEditEvent<CustomerUI, Boolean> t) {
      logger.info("checkbox handle");
      }
      });

      private Callback<TableColumn<CustomerUI, Boolean>, TableCell<CustomerUI, Boolean>> createCheckboxCallback() {
      Callback<TableColumn<CustomerUI,Boolean>, TableCell<CustomerUI, Boolean>> callback
      = new Callback<TableColumn<CustomerUI, Boolean>, TableCell<CustomerUI, Boolean>>() {

      @Override
      public TableCell<CustomerUI, Boolean> call(final TableColumn<CustomerUI, Boolean> selectColumn) {
      Callback<Integer,ObservableValue<Boolean>> callbackProperty = new Callback<Integer,ObservableValue<Boolean>>() {

      @Override
      public ObservableValue<Boolean> call(Integer p) {                      
      return selectColumn.getCellObservableValue(p);
      }

      };
      return new CheckBoxTableCell<>(callbackProperty);
      }
      };

      return callback;
      }
        • 1. Re: javafx CheckboxTableCell: setOnEditCommit event is not getting fired.
          James_D
          I haven't actually tried to use TableColumn.setOnEditCommit(...) before, but it appears not to get invoked. I'm not sure if this is a bug, or if we're misinterpreting the purpose of that method.

          In general, it's better if possible to listen to changes in your data than to listen to events on the UI. In this example I create the observable list with an extractor that reports list updates if the boolean property ("injured", in this example) changes, and attach a ListChangeListener to the observable list.

          Another approach would be to create a ChangeListener<Boolean> and attach it to the boolean property of each of the elements of the list. This approach might get tricky if you are going to add or remove elements from your list.

          BTW, please read [url https://forums.oracle.com/forums/ann.jspa?annID=1622]How to post code.
          import java.util.Arrays;
          import java.util.List;
          
          import javafx.application.Application;
          import javafx.beans.Observable;
          import javafx.beans.property.BooleanProperty;
          import javafx.beans.property.SimpleBooleanProperty;
          import javafx.beans.property.SimpleStringProperty;
          import javafx.beans.property.StringProperty;
          import javafx.beans.value.ChangeListener;
          import javafx.beans.value.ObservableValue;
          import javafx.collections.FXCollections;
          import javafx.collections.ListChangeListener;
          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.TableColumn.CellEditEvent;
          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> injuredColumn = new TableColumn<>("Injured");
              firstNameColumn.setCellValueFactory(new PropertyValueFactory<Player, String>("firstName"));
              lastNameColumn.setCellValueFactory(new PropertyValueFactory<Player, String>("lastName"));
              injuredColumn.setCellValueFactory(new PropertyValueFactory<Player, Boolean>("injured"));
              final Callback<TableColumn<Player, Boolean>, TableCell<Player, Boolean>> cellFactory = CheckBoxTableCell.forTableColumn(injuredColumn);
              injuredColumn.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);
                  return cell ;
                }
              });
              injuredColumn.setCellFactory(cellFactory);
              injuredColumn.setEditable(true);
          
              // This appears not to get invoked:
              injuredColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Player,Boolean>>() {
                @Override
                public void handle(CellEditEvent<Player, Boolean> event) {
                  System.out.println("Edit commit");
                }
              });
              
              table.setEditable(true);
              table.getColumns().addAll(firstNameColumn, lastNameColumn, injuredColumn);
              
              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() {
              List<Player> players = Arrays.asList(
                  new Player("Hugo" ,"Lloris", false),
                  new Player("Brad", "Friedel", false),
                  new Player("Kyle", "Naughton", false),
                  new Player("Younes", "Kaboul", true),
                  new Player("Benoit", "Assou-Ekotto", false),
                  new Player("Jan", "Vertonghen", false),
                  new Player("Michael", "Dawson", false),
                  new Player("William", "Gallas", true),
                  new Player("Kyle", "Walker", false),
                  new Player("Scott", "Parker", false),
                  new Player("Mousa", "Dembele", false),
                  new Player("Sandro", "Cordeiro", true),
                  new Player("Tom", "Huddlestone", false),
                  new Player("Gylfi","Sigurdsson", false),
                  new Player("Gareth", "Bale", false),
                  new Player("Aaron", "Lennon", false),
                  new Player("Jermane", "Defoe", false),
                  new Player("Emmanuel", "Adebayor", true)
              );
              ObservableList<Player> data =  FXCollections.<Player>observableArrayList( 
                  new Callback<Player, Observable[]>() {
                    @Override
                    public Observable[] call(Player player) {
                      return new Observable[]{player.injuredProperty()};
                    }
                  }
              );
              data.addAll(players);
              data.addListener(new ListChangeListener<Player>() {
                @Override
                public void onChanged(
                    javafx.collections.ListChangeListener.Change<? extends Player> change) {
                  System.out.println("List changed");
                  while (change.next()) {
                    if (change.wasUpdated()) {
                      System.out.println("List updated");
                      System.out.println(change.getAddedSubList());
                    }
                  }
                }
              });
              
              return data ;
            }
            
            public static class Player {
              private final StringProperty firstName ;
              private final StringProperty lastName ;
              private final BooleanProperty injured ;
              Player(String firstName, String lastName, boolean international) {
                this.firstName = new SimpleStringProperty(this, "firstName", firstName);
                this.lastName = new SimpleStringProperty(this, "lastName", lastName);
                this.injured = new SimpleBooleanProperty(this, "injured", 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 isInjuredl() { return injured.get(); }
              public void setInjured(boolean international) { this.injured.set(international); }
              public BooleanProperty injuredProperty() { return injured ; }
              @Override
              public String toString() {
                return firstName.get() + " " + lastName.get() + (injured.get()?" (injured)":"");
              }
            }
          }
          • 2. Re: javafx CheckboxTableCell: setOnEditCommit event is not getting fired.
            1006718
            Hi,
            Thanks for the reply and I'm sorry for the inconvenience for the code posted. I don't know the code posting format before. Thanks for intimating me. Regarding the issue I guess it should be a bug, because it is working fine with TextFieldTableCell class, Adding a ChangeListener also good way of achieving this issue. Thank you!