Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setOnKeyPressed event not working properly

I am in need to create a generated tunnel-like thing with curves for my project in the university. I found some code in the Internet that allowed me to drag the controlpoint (attached to Anchor object) of the curve.

However, I wanted to make it possible to change the controlpoint Ylocation by pressing arrow keys ("up" and "down") and somehow it's not working at all. I have been trying to hopelessly solve this issue myself, but I can' t find the way out.

import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;

/** Example of how a cubic curve works, drag the anchors around to change the curve. */
public class testsdfasdf extends Application {
  public static void main(String[] args) throws Exception { launch(args); }


  @Override public void start(Stage primaryStage) throws Exception {
    QuadCurve curve = createStartingCurve();


    final BorderPane root = new BorderPane();
    Scene scene = new Scene(root, 1000, 1000);

    final Anchor control2 = new Anchor(Color.GOLDENROD, curve.controlXProperty(), curve.controlYProperty());


    root.getChildren().add(curve);
    root.getChildren().add(control2);


    primaryStage.setTitle("Quadcurve Manipulation");
    primaryStage.setScene(scene);
    primaryStage.show();
  }

  private QuadCurve createStartingCurve() {
    QuadCurve curve = new QuadCurve();
    curve.setStartX(100);
    curve.setStartY(100);
    curve.setControlX(200);
    curve.setControlY(50);
    curve.setEndX(300);
    curve.setEndY(100);
    curve.setStroke(Color.BLACK);
    curve.setStrokeWidth(10);
    curve.setStrokeLineCap(StrokeLineCap.ROUND);
    curve.setFill(Color.CORNSILK.deriveColor(0, 1.2, 1, 0.6));
    return curve;
  }

  // a draggable anchor displayed around a point.
  class Anchor extends Circle { 

      Anchor(Color color, DoubleProperty x, DoubleProperty y) {
      super(x.get(), y.get(), 10);
      setFill(color.deriveColor(1, 1, 1, 0.5));

      y.bind(centerYProperty());
      enableDrag();
      changeCurve();
    }


    private void changeCurve() {
        setOnKeyPressed((event) -> { 
                System.out.println(event.getCode() == KeyCode.DOWN);
                if (event.getCode() == KeyCode.DOWN) {
                    double newY = getCenterY();
                    while (newY > 0 && newY < getScene().getHeight()) {
                        setCenterY(newY);
                        newY+=1;
                    }
                }
                else if (event.getCode() == KeyCode.UP) {
                    double newY = getCenterY();
                    while (newY > 0 && newY < getScene().getHeight()) {
                        setCenterY(newY);
                        newY-=1;
                    }
                }
        });
        setOnKeyReleased((event) -> {
                if (event.getCode() == KeyCode.DOWN) {
                }
                if (event.getCode() == KeyCode.UP) {
                }

            });
    }

    // make a node movable by dragging it around with the mouse.
    private void enableDrag() {
      setOnMousePressed(new EventHandler<MouseEvent>() {
        @Override public void handle(MouseEvent mouseEvent) {
          // record a delta distance for the drag and drop operation.
          getScene().setCursor(Cursor.MOVE);
        }
      });
      setOnMouseReleased(new EventHandler<MouseEvent>() {
        @Override public void handle(MouseEvent mouseEvent) {
          getScene().setCursor(Cursor.HAND);
        }
      });
      setOnMouseDragged(new EventHandler<MouseEvent>() {
        @Override public void handle(MouseEvent mouseEvent) {
          double newY = mouseEvent.getY();
          System.out.println(newY);
          if (newY > 0 && newY < getScene().getHeight()) {
            setCenterY(newY);
          }  
        }
      });
      setOnMouseEntered(new EventHandler<MouseEvent>() {
        @Override public void handle(MouseEvent mouseEvent) {
          if (!mouseEvent.isPrimaryButtonDown()) {
            getScene().setCursor(Cursor.HAND);
          }
        }
      });
      setOnMouseExited(new EventHandler<MouseEvent>() {
        @Override public void handle(MouseEvent mouseEvent) {
          if (!mouseEvent.isPrimaryButtonDown()) {
            getScene().setCursor(Cursor.DEFAULT);
          }
        }
      });
    }
  }  
}

Maybe there' s too much code here. But that is all to actually draw the curve there and make it draggable with enableDrag() function.

changeCurve() function is not working and that' s the problem.

like image 936
TheLast_BlenderBender Avatar asked Feb 04 '26 12:02

TheLast_BlenderBender


1 Answers

Problem

A node will not listen to events unless they are focused. Your cirle never receives focus and therefore, never reacts to the Key Events.

Solution

One of the easy solutions would be to ask for focus after the stage is displayed.

primaryStage.show();
control2.requestFocus();

Another solution would be to bind the Scene's onKeyPressedProperty to the Circle's onKeyPressedProperty. This will bind all the key press events taking place on the Scene to the Circle.

There might be situations where you would not want to do this..

scene.onKeyPressedProperty().bind(control2.onKeyPressedProperty());

There is also a small issue with your handle() as well. There is no need of the while loop. You just want to setCenterY() to a value less/more than the previous value, depending on the key pressed.

setOnKeyPressed((event) -> {
     if (event.getCode() == KeyCode.DOWN && getCenterY() < getScene().getHeight()){
         setCenterY(getCenterY() + 5);
     } else if (event.getCode() == KeyCode.UP && getCenterY() > 0) {
         setCenterY(getCenterY() - 5);
     }
});
like image 191
ItachiUchiha Avatar answered Feb 07 '26 01:02

ItachiUchiha



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!