欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaFX学习之样例4 博客分类: javafx分享 javamoveevent移动 

程序员文章站 2024-02-28 22:37:10
...
  该代码主要是通过键盘和鼠标移动物体
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.control.Label;
import javafx.scene.input.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class MovementEventsDemo extends Application {
  private static final int      KEYBOARD_MOVEMENT_DELTA = 5;
  private static final Duration TRANSLATE_DURATION      = Duration.seconds(1);

  public static void main(String[] args) { launch(args); }
  @Override public void start(Stage stage) throws Exception {
    final Circle circle = createCircle();
    final Group group = new Group(createInstructions(), circle);
    final TranslateTransition transition = createTranslateTransition(circle);
    
    final Scene scene = new Scene(group, 600, 400, Color.CORNSILK);
    moveCircleOnKeyPress(scene, circle);
    moveCircleOnMousePress(scene, circle, transition);
    
    stage.setScene(scene);
    stage.show();
  }

  private Label createInstructions() {
    Label instructions = new Label(
      "Use the arrow keys to move the circle in small increments\n" +
      "Click the mouse to move the circle to a given location\n" +
      "Ctrl + Click the mouse to slowly translate the circle to a given location"      
    );
    instructions.setTextFill(Color.FORESTGREEN);
    return instructions;
  }

  private Circle createCircle() {
    final Circle circle = new Circle(200, 150, 50, Color.BLUEVIOLET);
    circle.setOpacity(0.7); //设置透明度
    return circle;
  }

  private TranslateTransition createTranslateTransition(final Circle circle) {
    final TranslateTransition transition = new TranslateTransition(TRANSLATE_DURATION, circle);
    transition.setOnFinished(new EventHandler<ActionEvent>() {
      @Override public void handle(ActionEvent t) {
        circle.setCenterX(circle.getTranslateX() + circle.getCenterX());
        circle.setCenterY(circle.getTranslateY() + circle.getCenterY());
        circle.setTranslateX(0);
        circle.setTranslateY(0);
      }
    });
    return transition;
  }

  //键盘事件,通过event.getCode()判断是哪个键输入。
  private void moveCircleOnKeyPress(Scene scene, final Circle circle) {
    scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
      @Override public void handle(KeyEvent event) {
        switch (event.getCode()) {
          case UP:    circle.setCenterY(circle.getCenterY() - KEYBOARD_MOVEMENT_DELTA); break;
          case RIGHT: circle.setCenterX(circle.getCenterX() + KEYBOARD_MOVEMENT_DELTA); break;
          case DOWN:  circle.setCenterY(circle.getCenterY() + KEYBOARD_MOVEMENT_DELTA); break;
          case LEFT:  circle.setCenterX(circle.getCenterX() - KEYBOARD_MOVEMENT_DELTA); break;
        }
      }
    });
  }

  //鼠标按下事件
  private void moveCircleOnMousePress(Scene scene, final Circle circle, final TranslateTransition transition) {
    scene.setOnMousePressed(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent event) {
        if (!event.isControlDown()) {  //判断是否按下ctrl键,没有直接设置circle位置,有则慢慢移动
          circle.setCenterX(event.getSceneX());
          circle.setCenterY(event.getSceneY());
        } else {
          transition.setToX(event.getSceneX() - circle.getCenterX());
          transition.setToY(event.getSceneY() - circle.getCenterY());
          transition.playFromStart();
        }  
      }
    });
  }
}

该代码简单
值得注意的地方便是在transition完后,重置circle的center和translate。因为circle的实际位置时layout+center+translate。当你按下ctrl键移动时,则translate有了值,然后松开ctrl键,直接点击,此时circle的实际位置应该是circle.setCenterX(event.getSceneX())+translate的值。
一般circle都是直接设置center的,不用到layout