setOnKeyPressed事件无法正常工作 [英] setOnKeyPressed event not working properly

查看:180
本文介绍了setOnKeyPressed事件无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要为大学中的项目创建带有曲线的生成的类似隧道的东西.我在Internet上找到了一些代码,这些代码使我可以拖动曲线的控制点(附加到Anchor对象).

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.

但是,我想通过按箭头键(上"和下")来更改控制点Ylocation成为可能,并且它根本不起作用.我一直在试图自己解决这个问题,但是我找不到出路.

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

也许这里的代码太多了.但这就是在此处实际绘制曲线并使用 enableDrag()函数将其拖动的所有操作.

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()函数不起作用,这就是问题所在.

changeCurve() function is not working and that' s the 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.

解决方案

easy 解决方案之一是在舞台显示后要求焦点.

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

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

另一种解决方案是将场景的onKeyPressedProperty绑定到圆的onKeyPressedProperty.这会将在场景上发生的所有按键事件绑定到圆上.

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.

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

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

handle()也有一个小问题.不需要while loop.您只想setCenterY()值小于/大于上一个值,具体取决于所按下的键.

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

这篇关于setOnKeyPressed事件无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