当我将光标移动到 2D 内容上时,移动的 3D 对象将在 JavaFX 中冻结 [英] When I move the cursor over a 2D stuff the moving 3D objects will freeze in JavaFX

查看:27
本文介绍了当我将光标移动到 2D 内容上时,移动的 3D 对象将在 JavaFX 中冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Scene 在 3D 事物的 SubScene 上显示 2D 事物.

我正在使用计时器移动立方体.

问题是当我将光标移动到 2D 内容上时,移动的 3D 框会冻结.

这是有关该问题的视频:

import javafx.animation.Animation;导入 javafx.animation.KeyFrame;导入 javafx.animation.KeyValue;导入 javafx.animation.Timeline;导入 javafx.application.Application;导入 javafx.geometry.Point3D;导入 javafx.scene.Group;导入 javafx.scene.PerspectiveCamera;导入 javafx.scene.Scene;导入 javafx.scene.SubScene;导入 javafx.scene.control.Button;导入 javafx.scene.input.ScrollEvent;导入 javafx.scene.layout.AnchorPane;导入 javafx.scene.paint.Color;导入 javafx.scene.shape.Box;导入 javafx.scene.transform.Rotate;导入 javafx.stage.Stage;导入 javafx.util.Duration;/*** https://stackoverflow.com/q/69153580/230513*/公共类 Main 扩展应用程序 {私有静态最终整数宽度 = 640;私有静态最终整数高度 = 480;私人最终框 b1 = 新框 (100, 100, 100);私人最终旋转 r = new Rotate(0, Rotate.Y_AXIS);@覆盖公共无效开始(阶段primaryStage){AnchorPane globalRoot = new AnchorPane();场景场景=新场景(globalRoot,WIDTH,HEIGHT);PerspectiveCamera 相机 = new PerspectiveCamera();相机.setTranslateZ(-100);组 root3D = new Group();SubScene sub = new SubScene(root3D, WIDTH, HEIGHT);sub.setCamera(相机);sub.setFill(Color.BLACK);b1.getTransforms().add(r);root3D.getChildren().add(b1);globalRoot.getChildren().add(sub);globalRoot.getChildren().add(new Button("Just a button"));primaryStage.setScene(场景);scene.setOnScroll((final ScrollEvent e) -> {camera.setTranslateZ(camera.getTranslateZ() + e.getDeltaY());});primaryStage.show();动画动画 = createTimeline(new Point3D(b1.getTranslateX(),b1.getTranslateY(), b1.getTranslateZ()), new Point3D(WIDTH, HEIGHT, 0));动画播放();}public static void startTimer() {}私人时间线 createTimeline(Point3D p1, Point3D p2) {时间线 t = 新时间线();t.setCycleCount(Timeline.INDEFINITE);t.setAutoReverse(true);KeyValue keyX = new KeyValue(b1.translateXProperty(), p2.getX() - p1.getX());KeyValue keyY = new KeyValue(b1.translateYProperty(), p2.getY() - p1.getY());KeyValue keyR = new KeyValue(r.angleProperty(), 2 * 360);KeyFrame keyFrame = new KeyFrame(Duration.seconds(1), keyX, keyY, keyR);t.getKeyFrames().add(keyFrame);返回 t;}公共静态无效主(字符串 [] args){发射(参数);}}

I'm using Scene for showing 2D stuff over a SubScene for 3D things.

I'm moving the cube using a timer.

The problem is when I move the cursor to over a 2D stuff the moving 3D box will freeze.

Here's a video about the problem: https://drive.google.com/file/d/1Gix2uUBCFNnTxXUtyMsv9MUtQsnx0aLG/view?usp=sharing

And here's the code:

package application;
    
import java.util.Timer;
import java.util.TimerTask;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.SubScene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;

