Java setOnKeyPressed事件未正常工作

Java setOnKeyPressed事件未正常工作,java,javafx-2,keylistener,Java,Javafx 2,Keylistener,我需要为我在大学的项目创建一个生成的带有曲线的隧道状物体。我在网上找到一些代码,允许我拖动曲线的控制点(连接到锚定对象) 然而,我想通过按箭头键(“向上”和“向下”)来改变控制点的位置,但不知何故它根本不起作用。我一直试图自己解决这个问题,但我找不到出路 import javafx.application.Application; import javafx.beans.property.DoubleProperty; import javafx.event.EventHandler; impo

我需要为我在大学的项目创建一个生成的带有曲线的隧道状物体。我在网上找到一些代码,允许我拖动曲线的控制点(连接到锚定对象)

然而,我想通过按箭头键(“向上”和“向下”)来改变控制点的位置,但不知何故它根本不起作用。我一直试图自己解决这个问题,但我找不到出路

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);
          }
        }
      });
    }
  }  
}
导入javafx.application.application;
导入javafx.beans.property.DoubleProperty;
导入javafx.event.EventHandler;
导入javafx.scene.*;
导入javafx.scene.input.KeyCode;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.*;
导入javafx.stage.stage;
/**有关立方曲线如何工作的示例,请拖动定位点以更改曲线*/
公共类testsdfasdf扩展了应用程序{
公共静态void main(字符串[]args)引发异常{launch(args);}
@覆盖公共无效开始(阶段primaryStage)引发异常{
QuadCurve curve=createStartingCurve();
最终边界窗格根=新边界窗格();
场景=新场景(根,1000,1000);
最终锚定控件2=新锚定(Color.GOLDENROD,curve.controlXProperty(),curve.controlYProperty());
root.getChildren().add(曲线);
root.getChildren().add(control2);
primaryStage.setTitle(“四次曲线操纵”);
初级阶段。场景(场景);
primaryStage.show();
}
专用四元曲线createStartingCurve(){
四元曲线=新的四元曲线();
曲线.setStartX(100);
曲线设置起点(100);
曲线。setControlX(200);
曲线设置控制(50);
曲线.setEndX(300);
曲线:setEndY(100);
曲线设定行程(颜色为黑色);
曲线设定行程宽度(10);
曲线设置行程盖(行程盖圆形);
曲线.刚毛填充(颜色.玉米丝.衍生色(0,1.2,1,0.6));
回归曲线;
}
//围绕点显示的可拖动锚。
类锚扩展圆{
锚定(颜色、双属性x、双属性y){
super(x.get(),y.get(),10);
setFill(颜色:deriveColor(1,1,1,0.5));
y、 绑定(centerYProperty());
enableDrag();
改变曲线();
}
私有void changeCurve(){
setOnKeyPressed((事件)->{
System.out.println(event.getCode()==KeyCode.DOWN);
if(event.getCode()==KeyCode.DOWN){
double newY=getCenterY();
而(newY>0&&newY0&&newY{
if(event.getCode()==KeyCode.DOWN){
}
if(event.getCode()==KeyCode.UP){
}
});
}
//使用鼠标拖动节点,使其可移动。
私有void enableDrag(){
setOnMousePressed(新的EventHandler(){
@重写公共无效句柄(MouseEvent MouseEvent){
//记录拖放操作的增量距离。
getScene().setCursor(Cursor.MOVE);
}
});
setOnMouseReleased(新的EventHandler(){
@重写公共无效句柄(MouseEvent MouseEvent){
getScene().setCursor(Cursor.HAND);
}
});
SetOnMouseDrawed(新的EventHandler(){
@重写公共无效句柄(MouseEvent MouseEvent){
double newY=mouseEvent.getY();
System.out.println(newY);
如果(newY>0&&newY
也许这里的代码太多了。但这就是实际绘制曲线的全部内容,并使用enableDrag()函数将其拖动


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

问题

节点将不会侦听事件,除非它们被聚焦。你的漩涡从未获得焦点,因此,从未对关键事件做出反应

解决方案

其中一个简单的解决办法是在舞台展示后要求聚焦

primaryStage.show();
control2.requestFocus();
另一种解决方案是将场景的
onKeyPressedProperty
绑定到圆的
onKeyPressedProperty
。这会将场景中发生的所有按键事件绑定到圆圈

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

您的
句柄()
也有一个小问题。不需要
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);
     }
});
setOnKeyPressed((事件)->{
if(event.getCode()==KeyCode.DOWN&&getCenterY()0){
setCenterY(getCenterY()-5);
}
});

问题

节点将不会列出
setOnKeyPressed((event) -> {
     if (event.getCode() == KeyCode.DOWN && getCenterY() < getScene().getHeight()){
         setCenterY(getCenterY() + 5);
     } else if (event.getCode() == KeyCode.UP && getCenterY() > 0) {
         setCenterY(getCenterY() - 5);
     }
});