在javafx中的画布上平移
我正在尝试使用JavaFX2创建一个画布,用户可以在其中平移和缩放。对于静态内容,我的解决方案是有效的,但一旦用户在平移时内容得到更新,鼠标事件就会停止工作,直到释放并再次按下鼠标按钮 下面是一个演示该问题的简单示例。如果在白色区域中单击,则可以进行平移,但如果单击红色矩形开始平移,则内容更新时会中断在javafx中的画布上平移,java,javafx-2,Java,Javafx 2,我正在尝试使用JavaFX2创建一个画布,用户可以在其中平移和缩放。对于静态内容,我的解决方案是有效的,但一旦用户在平移时内容得到更新,鼠标事件就会停止工作,直到释放并再次按下鼠标按钮 下面是一个演示该问题的简单示例。如果在白色区域中单击,则可以进行平移,但如果单击红色矩形开始平移,则内容更新时会中断 class Test extends StackPane { private Timer timer = new Timer(); private Rectangle rect;
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();
}
}
类测试扩展StackPane
{
专用计时器=新计时器();
私有矩形矩形;
私人双按X,按Y;
公开考试()
{
setMinSize(600600);
setStyle(“-fx边框颜色:蓝色;”);
timer.schedule(新TimerTask()
{
@凌驾
公开募捐
{
Platform.runLater(新的Runnable()
{
@凌驾
公开募捐
{
if(rect!=null)
getChildren().remove(rect);
rect=新矩形(10,10,200,200);
矩形设置填充(颜色为红色);
getChildren().add(rect);
}
});
}
}, 0, 100);
setOnMousePressed(新的EventHandler()
{
公共无效句柄(MouseeEvent事件)
{
pressedX=event.getX();
pressedY=event.getY();
}
});
SetOnMouseDrawed(新的EventHandler()
{
公共无效句柄(MouseeEvent事件)
{
setTranslateX(getTranslateX()+event.getX()-按X);
setTranslateY(getTranslateY()+event.getY()-pressedY);
event.consume();
}
});
}
}
公共类TestApp扩展了应用程序
{
公共静态void main(字符串[]args)
{
发射(args);
}
@凌驾
公共无效开始(阶段primaryStage)
{
场景=新场景(新测试());
初级阶段。场景(场景);
primaryStage.show();
}
}
我在使用JDJ7u7的64位Windows 8上。我认为您的代码还可以,对我来说似乎运行良好,在Windows 7上使用jdk7u7操作时没有任何明显问题 我想您可能需要调用
rect.setMouseTransparent(true)
,这样矩形就不会捕捉到点击。鼠标透明度的问题与添加和删除矩形无关,它只是JavaFX中拾取的工作方式
您可能想考虑将测试节点放置在一个可佩戴的,而不是实现您自己的摇摄-可能需要将其封装在
,甚至可能会使事情更加混乱滚动窗格
Canvas
可能是一个好主意
这与您的问题无关,但我更喜欢使用一种方式来处理动画,而不是使用计时器
,尽管计时器
方法仍然有效,只要您正确使用平台。请稍后运行
下面是一个修改过的示例,它使用了时间线
和.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();
}
}
导入javafx.animation.*;
导入javafx.application.application;
导入javafx.beans.binding.Bindings;
导入javafx.beans.property.*;
导入javafx.event.*;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.layout.StackPane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Rectangle;
导入javafx.stage.stage;
导入javafx.util.Duration;
类测试扩展了StackPane{
私有矩形矩形;
私人双按X,按Y;
私有LongProperty框架=新的SimpleLongProperty();
公开考试(){
setMinSize(600600);
setStyle(“-fx边框颜色:蓝色;”);
标签计数=新标签();
count.textProperty().bind(Bindings.convert(frame));
getChildren().add(count);
count.setMouseTransparent(true);
setOnMousePressed(新的EventHandler(){
公共无效句柄(MouseeEvent事件){
pressedX=event.getX();
pressedY=event.getY();
}
});
SetOnMouseDrawed(新的EventHandler(){
公共无效句柄(MouseeEvent事件){
setTranslateX(getTranslateX()+event.getX()-按X);
setTranslateY(getTranslateY()+event.getY()-pressedY);
event.consume();
}
});
时间线t=新的时间线(新的关键帧(Duration.millis(100),新的EventHandler(){
@重写公共无效句柄(ActionEvent事件){
frame.set(frame.get()+1);
if(rect!=null){
getChildren().remove(rect);
}
rect=新矩形(10,10,200,200);
矩形设置填充(颜色为红色);
rect.setMouseTransparent(true);
getChildren().add(0,rect);
}
}));
t、 setCycleCount(Timeline.unfinite);
t、 play();
}
}
公共类TestApplication扩展了应用程序{
公共静态void main(字符串[]args){launch(args);}
@覆盖公共无效开始(阶段){
stage.setScene(新场景(新测试());
stage.show();
}
}
非常感谢!setMouseTransparent(true)方法正是我想要的。其他点也很好,但它们不适用于我的实际项目,仅适用于我的小示例,它们仍然是有效的点!