private void kochPanelMouseDragged(MouseEvent event) {
   zoomTranslateX = zoomTranslateX + event.getX() - lastDragX;
   zoomTranslateY = zoomTranslateY + event.getY() - lastDragY;
   lastDragX = event.getX();
   lastDragY = event.getY();
   kochManager.drawEdges();
 }
 private void decreaseLevelButtonActionPerformed(ActionEvent event) {
   if (currentLevel > 1) {
     // resetZoom();
     currentLevel--;
     labelLevel.setText("Level: " + currentLevel);
     kochManager.ChangeLevel(currentLevel);
   }
 }
 private void increaseLevelButtonActionPerformed(ActionEvent event) {
   if (currentLevel < 12) {
     // resetZoom();
     currentLevel++;
     labelLevel.setText("Level: " + currentLevel);
     kochManager.changeLevel(currentLevel);
   }
 }
 private void kochPanelMouseClicked(MouseEvent event) {
   if (Math.abs(event.getX() - startPressedX) < 1.0
       && Math.abs(event.getY() - startPressedY) < 1.0) {
     double originalPointClickedX = (event.getX() - zoomTranslateX) / zoom;
     double originalPointClickedY = (event.getY() - zoomTranslateY) / zoom;
     if (event.getButton() == MouseButton.PRIMARY) {
       zoom *= 2.0;
     } else if (event.getButton() == MouseButton.SECONDARY) {
       zoom /= 2.0;
     }
     zoomTranslateX = (int) (event.getX() - originalPointClickedX * zoom);
     zoomTranslateY = (int) (event.getY() - originalPointClickedY * zoom);
     kochManager.drawEdges();
   }
 }
  @Override
  public void start(Stage primaryStage) {

    // Define grid pane
    GridPane grid;
    grid = new GridPane();
    grid.setHgap(10);
    grid.setVgap(10);
    grid.setPadding(new Insets(25, 25, 25, 25));

    // For debug purposes
    // Make de grid lines visible
    // grid.setGridLinesVisible(true);

    // Drawing panel for Koch fractal
    kochPanel = new Canvas(kpWidth, kpHeight);
    grid.add(kochPanel, 0, 4, 25, 1);

    // Labels to present number of edges for Koch fractal
    labelNrEdges = new Label("Nr edges:");
    labelNrEdgesText = new Label();
    grid.add(labelNrEdges, 0, 0, 4, 1);
    grid.add(labelNrEdgesText, 3, 0, 22, 1);

    // Labels to present time of calculation for Koch fractal
    labelCalc = new Label("Calculating:");
    labelCalcText = new Label();
    grid.add(labelCalc, 0, 1, 4, 1);
    grid.add(labelCalcText, 3, 1, 22, 1);

    // Labels to present time of drawing for Koch fractal
    labelDraw = new Label("Drawing:");
    labelDrawText = new Label();
    grid.add(labelDraw, 0, 2, 4, 1);
    grid.add(labelDrawText, 3, 2, 22, 1);

    // Label to present current level of Koch fractal
    labelLevel = new Label("Level: " + currentLevel);
    grid.add(labelLevel, 0, 6);

    // Button to increase level of Koch fractal
    Button buttonIncreaseLevel = new Button();
    buttonIncreaseLevel.setText("Increase Level");
    buttonIncreaseLevel.setOnAction(
        new EventHandler<ActionEvent>() {
          @Override
          public void handle(ActionEvent event) {
            increaseLevelButtonActionPerformed(event);
          }
        });
    grid.add(buttonIncreaseLevel, 3, 6);

    // Button to decrease level of Koch fractal
    Button buttonDecreaseLevel = new Button();
    buttonDecreaseLevel.setText("Decrease Level");
    buttonDecreaseLevel.setOnAction(
        new EventHandler<ActionEvent>() {
          @Override
          public void handle(ActionEvent event) {
            decreaseLevelButtonActionPerformed(event);
          }
        });
    grid.add(buttonDecreaseLevel, 5, 6);

    // Button to fit Koch fractal in Koch panel
    Button buttonFitFractal = new Button();
    buttonFitFractal.setText("Fit Fractal");
    buttonFitFractal.setOnAction(
        new EventHandler<ActionEvent>() {
          @Override
          public void handle(ActionEvent event) {
            fitFractalButtonActionPerformed(event);
          }
        });
    grid.add(buttonFitFractal, 14, 6);

    // Add mouse clicked event to Koch panel
    kochPanel.addEventHandler(
        MouseEvent.MOUSE_CLICKED,
        new EventHandler<MouseEvent>() {
          @Override
          public void handle(MouseEvent event) {
            kochPanelMouseClicked(event);
          }
        });

    // Add mouse pressed event to Koch panel
    kochPanel.addEventHandler(
        MouseEvent.MOUSE_PRESSED,
        new EventHandler<MouseEvent>() {
          @Override
          public void handle(MouseEvent event) {
            kochPanelMousePressed(event);
          }
        });

    // Add mouse dragged event to Koch panel
    kochPanel.setOnMouseDragged(
        new EventHandler<MouseEvent>() {
          @Override
          public void handle(MouseEvent event) {
            kochPanelMouseDragged(event);
          }
        });
    // Adding progress bars and their info
    Label LeftLabel = new Label("Left Progress");
    lblLeftCalc = new Label(". . . . .");
    grid.add(lblLeftCalc, 7, 10);
    grid.add(LeftLabel, 1, 5);
    grid.add(progressBarLeft, 2, 5);

    Label RightLabel = new Label("Right Progress");
    lblRightCalc = new Label(". . . . .");
    grid.add(lblRightCalc, 7, 11);
    grid.add(RightLabel, 1, 6);
    grid.add(progressBarRight, 2, 6);

    Label BottomLabel = new Label("Bottom Progress");
    lblBottomCalc = new Label(". . . . .");
    grid.add(lblBottomCalc, 7, 12);
    grid.add(BottomLabel, 1, 7);
    grid.add(progressBarBottom, 2, 7);

    // Create Koch manager and set initial level
    resetZoom();
    kochManager = new KochManager(this);
    kochManager.ChangeLevel(currentLevel);

    // Create the scene and add the grid pane
    Group root = new Group();
    Scene scene = new Scene(root, kpWidth + 50, kpHeight + 170);
    root.getChildren().add(grid);

    // Define title and assign the scene for main window
    primaryStage.setTitle("Koch Fractal");
    primaryStage.setScene(scene);
    primaryStage.show();
  }
 private void fitFractalButtonActionPerformed(ActionEvent event) {
   resetZoom();
   kochManager.drawEdges();
 }