JavaFx 处理从节点或主节点的 FXML 控制器拖动节点?
JavaFx handle dragging nodes from FXML controller of node or main?
我正在尝试拖动一些自定义节点。这些节点作为子节点添加到 AnchorPane,如根 FXML 的控制器中所定义:
package sample;
import ...
public class Controller {
@FXML
AnchorPane anchorPane;
public void add() {
try {
// Node.fxml is the custom node object
Parent root = FXMLLoader.load(getClass().getResource("Node.fxml"));
anchorPane.getChildren().add(root);
} catch (IOException e) {
e.printStackTrace();
}
}
}
我应该在根 FXML 控制器内处理我的节点拖动,还是在可拖动节点本身的 FXML 控制器内处理?
如果我应该在根 FXML 控制器中执行此操作,我该怎么做?调用 FXMLLoader.Load() 只是引用一个 FXML 文件,因此我无法将鼠标事件附加到它。
我对 Java 和 JavaFx 还很陌生,所以任何东西都有帮助。 (但是,不是编程初学者)。
提前致谢。
感谢@fabian 和@Gikkman,我找到了解决问题的方法。
我的错误是不理解 Parent 扩展了 Node——我以为我需要引用其他东西。
为了实现我想要的拖动功能,我创建了一个函数,它有一个 Node 输入变量(感谢@Gikkman)——然后这个 Node 对象可以附加事件处理程序。由于 Parent 扩展了 Node(我没有意识到),我可以轻松地使用 FXMLLoader.Load() 作为输入。
所以我有:
package sample;
import ...
import java.io.IOException;
public class Controller {
@FXML
AnchorPane anchorPane;
public void add() {
try {
// Node.fxml is the custom node object
Parent root = FXMLLoader.load(getClass().getResource("Node.fxml"));
// Sets the EventHandlers for dragging
dragNode(root);
// Adds the node to the scene
anchorPane.getChildren().add(root);
} catch (IOException e) {
e.printStackTrace();
}
}
// Handles all dragging EventHandlers for any node object
public void dragNode(Node node) {
// Custom object to hold x and y positions
final Delta dragDelta = new Delta();
node.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
dragDelta.x = node.getLayoutX() - mouseEvent.getSceneX();
dragDelta.y = node.getLayoutY() - mouseEvent.getSceneY();
}
});
node.setOnMouseReleased(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
node.setCursor(Cursor.HAND);
}
});
node.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
node.setLayoutX(mouseEvent.getSceneX() + dragDelta.x);
node.setLayoutY(mouseEvent.getSceneY() + dragDelta.y);
}
});
node.setOnMouseEntered(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
node.setCursor(Cursor.HAND);
}
});
}
class Delta { double x, y; }
}
我正在尝试拖动一些自定义节点。这些节点作为子节点添加到 AnchorPane,如根 FXML 的控制器中所定义:
package sample;
import ...
public class Controller {
@FXML
AnchorPane anchorPane;
public void add() {
try {
// Node.fxml is the custom node object
Parent root = FXMLLoader.load(getClass().getResource("Node.fxml"));
anchorPane.getChildren().add(root);
} catch (IOException e) {
e.printStackTrace();
}
}
}
我应该在根 FXML 控制器内处理我的节点拖动,还是在可拖动节点本身的 FXML 控制器内处理?
如果我应该在根 FXML 控制器中执行此操作,我该怎么做?调用 FXMLLoader.Load() 只是引用一个 FXML 文件,因此我无法将鼠标事件附加到它。
我对 Java 和 JavaFx 还很陌生,所以任何东西都有帮助。 (但是,不是编程初学者)。
提前致谢。
感谢@fabian 和@Gikkman,我找到了解决问题的方法。 我的错误是不理解 Parent 扩展了 Node——我以为我需要引用其他东西。
为了实现我想要的拖动功能,我创建了一个函数,它有一个 Node 输入变量(感谢@Gikkman)——然后这个 Node 对象可以附加事件处理程序。由于 Parent 扩展了 Node(我没有意识到),我可以轻松地使用 FXMLLoader.Load() 作为输入。
所以我有:
package sample;
import ...
import java.io.IOException;
public class Controller {
@FXML
AnchorPane anchorPane;
public void add() {
try {
// Node.fxml is the custom node object
Parent root = FXMLLoader.load(getClass().getResource("Node.fxml"));
// Sets the EventHandlers for dragging
dragNode(root);
// Adds the node to the scene
anchorPane.getChildren().add(root);
} catch (IOException e) {
e.printStackTrace();
}
}
// Handles all dragging EventHandlers for any node object
public void dragNode(Node node) {
// Custom object to hold x and y positions
final Delta dragDelta = new Delta();
node.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
dragDelta.x = node.getLayoutX() - mouseEvent.getSceneX();
dragDelta.y = node.getLayoutY() - mouseEvent.getSceneY();
}
});
node.setOnMouseReleased(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
node.setCursor(Cursor.HAND);
}
});
node.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
node.setLayoutX(mouseEvent.getSceneX() + dragDelta.x);
node.setLayoutY(mouseEvent.getSceneY() + dragDelta.y);
}
});
node.setOnMouseEntered(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
node.setCursor(Cursor.HAND);
}
});
}
class Delta { double x, y; }
}