Package program

Source Code of program.GridGameGUI

package program;

import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Bounds;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBase;
import javafx.scene.control.Labeled;
import javafx.scene.control.TextField;
import javafx.scene.control.TextInputControl;
import javafx.scene.input.KeyCharacterCombination;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.text.Text;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class GridGameGUI extends Application implements GameOutput, GridListener {

  private GridGame gridGame;
  private String level = null;

  private void init(GridGame program, String level) {
    this.gridGame = program;
    this.level = level;
  }
 
  private GridGame getGridGame() {
    return this.gridGame;
  }

  private TextInputControl levelTextField;
  private Button startButton;

  private TextInputControl inputTextField;
  private Button inputButton;

  private Button browseButton;
  private FileChooser fileChooser;
 
  private Map<KeyCombination, Node> keyCombinationNodes;

  @Override
  public void start(final Stage stage) throws Exception {
    List<String> parameters = getParameters().getRaw();
    GridGame program = (GridGame) Class.forName(parameters.get(0)).newInstance();
    init(program, parameters.size() > 1 ? parameters.get(1) : null);

    URL url = program.getClass().getResource(program.getClass().getSimpleName() + ".fxml");
    if (url == null) {
      url = this.getClass().getResource(this.getClass().getSimpleName() + ".fxml");
    }
    Parent root = FXMLLoader.load(url, null, new ProgramBuilderFactory());

    browseButton = lookupNode(root, "#fileButton", Button.class, browseActionHandler);

    levelTextField = lookupNode(root, "#levelTextField", TextInputControl.class, levelTextActionHandler);
    if (levelTextField != null && level != null) {
      levelTextField.setText(level);
    }
    startButton = lookupNode(root, "#startButton", Button.class, levelTextActionHandler);

    inputTextField = lookupNode(root, "#inputTextField", TextInputControl.class, inputTextActionHandler);
    inputButton = lookupNode(root, "#inputButton", Button.class, inputTextActionHandler);

    messageText = lookupNode(root, "#messageText", Text.class);
    gridPane = lookupNode(root, "#gridPane", GameGridPane.class);
   
    if (gridPane != null) {
      gridPane.setFocusTraversable(true);
      keyCombinationNodes = new HashMap<KeyCombination, Node>();
      for (Node node : root.lookupAll(".keyCombinationId")) {
        keyCombinationNodes.put(KeyCombination.valueOf(node.getId().replace('_', '+')), node);
      }
      for (Node node : root.lookupAll(".inputTextButton")) {
        if (node instanceof Labeled) {
          char firstChar = ((Labeled) node).getText().charAt(0);
          KeyCharacterCombination kc = new KeyCharacterCombination(String.valueOf(firstChar));
          keyCombinationNodes.put(kc, node);
        }
      }
      gridPane.setOnKeyTyped(keyCombinationHandler);
      gridPane.setOnKeyPressed(keyCombinationHandler);
      gridPane.setOnKeyPressed(directionKeyHandler);
      gridPane.setOnMouseClicked(graphicsNodeMouseHandler);
    }

    for (Node node : root.lookupAll(".inputTextButton")) {
      setActionHandler(node, inputTextActionHandler);
    }
   
    stage.setScene(new Scene(root));
    stage.show();
  }

  private <T extends Node> T lookupNode(Node root, String selector, Class<T> c) {
    Node node = root.lookup(selector);
    return (c.isInstance(node) ? (T) node : null);
  }
 
  private <T extends Node> T lookupNode(Node root, String selector, Class<T> c, EventHandler<ActionEvent> handler) {
    T node = lookupNode(root, selector, c);
    if (handler != null) {
      setActionHandler(node, handler);
    }
    return node;
  }

  private <T extends Node> void setActionHandler(T node, EventHandler<ActionEvent> handler) {
    if (node instanceof ButtonBase) {
      ((ButtonBase) node).setOnAction(handler);
    } else if (node instanceof TextField) {
      ((TextField) node).setOnAction(handler);
    }
  }
 
  private EventHandler<ActionEvent> levelTextActionHandler = new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent actionEvent) {
      getGridGame().init(levelTextField.getText());
      getGridGame().run(GridGameGUI.this);
      if (gridPane != null) {
        gridProvider = getGridGame().getGridProvider();
        gridProvider.addGridListener(GridGameGUI.this);
        initGrid();
        gridPane.requestFocus();
      }
      inputButton.setDisable(false);
    }
  };

  private EventHandler<ActionEvent> inputTextActionHandler = new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent actionEvent) {
      Object source = actionEvent.getSource();
      if (source == inputTextField || source == inputButton) {
        doCommand(inputTextField.getText());
      } else if (source instanceof Labeled && ((Node) source).getStyleClass().contains("inputTextButton")) {
        doCommand(((Labeled) source).getText());
      }
    }
  };
 
  private EventHandler<ActionEvent> browseActionHandler = new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent actionEvent) {
      if (fileChooser == null) {
        fileChooser = new FileChooser();
      }
      fileChooser.setTitle("Open level file");
      File file = fileChooser.showOpenDialog(browseButton.getScene().getWindow());
      if (file != null) {
        levelTextField.setText(file.getAbsolutePath());
        doAction(startButton);
      }
    }
  };
 
  private EventHandler<KeyEvent> directionKeyHandler = new EventHandler<KeyEvent>() {
    @Override
    public void handle(KeyEvent keyEvent) {
      if (! keyEvent.isConsumed()) {
        if (keyEvent.getCode() == KeyCode.UP) {
          directionInput(0, -1);
        } else if (keyEvent.getCode() == KeyCode.DOWN) {
          directionInput(0, 1);
        } else if (keyEvent.getCode() == KeyCode.LEFT) {
          directionInput(-1, 0);
        } else if (keyEvent.getCode() == KeyCode.RIGHT) {
          directionInput(1, 0);
        } else {
          return;
        }
        keyEvent.consume();
      }
    }
  };
 
  private EventHandler<KeyEvent> keyCombinationHandler = new EventHandler<KeyEvent>() {
    @Override
    public void handle(KeyEvent keyEvent) {
      if (! keyEvent.isConsumed()) {
        Node node = getKeyCombinationNode(keyEvent);
        if (node != null && doAction(node)) {
          keyEvent.consume();
        }
      }
    }
  };
 
  private EventHandler<MouseEvent> graphicsNodeMouseHandler = new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent mouseEvent) {
      gridPane.requestFocus();
      for (Node child : gridPane.getChildrenUnmodifiable()) {
        Bounds bounds = child.getBoundsInParent();
        if (bounds.contains(mouseEvent.getX(), mouseEvent.getY())) {
          Integer column = GridPane.getColumnIndex(child), row = GridPane.getRowIndex(child);
          if (column != null && column < gridProvider.getGridWidth() && row != null && row < gridProvider.getGridHeight()) {
            gridInput(column, row);
          }
        }
      }
    }
  };
 
  private boolean match(KeyCombination kc, KeyEvent keyEvent) {
    if (keyEvent.getEventType() == KeyEvent.KEY_TYPED) {
      if (kc instanceof KeyCharacterCombination) {
        return ((KeyCharacterCombination) kc).getCharacter().equals(keyEvent.getCharacter());
      }
    } else  {
      return kc.match(keyEvent);
    }
    return false;
  }
 
  private Node getKeyCombinationNode(KeyEvent keyEvent) {
    for (KeyCombination kc : keyCombinationNodes.keySet()) {
      if (match(kc, keyEvent)) {
        return keyCombinationNodes.get(kc);
      }
    }
    return null;
  }

  private void doCommand(String line) {
    updateMessage(null, null, true);
    Integer result = getGridGame().doCommand(line);
    handleInputResult(result);
    inputTextField.selectAll();
  }

  private void handleInputResult(Integer result) {
    if (result != null) {
      info("Game over" + (result != 0 ? "" : ", no result") + "!");
      inputButton.setDisable(true);
    }
  }
 
  private void gridInput(int column, int row) {
    updateMessage(null, null, true);
    Integer result = getGridGame().gridElementInput(column, row);
    handleInputResult(result);
  }
 
  private void directionInput(int dx, int dy) {
    updateMessage(null, null, true);
    Integer result = getGridGame().directionInput(dx, dy);
    handleInputResult(result);
  }

  private boolean doAction(Node node) {
    EventHandler<ActionEvent> handler = null;
    if (node instanceof ButtonBase) {
      handler = ((ButtonBase) node).getOnAction();
    } else if (node instanceof TextField) {
      handler = ((TextField) node).getOnAction();
    }
    if (handler != null) {
      handler.handle(new ActionEvent(node, null));
      return true;
    } else if (node instanceof ButtonBase) {
      ((ButtonBase) node).fire();
      return true;
    }
    return false;
  }
 
  // from GraphicalOutput
 
  private Node messageText;

  public void info(String message) {
    updateMessage(message, null, false);
  }

  public void warning(String message) {
    updateMessage(message, Color.RED, false);
  }

  public void error(String message) {
    Stage dialog = new Stage();
    dialog.initStyle(StageStyle.UTILITY);
    Scene scene = new Scene(new Group(new Text(25, 25, message)));
    dialog.setScene(scene);
    dialog.show();
  }

  private void updateMessage(String message, final Paint paint, boolean clear) {
    String text = message != null ? message : "";
    if (messageText instanceof Text) {
      if (! clear) {
        text = ((Text) messageText).getText() + "\n" + text;
      }
      ((Text) messageText).setFill(paint != null ? paint : Color.BLACK);
      ((Text) messageText).setText(text);
    } else if (messageText instanceof Labeled) {
      if (! clear) {
        text = ((Labeled) messageText).getText() + "\n" + text;
      }
      ((Labeled) messageText).setText(text);
    }
  }

  private GameGridPane gridPane;
 
  private GridProvider gridProvider;
 
  @Override
  public void gridChanged(GridProvider gridProvider, int x, int y, int w, int h) {
    if (gridProvider == this.gridProvider) {
      updateGrid(x, y, w, h);
    }
  }

  private void initGrid() {
    gridPane.setDimensions(gridProvider.getGridWidth(), gridProvider.getGridHeight());
    updateGrid(0, 0, gridProvider.getGridWidth(), gridProvider.getGridHeight());
    gridPane.setPrefSize(gridProvider.getGridWidth() * 16, gridProvider.getGridHeight() * 16);
  }
 
  private void updateGrid(int x, int y, int w, int h) {
    for (int column = x; column < x + w; column++) {
      for (int row = y; row < y + h; row++) {
        Object gridElement = gridProvider.getGridElement(column, row);
        String text = getGridGame().getTextFor(gridElement);
        String imageKey = getGridGame().getImageFor(gridElement);
        gridPane.setText(text, column, row);
        gridPane.setImage(imageKey, column, row, getGridGame(), this);
      }     
    }
  }
 
  //
 
  public static void main(String[] args) throws Exception {
    launch(GridGameGUI.class, args);
  }
}
TOP

Related Classes of program.GridGameGUI

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.