gpt4 book ai didi

java - 在 javafx 中的 Canvas 上平移

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:55:57 25 4
gpt4 key购买 nike

我正在尝试使用 javafx 2 创建 Canvas ,用户可以在其中平移和缩放。对于静态内容,我的解决方案有效,但一旦内容在用户平移时更新,鼠标事件就会停止工作,直到松开并再次按下鼠标按钮。

以下是演示问题的最小示例。如果您在白色区域中单击,您可以四处平移,但如果您通过单击红色矩形开始平移,则会在内容更新时中断。

class Test extends StackPane
{
private Timer timer = new Timer();
private Rectangle rect;
private double pressedX, pressedY;

public Test()
{
setMinSize(600, 600);
setStyle("-fx-border-color: blue;");

timer.schedule(new TimerTask()
{
@Override
public void run()
{
Platform.runLater(new Runnable()
{
@Override
public void run()
{
if (rect != null)
getChildren().remove(rect);

rect = new Rectangle(10, 10, 200, 200);
rect.setFill(Color.RED);
getChildren().add(rect);
}
});
}
}, 0, 100);

setOnMousePressed(new EventHandler<MouseEvent>()
{
public void handle(MouseEvent event)
{
pressedX = event.getX();
pressedY = event.getY();
}
});

setOnMouseDragged(new EventHandler<MouseEvent>()
{
public void handle(MouseEvent event)
{
setTranslateX(getTranslateX() + event.getX() - pressedX);
setTranslateY(getTranslateY() + event.getY() - pressedY);

event.consume();
}
});
}
}

public class TestApp extends Application
{
public static void main(String[] args)
{
launch(args);
}

@Override
public void start(Stage primaryStage)
{
Scene scene = new Scene(new Test());
primaryStage.setScene(scene);
primaryStage.show();
}
}

我在使用 JDJ7u7 的 Windows 8 64 位系统上。

最佳答案

嗯,我认为你的代码没问题,似乎对我来说运行良好,并且在 Windows 7 上使用 jdk7u7 时没有任何明显的问题。

我想也许您想调用 rect.setMouseTransparent(true),这样矩形就不会捕捉到点击。鼠标透明度与添加和删除矩形无关,它只是 JavaFX 中拾取的工作方式。

您可能需要考虑将您的测试节点放在一个可平移的 ScrollPane 中而不是自己实现平移 - 可能需要将其包装在 Group 中以获得适当的行为。但是您拥有的代码很简单并且似乎可以正常工作,因此可能没有必要使用 ScrollPane,甚至可能会使事情变得更加困惑。

有一个Canvas Java 中的类,这与您拥有的有所不同,因此将您的节点称为 Canvas 以外的名称可能是个好主意。

与您的问题无关,但使用 Timeline是我处理动画的首选方法而不是 Timer,尽管只要您正确使用 Platform.runLater 作为 Timer 方法仍然有效你在做什么。

这是一个使用 Timeline.mouseTransparent() 并添加了帧计数器的修改示例,这样可以清楚地看到动画正在发生。

import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.event.*;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

class Test extends StackPane {
private Rectangle rect;
private double pressedX, pressedY;
private LongProperty frame = new SimpleLongProperty();

public Test() {
setMinSize(600, 600);
setStyle("-fx-border-color: blue;");
Label count = new Label();
count.textProperty().bind(Bindings.convert(frame));
getChildren().add(count);
count.setMouseTransparent(true);

setOnMousePressed(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
pressedX = event.getX();
pressedY = event.getY();
}
});

setOnMouseDragged(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
setTranslateX(getTranslateX() + event.getX() - pressedX);
setTranslateY(getTranslateY() + event.getY() - pressedY);

event.consume();
}
});

Timeline t = new Timeline(new KeyFrame(Duration.millis(100), new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent event) {
frame.set(frame.get() + 1);

if (rect != null) {
getChildren().remove(rect);
}

rect = new Rectangle(10, 10, 200, 200);
rect.setFill(Color.RED);
rect.setMouseTransparent(true);
getChildren().add(0, rect);
}
}));
t.setCycleCount(Timeline.INDEFINITE);
t.play();
}
}

public class TestApplication extends Application {
public static void main(String[] args) { launch(args); }
@Override public void start(Stage stage) {
stage.setScene(new Scene(new Test()));
stage.show();
}
}

Sample program output

关于java - 在 javafx 中的 Canvas 上平移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12375276/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com