Я не понимаю, почему это происходит. В настоящее время я пытаюсь перетащить узел (Canvas), щелкнув его правой кнопкой мыши, нажав правой кнопкой мыши и перемещая мышь. Сначала он плавный, но затем он начинает получать этот странный джиттер. Это происходит только тогда, когда я удерживаю кнопку мыши. Если вы отпустите его, тогда он вернется к норме (но может очень быстро получить дрожь снова).Точность определения местоположения JavaFX MouseEvent ухудшается с течением времени, приводит к дрожанию узла.
С некоторой отладкой кажется, что чем больше вы его перемещаете, тем больше вы получаете эту «неточность» между каждым событием перетаскивания, когда положение мыши больше не синхронизируется. Конечным результатом является то, что он переворачивает flops взад и вперед, что выглядит очень плохо. используется
Код:
Main.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("CanvasPane.fxml"));
Pane root = fxmlLoader.load();
Scene scene = new Scene(root, 512, 512);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Controller.java
import javafx.fxml.FXML;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.StrokeLineCap;
import javafx.scene.shape.StrokeLineJoin;
public class Controller {
@FXML
private Pane rootPane;
@FXML
private Canvas canvas;
private double mouseX;
private double mouseY;
@FXML
private void initialize() {
GraphicsContext gc = canvas.getGraphicsContext2D();
// Set the writing pen.
gc.setLineCap(StrokeLineCap.ROUND);
gc.setLineJoin(StrokeLineJoin.ROUND);
gc.setLineWidth(1);
gc.setStroke(Color.BLACK);
// Set the background to be transparent.
gc.setFill(Color.BLUE);
gc.fillRect(0, 0, 256, 256);
// Handle moving the canvas.
canvas.setOnMousePressed(e -> {
if (e.getButton() == MouseButton.PRIMARY) {
gc.moveTo(e.getX(), e.getY());
} else if (e.getButton() == MouseButton.SECONDARY) {
mouseX = e.getX();
mouseY = e.getY();
}
});
canvas.setOnMouseDragged(e -> {
if (e.getButton() == MouseButton.PRIMARY) {
gc.lineTo(e.getX(), e.getY());
gc.stroke();
} else if (e.getButton() == MouseButton.SECONDARY) {
double newMouseX = e.getX();
double newMouseY = e.getY();
double deltaX = newMouseX - mouseX;
double deltaY = newMouseY - mouseY;
canvas.setLayoutX(canvas.getLayoutX() + deltaX);
canvas.setLayoutY(canvas.getLayoutY() + deltaY);
mouseX = newMouseX;
mouseY = newMouseY;
// Debug: Why is this happening?
if (Math.abs(deltaX) > 4 || Math.abs(deltaY) > 4)
System.out.println(deltaX + " " + deltaY);
}
});
}
}
CanvasPane.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.canvas.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.Pane?>
<Pane fx:id="rootPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="0.0" minWidth="0.0" prefHeight="512.0" prefWidth="512.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="your-controller-here">
<children>
<Canvas fx:id="canvas" height="256.0" layoutX="122.0" layoutY="107.0" width="256.0" />
</children>
</Pane>
ИНСТРУКЦИЯ ПО ИСПОЛЬЗОВАНИЮ
1) Запустить приложение
2) Щелкните правой кнопкой мыши на холсте и переместить его очень немного (например, только один пиксел в секунду)
3) Переместить это немного быстрее, поэтому отладочные отпечатки
4) Когда вы возвращаетесь к медленному движению, по какой-то причине вы увидите, как он прыгает взад-вперед (как дельта-движение между старым и новым положением больше 5 пикселей), хотя вы только переместили его на один пиксель.
Затем он пытается исправить себя в следующий раз, когда вы двигаетесь, что придает ему уродливый нервный взгляд.
Причина я смущен, потому что бывают случаи, когда он прекрасно работает, а затем точность только падает, как вы продолжайте перетаскивать.
Я сделал что-то неправильно, или это потенциальная ошибка?