java - setOnKeyPressed 事件无法正常工作

标签 java javafx-2 keylistener

我需要为我在大学的项目创建一个带有曲线的生成的类似隧道的东西。我在 Internet 上找到了一些代码,允许我拖动曲线的控制点(附加到 anchor 对象)。

但是,我想通过按箭头键(“向上”和“向下”)来更改控制点 Ylocation 成为可能,但不知何故它根本不起作用。我一直在无可救药地尝试自己解决这个问题,但我找不到出路。

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);
          }
        }
      });
    }
  }  
}

也许这里的代码太多了。但这就是实际在那里绘制曲线并使用 enableDrag() 函数使其可拖动的全部内容。

changeCurve() 函数不起作用,这就是问题所在。

最佳答案

问题

节点不会监听事件,除非它们被聚焦。您的圈子永远不会受到关注,因此永远不会对关键事件使用react。

解决方案

其中一个简单的解决方案是在显示舞台后请求聚焦。

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

另一种解决方案是将场景的 onKeyPressedProperty 绑定(bind)到 Circle 的 onKeyPressedProperty。这会将场景中发生的所有按键事件绑定(bind)到 Circle。

在某些情况下您可能不想这样做..

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

您的 handle() 也有一个小问题。不需要 while 循环。您只想将 setCenterY() 设置为小于/大于先前值的值,具体取决于按下的键。

setOnKeyPressed((event) -> {
     if (event.getCode() == KeyCode.DOWN && getCenterY() < getScene().getHeight()){
         setCenterY(getCenterY() + 5);
     } else if (event.getCode() == KeyCode.UP && getCenterY() > 0) {
         setCenterY(getCenterY() - 5);
     }
});

关于java - setOnKeyPressed 事件无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32802664/

相关文章:

JavaFX 组合框样式按钮(如果可编辑)

java - 保存子类别时出现 Hibernate 异常

java - 如何分别替换同一句话中相同的单词但不同的大小写?

java - 无法访问Java中相同类型的私有(private)成员

utf-8 - 如何取消屏蔽 JavaFX PasswordField 或正确屏蔽 TextField?

JavaFX 应用程序图标

java - 单击按钮后 KeyListener 不起作用

java - 为什么我不能访问面板的 getWidth() 和 getHeight() 函数?

java - JPanel KeyListener 不工作

java - 如何访问 Mule ESB 中的流变量...?