public class Main extends Application {
    public static TimerTask timertask1;
    public static Timer timer = new Timer();
    public static Box b1 = new Box(5,5,5);
    @Override public void start(Stage primaryStage) {
        AnchorPane globalRoot = new AnchorPane();
        Scene scene = new Scene(globalRoot, 1366, 768, true);
        PerspectiveCamera camera = new PerspectiveCamera(true);
        Group root3D = new Group();
        SubScene sub = new SubScene(root3D,1366,768,false,SceneAntialiasing.BALANCED);
        camera.getTransforms().addAll(new Rotate(30, Rotate.X_AXIS), new Translate(0, 0, -80));
        sub.setCamera(camera);
        sub.setFill(Color.BLACK);
        globalRoot.getChildren().add(sub);
        root3D.getChildren().add(b1);
        globalRoot.getChildren().add(new Button("Just a button"));
        primaryStage.setFullScreen(true);
        primaryStage.setFullScreenExitHint("");
        primaryStage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
        primaryStage.setScene(scene);
        primaryStage.show();
       startTimer();
    }
     public static void startTimer() { 
            timertask1 = new TimerTask() {
                @Override public void run() {               
                    b1.setTranslateX(b1.getTranslateX()+0.1);                   
                }}; timer.scheduleAtFixedRate(timertask1, 0, 10);}
    public static void main(String[] args) {
        launch(args);
    }
}

Where is my mistake?

解决方案

As noted here, your timer incorrecly alters the scene from another thread. Instead, use a Timeline, as shown here. The variation below moves the Box from the SubScene origin at the top left to the lower right, while also rotating it about the Y_AXIS. Scroll the mouse to dolly the camera to and fro.

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.geometry.Point3D;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SubScene;
import javafx.scene.control.Button;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
 * https://stackoverflow.com/q/69153580/230513
 */
public class Main extends Application {

    private static final int WIDTH = 640;
    private static final int HEIGHT = 480;
    private final Box b1 = new Box(100, 100, 100);
    private final Rotate r = new Rotate(0, Rotate.Y_AXIS);

    @Override
    public void start(Stage primaryStage) {
        AnchorPane globalRoot = new AnchorPane();
        Scene scene = new Scene(globalRoot, WIDTH, HEIGHT);
        PerspectiveCamera camera = new PerspectiveCamera();
        camera.setTranslateZ(-100);
        Group root3D = new Group();
        SubScene sub = new SubScene(root3D, WIDTH, HEIGHT);
        sub.setCamera(camera);
        sub.setFill(Color.BLACK);
        b1.getTransforms().add(r);
        root3D.getChildren().add(b1);
        globalRoot.getChildren().add(sub);
        globalRoot.getChildren().add(new Button("Just a button"));
        primaryStage.setScene(scene);
        scene.setOnScroll((final ScrollEvent e) -> {
            camera.setTranslateZ(camera.getTranslateZ() + e.getDeltaY());
        });
        primaryStage.show();
        Animation animation = createTimeline(new Point3D(b1.getTranslateX(),
            b1.getTranslateY(), b1.getTranslateZ()), new Point3D(WIDTH, HEIGHT, 0));
        animation.play();
    }

    public static void startTimer() {
    }

    private Timeline createTimeline(Point3D p1, Point3D p2) {
        Timeline t = new Timeline();
        t.setCycleCount(Timeline.INDEFINITE);
        t.setAutoReverse(true);
        KeyValue keyX = new KeyValue(b1.translateXProperty(), p2.getX() - p1.getX());
        KeyValue keyY = new KeyValue(b1.translateYProperty(), p2.getY() - p1.getY());
        KeyValue keyR = new KeyValue(r.angleProperty(), 2 * 360);
        KeyFrame keyFrame = new KeyFrame(Duration.seconds(1), keyX, keyY, keyR);
        t.getKeyFrames().add(keyFrame);
        return t;
    }

    public static void main(String[] args) {
        launch(args);
    }
}

这篇关于当我将光标移动到 2D 内容上时,移动的 3D 对象将在 JavaFX 中冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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