title: Listen to if a button is disabled or enabled in JavaFX
body: <p>I want a code that allows me to listen for any changes made on a <code>TextField</code> component for disabling or enabling a button called <code>save</code>. Is it possible to do this using bindings or something similar? </p>
  
  <p>For example: <code>save.disableProperty().bind(...)</code>
  I used two <code>TextField</code> components for changing the information stored in a <code>TableView</code>.<br>
  I used data binding so that when a <code>TableView</code> row is selected, the information in that row is displayed in a <code>TextField</code>.  </p>
  
  <pre><code>@FXML
  private TableView&lt;UserData&gt; table;
  @FXML
  private TableColumn&lt;UserData, String&gt; col1;
  @FXML
  private TableColumn&lt;UserData, String&gt; col2;
  @FXML
  private TextField name;
  @FXML
  private TextField email;
  
  @FXML
  Button newUser;
  @FXML
  Button save;
  @FXML
  Button delete;
  private Connection conn;
  private Statement stm;
  private PreparedStatement prep;
  private ResultSet result;
  
  /**
   * Initializes the controller class.
   */
  @Override
  public void initialize(URL url, ResourceBundle rb) {
      populateTableView();
      configureDisable();
      table.getSelectionModel().selectedItemProperty().addListener(userDataListener);
      name.disableProperty().bind(table.getSelectionModel().selectedItemProperty().isNull());
      email.disableProperty().bind(table.getSelectionModel().selectedItemProperty().isNull());
      delete.disableProperty().bind(table.getSelectionModel().selectedItemProperty().isNull());
      data.addListener((Change&lt;? extends UserData&gt; change) -&gt; save.setDisable(false));
      name.setOnAction(ev -&gt; email.requestFocus());
  }
  
  private final ChangeListener&lt;UserData&gt; userDataListener = ((v, oldV, newV) -&gt; {
      if (oldV != null) {
          name.textProperty().unbindBidirectional(oldV.nameProperty());
          email.textProperty().unbindBidirectional(oldV.emailProperty());
  
      }
      if (newV != null) {
          name.textProperty().bindBidirectional(newV.nameProperty());
          email.textProperty().bindBidirectional(newV.emailProperty());
  
      }
      private void populateTableView() {
          try {
              conn = CreateConnection.getConnection();
              stm = conn.createStatement();
              data = FXCollections.observableArrayList();
              result = conn.createStatement().executeQuery("select *from user");
              while (result.next()) {
                  data.add(new UserData(result.getString("Name"), result.getString("Email")));
              }
              col1.setCellValueFactory(new PropertyValueFactory&lt;UserData, String&gt;("name"));
              col2.setCellValueFactory(new PropertyValueFactory&lt;UserData, String&gt;("email"));
              table.setItems(data);
          } catch (IOException ex) {
              Logger.getLogger(FXMLController.class.getName()).log(Level.SEVERE, null, ex);
          } catch (SQLException ex) {
              Logger.getLogger(FXMLController.class.getName()).log(Level.SEVERE, null, ex);
          }
      }
  });
  </code></pre>