title: Creating a backspace button in JavaFX for a calculator
body: <p>I am trying to create a JavaFX calculator, a very basic one but I am unsure of how to implement the backspace. </p>
  
  <pre><code>private void makeBackspaceButton(Button button) {
      button.setStyle("-fx-base: ivory;");
      button.setOnAction(new EventHandler&lt;ActionEvent&gt;() {
          @Override
          public void handle(ActionEvent actionEvent) {
              value.set(value.get());
          }
      });
  
  }
  </code></pre>
  
  <p>I cannot for the life of me think of a way to remove the last value that was entered. So that if the value 89 is entered only the last digit (9) will be removed. 
  Is there a way to use it in this format or do I need to change my format.
  My full code is below, it is not finished yet.</p>
  
  <pre><code>import javafx.application.Application;
  import javafx.beans.binding.Bindings;
  import javafx.beans.property.*;
  import javafx.event.ActionEvent;
  import javafx.event.EventHandler;
  import javafx.geometry.Pos;
  import javafx.scene.Scene;
  import javafx.scene.control.*;
  import javafx.scene.input.KeyEvent;
  import javafx.scene.layout.*;
  import javafx.stage.Stage;
  import javafx.stage.StageStyle;
  
  import java.util.HashMap;
  import java.util.Map;
  
  // a simple JavaFX calculator.
  public class Calcy extends Application {
  
  //implementing the template if how i would like the buttons to look like
  private static final String[][] template = {
      {"c", "%", "√", "←"},
      {"7", "8", "9", "/"},
      {"4", "5", "6", "*"},
      {"1", "2", "3", "-"},
      {"0", ".", "=", "+"}
  };
  
  private final Map&lt;String, Button&gt; accelerators = new HashMap&lt;&gt;();
  
  
  private DoubleProperty stackValue = new SimpleDoubleProperty();
  private DoubleProperty value = new SimpleDoubleProperty();
  
  private enum Op {
  
      NOOP, ADD, SUBTRACT, MULTIPLY, DIVIDE
  }
  
  private Op curOp = Op.NOOP;
  private Op stackOp = Op.NOOP;
  
  public static void main(String[] args) {
      launch(args);
  }
  
  @Override
  public void start(Stage stage) {
      final TextField screen = createScreen();
      final TilePane buttons = createButtons();
  
      stage.setTitle("Thank goodness for a calculator!");
      stage.initStyle(StageStyle.UTILITY);
      stage.setResizable(false);
      stage.setScene(new Scene(createLayout(screen, buttons)));
      stage.show();
  }
  
  private VBox createLayout(TextField screen, TilePane buttons) {
      final VBox layout = new VBox(20);
      layout.setAlignment(Pos.CENTER);
      layout.setStyle("-fx-background-color: floralwhite; -fx-padding: 20; -fx-font-size: 20;");
      layout.getChildren().setAll(screen, buttons);
      handleAccelerators(layout);
      screen.prefWidthProperty().bind(buttons.widthProperty());
      return layout;
  }
  
  private void handleAccelerators(VBox layout) {
      layout.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler&lt;KeyEvent&gt;() {
          @Override
          public void handle(KeyEvent keyEvent) {
              Button activated = accelerators.get(keyEvent.getText());
              if (activated != null) {
                  activated.fire();
              }
          }
      });
  }
  
  private TextField createScreen() {
      final TextField screen = new TextField();
      screen.setStyle("-fx-background-color: lightgrey;");
      screen.setAlignment(Pos.CENTER_RIGHT);
      screen.setEditable(false);
      screen.textProperty().bind(Bindings.format("%.2f", value));
      return screen;
  }
  
  private TilePane createButtons() {
      TilePane buttons = new TilePane();
      buttons.setVgap(7);
      buttons.setHgap(7);
      buttons.setPrefColumns(template[0].length);
      for (String[] r : template) {
          for (String s : r) {
              buttons.getChildren().add(createButton(s));
          }
      }
      return buttons;
  }
  
  private Button createButton(final String s) {
      Button button = makeStandardButton(s);
  
      if (s.matches("[0-9]")) {
          makeNumericButton(s, button);
      } else {
          final ObjectProperty&lt;Op&gt; triggerOp = determineOperand(s);
          if (triggerOp.get() != Op.NOOP) {
              makeOperandButton(button, triggerOp);
          } else if ("c".equals(s)) {
              makeClearButton(button);
          } else if ("=".equals(s)) {
              makeEqualsButton(button);
          } else if ("←".equals(s)) {
              makeBackspaceButton(button);
          } else if ("%".equals(s)) {
              makePercentageButton(button);
          } else if ("√".equals(s)) {
              makeSquarerootButton(button);
          } else if (".".equals(s)) {
              makePointButton(button);
          }
      }
  
      return button;
  }
  
  private ObjectProperty&lt;Op&gt; determineOperand(String s) {
      final ObjectProperty&lt;Op&gt; triggerOp = new SimpleObjectProperty&lt;&gt;(Op.NOOP);
      switch (s) {
          case "+":
              triggerOp.set(Op.ADD);
              break;
          case "-":
              triggerOp.set(Op.SUBTRACT);
              break;
          case "*":
              triggerOp.set(Op.MULTIPLY);
              break;
          case "/":
              triggerOp.set(Op.DIVIDE);
              break;
          case "%":
  
      }
      return triggerOp;
  }
  
  private void makeOperandButton(Button button, final ObjectProperty&lt;Op&gt; triggerOp) {
      button.setStyle("-fx-base: ivory;");
      button.setOnAction(new EventHandler&lt;ActionEvent&gt;() {
          @Override
          public void handle(ActionEvent actionEvent) {
              curOp = triggerOp.get();
          }
      });
  }
  
  private Button makeStandardButton(String s) {
      Button button = new Button(s);
      button.setStyle("-fx-base: ivory;");
      accelerators.put(s, button);
      button.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
      return button;
  }
  
  private void makeNumericButton(final String s, Button button) {
      button.setOnAction(new EventHandler&lt;ActionEvent&gt;() {
          @Override
          public void handle(ActionEvent actionEvent) {
              if (curOp == Op.NOOP) {
                  value.set(value.get() * 10 + Integer.parseInt(s));
              } else {
                  stackValue.set(value.get());
                  value.set(Integer.parseInt(s));
                  stackOp = curOp;
                  curOp = Op.NOOP;
              }
          }
      });
  }
  
  private void makeClearButton(Button button) {
      button.setStyle("-fx-base: ivory;");
      button.setOnAction(new EventHandler&lt;ActionEvent&gt;() {
          @Override
          public void handle(ActionEvent actionEvent) {
              value.set(0);
          }
      });
  }
  
  private void makeBackspaceButton(Button button) {
      button.setStyle("-fx-base: ivory;");
      button.setOnAction(new EventHandler&lt;ActionEvent&gt;() {
          @Override
          public void handle(ActionEvent actionEvent) {
              value.set(value.get());
          }
      });
  
  }
  
  private void makeSquarerootButton(Button button) {
      button.setStyle("-fx-base: ivory;");
  }
  
  private void makePercentageButton(Button button) {
      button.setStyle("-fx-base: ivory;");
  }
  
  private void makePointButton(Button button) {
      button.setStyle("-fx-base: ivory;");
  }
  
  private void makeEqualsButton(Button button) {
      button.setStyle("-fx-base: ivory;");
      button.setOnAction(new EventHandler&lt;ActionEvent&gt;() {
          @Override
          public void handle(ActionEvent actionEvent) {
              switch (stackOp) {
                  case ADD:
                      value.set(stackValue.get() + value.get());
                      break;
                  case SUBTRACT:
                      value.set(stackValue.get() - value.get());
                      break;
                  case MULTIPLY:
                      value.set(stackValue.get() * value.get());
                      break;
                  case DIVIDE:
                      value.set(stackValue.get() / value.get());
                      break;
              }
          }
      });
  }
  </code></pre>
  
  <p>}</p>