我正在将一个带有大量自定义绘画的Swing/Graphics2D应用程序转换为JavaFX2应用程序.虽然我非常喜欢新的API,但是在绘制椭圆时我似乎有一个性能问题,我希望在鼠标光标下方的任何地方都可以移动鼠标.当我以稳定的方式移动我的鼠标,而不是快速的滑动时,我注意到椭圆总是在鼠标轨迹后面几厘米处被绘制,并且只有在我停止移动光标时才会捕获.这在一个只有极少数节点的场景图中.在我的Swing应用程序中,我没有遇到这个问题.
我想知道这是否是绘制鼠标光标所在的形状的正确方法?
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.SceneBuilder;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Ellipse;
import javafx.scene.shape.EllipseBuilder;
import javafx.stage.Stage;
public class TestApp extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Pane p = new Pane();
final Ellipse ellipse = EllipseBuilder.create().radiusX(10).radiusY(10).fill(Color.RED).build();
p.getChildren().add(ellipse);
p.setOnMouseMoved(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
ellipse.setCenterX(event.getX());
ellipse.setCenterY(event.getY());
}
});
Scene scene = SceneBuilder.create().root(p).width(1024d).height(768d).build();
primaryStage.setScene(scene);
primaryStage.show();
}
}
Run Code Online (Sandbox Code Playgroud)
小更新:我升级到JavaFX 2.2和Java7u6(在Windows 7 64bit上),但似乎没有什么区别.
jew*_*sea 22
下面是一些代码,用于允许在窗格中拖动Label.我没有发现跟踪鼠标的任何明显滞后.
// allow the label to be dragged around.
final Delta dragDelta = new Delta();
label.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
// record a delta distance for the drag and drop operation.
dragDelta.x = label.getLayoutX() - mouseEvent.getSceneX();
dragDelta.y = label.getLayoutY() - mouseEvent.getSceneY();
label.setCursor(Cursor.MOVE);
}
});
label.setOnMouseReleased(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
label.setCursor(Cursor.HAND);
}
});
label.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
label.setLayoutX(mouseEvent.getSceneX() + dragDelta.x);
label.setLayoutY(mouseEvent.getSceneY() + dragDelta.y);
}
});
label.setOnMouseEntered(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
label.setCursor(Cursor.HAND);
}
});
. . .
// records relative x and y co-ordinates.
class Delta { double x, y; }
Run Code Online (Sandbox Code Playgroud)
这是一个使用上面代码的小型完整示例应用程序.
更新 上面的示例,当拖动的对象很小时,仍将滞后于拖动光标的对象.
另一种方法是使用ImageCursor,其包含叠加在被拖动节点的图像表示上的MousePointer,然后在拖动的开始和完成时隐藏并显示实际节点.这意味着节点拖动渲染不会滞后于光标(因为节点的图像表示现在是光标).但是这种方法确实有缺点=> ImageCursors的大小和格式有限制,而且你需要将你的节点转换为Image以将其放置在ImageCursor中,你可能需要高级Node => Image转换操作可在JavaFX 2.2+中获得.
您描述的滞后(在鼠标和拖动的形状之间)是一个已知的JavaFX错误:
https://bugs.openjdk.java.net/browse/JDK-8087922
您可以使用未记录的JVM标志解决此问题(至少在Windows上):
-Djavafx.animation.fullspeed=true
Run Code Online (Sandbox Code Playgroud)
这个标志通常用于内部性能测试,这就是为什么它没有文档,但我们已经使用了几个月,到目前为止它没有任何问题.
编辑:
还有另一种类似的方法来解决这个可能在CPU使用上更容易的错误.只需关闭Prism的垂直同步:
-Dprism.vsync=false
Run Code Online (Sandbox Code Playgroud)
在我们的应用程序中,这些变通方法中的任何一个都解决了滞后; 没有必要同时做到这两点.
| 归档时间: |
|
| 查看次数: |
32346 次 |
| 最近记录: |