Package rpn

Source Code of rpn.RPNFX

package rpn;

import java.lang.reflect.Field;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Labeled;
import javafx.scene.control.TextInputControl;
import javafx.stage.Stage;

public class RPNFX extends Application implements EventHandler<ActionEvent> {

  private RPN rpn;
  private Node valueText = null;
  private String input = null;
 
  @Override
  public void init() throws Exception {
    super.init();
    rpn = new RPN();
  }

  private Class<?>[] constantClasses = {Math.class, this.getClass()};

  private void performAction(String command) {
    // push existing input
    if (input != null) {
      rpn.push(Double.valueOf(input));
      input = null;
    }
    Number number = null;
    try {
      // try commmand as double value
      number = Double.valueOf(command);
    } catch (NumberFormatException nfe) {
      // try command as named double field in either the Math class or this class
      for (Class<?> constantClass: constantClasses) {
        try {
          // change to constant naming convention
          String constantName = command.toUpperCase().replace(' ', '_');
          Field constantField = constantClass.getField(constantName);
          // check correct type
          if (constantField.getType() == double.class) {
            number = (Number) constantField.get(this);
          }
        } catch (Exception e) {
        }
      }
    }
    // check if command could (somehow) be interpreted as a number
    if (number != null) {
      rpn.push(number.doubleValue());
    } else if (command.equals("push")) {
    }
    updateValueText();
  }

  private void updateValueText() {
    String label = "";
    for (int i = 0; i < rpn.getSize(); i++) {
      label = rpn.peek(i) + " " + label;
    }
    if (input != null) {
      label = label + input;
    }
    if (valueText instanceof TextInputControl) {
      ((TextInputControl) valueText).setText(label);
    } else if (valueText instanceof Labeled) {
      ((Labeled) valueText).setText(label);
    }
  }

  @Override
  public void handle(ActionEvent event) {
    Object source = event.getSource();
    Labeled labeled = null;
    if (source instanceof Labeled) {
      labeled = (Labeled) source;
    }
    if (labeled != null) {
      // check CSS styles, see RPN.fxml

      // the inputTextButton style is for buttons that append text to the input text field, e.g. digits
      String text = labeled.getText();
      if (labeled.getStyleClass().contains("inputTextButton")) {
        input = (input == null ? String.valueOf(text) : input + text);
        updateValueText();
      }
      // the inputTextEditButton style is for buttons that (somehow) edit the input text field, e.g. backspace
      if (labeled.getStyleClass().contains("inputTextEditButton")) {
        if (text.equals("backspace")) {
          if (input == null || input.length() == 0) {
            input = String.valueOf(rpn.pop(0.0));
          }
          input = input.substring(0, input.length() - 1);
        }
        updateValueText();
      }
      // the operatorButton style is for operator buttons, e.g. +
      if (labeled.getStyleClass().contains("operatorButton")) {
        char op = text.charAt(0);
        // push existing input
        if (input != null) {
          rpn.push(Double.valueOf(input));
          input = null;
        }
        rpn.performOperation(op);
        updateValueText();
      }
      // the actionButton style is for buttons that otherwise modify the calculator stack, e.g. push
      if (labeled.getStyleClass().contains("actionButton")) {
        performAction(text);
      }
    }
  }

  private String fxmlFile = "RPN.fxml";

  @Override
  public void start(Stage stage) throws Exception {
    FXMLLoader fxmlLoader = new FXMLLoader();
    fxmlLoader.setLocation(getClass().getResource(fxmlFile));
    fxmlLoader.load(getClass().getResourceAsStream(fxmlFile));
    Parent root = fxmlLoader.<Parent>getRoot();
   
    for (Node node : root.lookupAll("Button")) {
      node.addEventHandler(ActionEvent.ACTION, this);
    }
    // the node holding the current value, using id lookup
    valueText = (TextInputControl) root.lookup("#valueTextNode");
   
    stage.setScene(new Scene(root));
    stage.show();
  }

  public static void main(String[] args) {
    launch(RPNFX.class);
  }
}
TOP

Related Classes of rpn.RPNFX

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.