title: Why are JavaFX2.2 buttons in my table view code not visible?
body: <p>The JavaFX2 tutorial has an Addressbook example which is a table view. </p>
  
  <p>tutorial:
  <a href="http://docs.oracle.com/javafx/2/fxml_get_started/fxml_tutorial_intermediate.htm#CACFEHBI" rel="nofollow">http://docs.oracle.com/javafx/2/fxml_get_started/fxml_tutorial_intermediate.htm#CACFEHBI</a></p>
  
  <p>enhancement to edit cells:
  <a href="http://docs.oracle.com/javafx/2/ui_controls/table-view.htm" rel="nofollow">http://docs.oracle.com/javafx/2/ui_controls/table-view.htm</a></p>
  
  <p>modification to add checkbox:
  <a href="http://download.oracle.com/otndocs/products/javafx/2.2/samples/Ensemble/index.html#SAMPLES/Controls/Table/Table" rel="nofollow">http://download.oracle.com/otndocs/products/javafx/2.2/samples/Ensemble/index.html#SAMPLES/Controls/Table/Table</a> Cell Factory</p>
  
  <p>Entering data in the text boxes and Clicking the Add button adds a row to the table.
  However, rows cannot be deleted.
  I was trying to see if I can add a Delete button in each cell - clicking it will delete the row. 
  I modified the existing sample code.
  Somehow, the buttons are not visible. Any pointers appreciated.</p>
  
  <p>//FXML_tableview.fxml file</p>
  
  <pre><code>&lt;?import javafx.collections.*?&gt; 
  &lt;?import javafx.geometry.Insets?&gt;
  &lt;?import java.lang.*?&gt;
  &lt;?import javafx.scene.*?&gt;
  &lt;?import javafx.scene.control.*?&gt;
  &lt;?import javafx.scene.control.cell.*?&gt;
  &lt;?import javafx.scene.layout.*?&gt;
  &lt;?import fxmltableview.*?&gt; 
   &lt;Scene fx:id="root" width="550" height="550"
      fx:controller="fxmltableview.FXMLTableViewController" 
      xmlns:fx="http://javafx.com/fxml"&gt;      
      &lt;GridPane alignment="center" hgap="10" vgap="10"&gt;
          &lt;padding&gt;
              &lt;Insets top="10" right="10" bottom="10" left="10"/&gt;
          &lt;/padding&gt;
  
          &lt;TableView fx:id="tableView" GridPane.columnIndex="0" 
                     GridPane.rowIndex="1"&gt;
          &lt;/TableView&gt;
  
          &lt;HBox spacing="10" alignment="bottom_right" GridPane.columnIndex="0" 
                GridPane.rowIndex="2"&gt;
              &lt;TextField fx:id="firstNameField" promptText="First Name"
                         prefWidth="90"/&gt;
              &lt;TextField fx:id="lastNameField" promptText="Last Name"
                         prefWidth="90"/&gt;
              &lt;TextField fx:id="emailField" promptText="Email"
                         prefWidth="150"/&gt;
              &lt;Button text="Add" onAction="#addPerson"/&gt;
          &lt;/HBox&gt;
      &lt;/GridPane&gt;
   &lt;/Scene&gt;
  </code></pre>
  
  <p>// FXMLTableView.java</p>
  
  <pre><code>package fxmltableview;
  
  import javafx.application.Application;
  import javafx.event.EventHandler;
  import javafx.fxml.FXMLLoader;
  import javafx.scene.Scene;
  import javafx.scene.control.TableColumn;
  import javafx.stage.Stage;
  import javafx.beans.property.BooleanProperty;
  import javafx.beans.property.SimpleBooleanProperty;
  import javafx.beans.property.StringProperty;
  import javafx.beans.property.SimpleStringProperty;
  import javafx.beans.value.ChangeListener;
  import javafx.beans.value.ObservableValue;
  import javafx.collections.FXCollections;
  import javafx.collections.ObservableList;
  import javafx.event.ActionEvent;
  import javafx.event.EventHandler;
  import javafx.fxml.FXML;
  import javafx.geometry.Pos;
  import javafx.scene.control.Button;
  import javafx.scene.control.CheckBox;
  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.TextField;
  import javafx.scene.control.cell.PropertyValueFactory;
  import javafx.scene.input.KeyCode;
  import javafx.scene.input.KeyEvent;
  import javafx.scene.layout.AnchorPane;
  import javafx.util.Callback;
  
  public class FXMLTableView extends Application {
     static public ObservableList&lt;Person&gt; data;
     @FXML Scene root;
     @FXML TableView tableView;
      @Override
      public void start(Stage primaryStage) throws Exception {
  
          primaryStage.setTitle("FXML TableView Example");
          root = (Scene)FXMLLoader.load(getClass().getResource("fxml_tableview.fxml"));
          primaryStage.setScene(root);
                  data = FXCollections.observableArrayList(
                  new Person(true, "Jacob", "Smith", "jacob.smith@example.com"),
                  new Person(false, "Isabella", "Johnson", "isabella.johnson@example.com"),
                  new Person(true, "Ethan", "Williams", "ethan.williams@example.com"),
                  new Person(true, "Emma", "Jones", "emma.jones@example.com"),
                  new Person(false, "Michael", "Brown", "michael.brown@example.com"));
  
          tableView = (TableView) root.lookup("#tableView");
          TableColumn delCol = new TableColumn&lt;Person, Boolean&gt;();
           delCol.setMinWidth(50);
          delCol.setCellFactory(new Callback&lt;TableColumn&lt;Person, Boolean&gt;, TableCell&lt;Person, Boolean&gt;&gt;() {
  
              public TableCell&lt;Person, Boolean&gt; call(TableColumn&lt;Person, Boolean&gt; p) {
                  return new DeleteTableCell&lt;Person, Boolean&gt;();
              }
          });
          //"Invited" column
          TableColumn invitedCol = new TableColumn&lt;Person, Boolean&gt;();
          invitedCol.setText("Invited");
          invitedCol.setMinWidth(50);
          invitedCol.setCellValueFactory(new PropertyValueFactory("invited"));
          invitedCol.setCellFactory(new Callback&lt;TableColumn&lt;Person, Boolean&gt;, TableCell&lt;Person, Boolean&gt;&gt;() {
  
              public TableCell&lt;Person, Boolean&gt; call(TableColumn&lt;Person, Boolean&gt; p) {
                  return new CheckBoxTableCell&lt;Person, Boolean&gt;();
              }
          });
          //"First Name" column
          TableColumn firstNameCol = new TableColumn();
          firstNameCol.setText("First");
          firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName"));
          //"Last Name" column
          TableColumn lastNameCol = new TableColumn();
          lastNameCol.setText("Last");
          lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName"));
          //"Email" column
          TableColumn emailCol = new TableColumn();
          emailCol.setText("Email");
          emailCol.setMinWidth(200);
          emailCol.setCellValueFactory(new PropertyValueFactory("email"));
  
          //Set cell factory for cells that allow editing
          Callback&lt;TableColumn, TableCell&gt; cellFactory =
                  new Callback&lt;TableColumn, TableCell&gt;() {
  
                      public TableCell call(TableColumn p) {
                          return new EditingCell();
                      }
                  };
          emailCol.setCellFactory(cellFactory);
          firstNameCol.setCellFactory(cellFactory);
          lastNameCol.setCellFactory(cellFactory);
  
          //Set handler to update ObservableList properties. Applicable if cell is edited
          updateObservableListProperties(emailCol, firstNameCol, lastNameCol);
  
  
          tableView.setItems(data);
          //Enabling editing
          tableView.setEditable(true);
          tableView.getColumns().addAll(invitedCol, firstNameCol, lastNameCol, emailCol, delCol);
   //       root.getChildren().add(tableView); 
          primaryStage.show();
      }
     private void updateObservableListProperties(TableColumn emailCol, TableColumn firstNameCol,
              TableColumn lastNameCol) {
          //Modifying the email property in the ObservableList
          emailCol.setOnEditCommit(new EventHandler&lt;TableColumn.CellEditEvent&lt;Person, String&gt;&gt;() {           
              @Override public void handle(TableColumn.CellEditEvent&lt;Person, String&gt; t) {
                  ((Person) t.getTableView().getItems().get(
                          t.getTablePosition().getRow())).setEmail(t.getNewValue());
              }
          });
          //Modifying the firstName property in the ObservableList
          firstNameCol.setOnEditCommit(new EventHandler&lt;TableColumn.CellEditEvent&lt;Person, String&gt;&gt;() {          
              @Override public void handle(TableColumn.CellEditEvent&lt;Person, String&gt; t) {
                  ((Person) t.getTableView().getItems().get(
                          t.getTablePosition().getRow())).setFirstName(t.getNewValue());
              }
          });
          //Modifying the lastName property in the ObservableList
          lastNameCol.setOnEditCommit(new EventHandler&lt;TableColumn.CellEditEvent&lt;Person, String&gt;&gt;() {           
              @Override public void handle(TableColumn.CellEditEvent&lt;Person, String&gt; t) {
                  ((Person) t.getTableView().getItems().get(
                          t.getTablePosition().getRow())).setLastName(t.getNewValue());
              }
          });
      }
     //CheckBoxTableCell for creating a CheckBox in a table cell
      public static class CheckBoxTableCell&lt;S, T&gt; extends TableCell&lt;S, T&gt; {
          private final CheckBox checkBox;
          private ObservableValue&lt;T&gt; ov;
  
          public CheckBoxTableCell() {
              this.checkBox = new CheckBox();
              this.checkBox.setAlignment(Pos.CENTER);
  
              setAlignment(Pos.CENTER);
              setGraphic(checkBox);
          } 
  
          @Override public void updateItem(T item, boolean empty) {
              super.updateItem(item, empty);
              if (empty) {
                  setText(null);
                  setGraphic(null);
              } else {
                  setGraphic(checkBox);
                  if (ov instanceof BooleanProperty) {
                      checkBox.selectedProperty().unbindBidirectional((BooleanProperty) ov);
                  }
                  ov = getTableColumn().getCellObservableValue(getIndex());
                  if (ov instanceof BooleanProperty) {
                      checkBox.selectedProperty().bindBidirectional((BooleanProperty) ov);
                  }
              }
          }
      }
       public static class DeleteTableCell&lt;S, T&gt; extends TableCell&lt;S, T&gt; {
          private final Button del;
          private ObservableValue&lt;T&gt; ov;
  
          public DeleteTableCell() {
              this.del = new Button("X");
              del.setStyle("-fx-base: red;");
              this.del.setAlignment(Pos.CENTER);
  
              setAlignment(Pos.CENTER);
              setGraphic(del);
              del.setOnAction(new EventHandler&lt;ActionEvent&gt; () {
                  @Override
                  public void handle(ActionEvent t) {
                      int i= getIndex();
                      FXMLTableView.data.remove(i);
                  }                
              });
          } 
  
          @Override public void updateItem(T item, boolean empty) {
              super.updateItem(item, empty);
              if (empty) {
                  setText(null);
                  setGraphic(null);
              } else {
                  setGraphic(del);
              }
          }
      }
      // EditingCell - for editing capability in a TableCell
      public static class EditingCell extends TableCell&lt;Person, String&gt; {
          private TextField textField;
  
          public EditingCell() {
          }
  
          @Override public void startEdit() {
              super.startEdit();
  
              if (textField == null) {
                  createTextField();
              }
              setText(null);
              setGraphic(textField);
              textField.selectAll();
          }
  
          @Override public void cancelEdit() {
              super.cancelEdit();
              setText((String) getItem());
              setGraphic(null);
          }
  
          @Override public void updateItem(String item, boolean empty) {
              super.updateItem(item, empty);
              if (empty) {
                  setText(null);
                  setGraphic(null);
              } else {
                  if (isEditing()) {
                      if (textField != null) {
                          textField.setText(getString());
                      }
                      setText(null);
                      setGraphic(textField);
                  } else {
                      setText(getString());
                      setGraphic(null);
                  }
              }
          }
  
          private void createTextField() {
              textField = new TextField(getString());
              textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
              textField.setOnKeyReleased(new EventHandler&lt;KeyEvent&gt;() {                
                  @Override public void handle(KeyEvent t) {
                      if (t.getCode() == KeyCode.ENTER) {
                          commitEdit(textField.getText());
                      } else if (t.getCode() == KeyCode.ESCAPE) {
                          cancelEdit();
                      }
                  }
              });
          }
  
          private String getString() {
              return getItem() == null ? "" : getItem().toString();
          }
      } 
  
      public static void main(String[] args) {
          launch(args);
      }
  }
  </code></pre>
  
  <p>// FXMLTableViewController.java</p>
  
  <pre><code>package fxmltableview;
  
  import javafx.collections.ObservableList;
  import javafx.event.ActionEvent;
  import javafx.event.EventHandler;
  import javafx.fxml.FXML;
  import javafx.scene.control.TableColumn;
  import javafx.scene.control.TableView;
  import javafx.scene.control.TextField;
  
  public class FXMLTableViewController {
      @FXML private TableView&lt;Person&gt; tableView;
      @FXML private TextField firstNameField;
      @FXML private TextField lastNameField;
      @FXML private TextField emailField;
  
      @FXML
      protected void addPerson(ActionEvent event) {
          ObservableList&lt;Person&gt; data = tableView.getItems();
          data.add(new Person(false, firstNameField.getText(),
              lastNameField.getText(),
              emailField.getText()
          ));
  
          firstNameField.setText("");
          lastNameField.setText("");
          emailField.setText("");   
      }
  
  
  }
  </code></pre>
  
  <p>// Person.java</p>
  
  <pre><code>package fxmltableview;
  
  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;
  
  //Person object
  public class Person {
      private BooleanProperty invited;
      private StringProperty firstName;
      private StringProperty lastName;
      private StringProperty email;
  
      Person(boolean invited, String fName, String lName, String email) {
          this.invited = new SimpleBooleanProperty(invited);
          this.firstName = new SimpleStringProperty(fName);
          this.lastName = new SimpleStringProperty(lName);
          this.email = new SimpleStringProperty(email);
          this.invited = new SimpleBooleanProperty(invited);
  
          this.invited.addListener(new ChangeListener&lt;Boolean&gt;() {
              public void changed(ObservableValue&lt;? extends Boolean&gt; ov, Boolean t, Boolean t1) {
                  System.out.println(firstNameProperty().get() + " invited: " + t1);
              }
          });            
      }
  
      public BooleanProperty invitedProperty() { return invited; }
  
      public StringProperty firstNameProperty() { return firstName; }
  
      public StringProperty lastNameProperty() { return lastName; }
  
      public StringProperty emailProperty() { return email; }
  
      public void setLastName(String lastName) { this.lastName.set(lastName); }
  
      public void setFirstName(String firstName) { this.firstName.set(firstName); }
  
      public void setEmail(String email) { this.email.set(email); }
  }
  </code></pre>