你的问题中有几个问题——我会一次解决一个问题。
如何在 JavaFX 中获取鼠标在 x 和 y 中的位置?
将鼠标事件处理程序添加到要跟踪鼠标位置的相应 JavaFX 组件。JavaFX 鼠标事件将报告多种不同类型的坐标。 x 和 y 坐标相对于正在监视其位置的节点的左上角。 sceneX 和 sceneY 坐标相对于场景的左上角 0,0 坐标。 screenX 和 screenY 坐标相对于当前屏幕的左上角 0,0 坐标。
这些坐标记录在鼠标事件 http://docs.oracle.com/javafx/2/api/javafx/scene/input/MouseEvent.html文档。在理解坐标系方面有额外的信息Node http://docs.oracle.com/javafx/2/api/javafx/scene/Node.html and Scene http://docs.oracle.com/javafx/2/api/javafx/scene/package-summary.html文档。
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.event.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.stage.*;
public class MouseLocationReporter extends Application {
private static final String OUTSIDE_TEXT = "Outside Label";
public static void main(String[] args) { launch(args); }
@Override public void start(final Stage stage) {
final Label reporter = new Label(OUTSIDE_TEXT);
Label monitored = createMonitoredLabel(reporter);
VBox layout = new VBox(10);
layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10px;");
layout.getChildren().setAll(
monitored,
reporter
);
layout.setPrefWidth(500);
stage.setScene(
new Scene(layout)
);
stage.show();
}
private Label createMonitoredLabel(final Label reporter) {
final Label monitored = new Label("Mouse Location Monitor");
monitored.setStyle("-fx-background-color: forestgreen; -fx-text-fill: white; -fx-font-size: 20px;");
monitored.setOnMouseMoved(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent event) {
String msg =
"(x: " + event.getX() + ", y: " + event.getY() + ") -- " +
"(sceneX: " + event.getSceneX() + ", sceneY: " + event.getSceneY() + ") -- " +
"(screenX: " + event.getScreenX()+ ", screenY: " + event.getScreenY() + ")";
reporter.setText(msg);
}
});
monitored.setOnMouseExited(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent event) {
reporter.setText(OUTSIDE_TEXT);
}
});
return monitored;
}
}
我尝试使用AWT的MouseInfo(也导入了它),但它不起作用。
不要这样做。混合不同的图形工具包(例如 Swing/AWT 和 JavaFX)是一个高级主题。一般来说,如果您正在编写 JavaFX 应用程序,请避免从java.awt
命名空间和javax.swing
命名空间。仅当您有一个大型的现有基于 Swing 的应用程序或框架且需要与 JavaFX 应用程序进行互操作时,您才真正需要使用它们。在这种情况下,你就不存在这种情况。
我还在 Ensembles 中看到了它的代码(在“高级阶段”拖动球窗口,这就是我需要做的,拖动我未装饰的 JavaFX 阶段),但它也不起作用。
我尝试了 Ensemble Advanced Stage 示例,拖动该舞台对我来说很有效。
在 JavaFX 中拖动未装饰舞台的另一个示例是在答案中如何使用 JavaFX 2 绘制时钟? https://stackoverflow.com/questions/10541738/how-to-draw-a-clock-with-javafx-2其中有相关示例代码 https://gist.github.com/jewelsea/3388637。用于使时钟样本的未装饰阶段可拖动的方法是:
/** makes a stage draggable using a given node */
public static void makeDraggable(final Stage stage, final Node byNode) {
final Delta dragDelta = new Delta();
byNode.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
// record a delta distance for the drag and drop operation.
dragDelta.x = stage.getX() - mouseEvent.getScreenX();
dragDelta.y = stage.getY() - mouseEvent.getScreenY();
byNode.setCursor(Cursor.MOVE);
}
});
byNode.setOnMouseReleased(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
byNode.setCursor(Cursor.HAND);
}
});
byNode.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
stage.setX(mouseEvent.getScreenX() + dragDelta.x);
stage.setY(mouseEvent.getScreenY() + dragDelta.y);
}
});
byNode.setOnMouseEntered(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
if (!mouseEvent.isPrimaryButtonDown()) {
byNode.setCursor(Cursor.HAND);
}
}
});
byNode.setOnMouseExited(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
if (!mouseEvent.isPrimaryButtonDown()) {
byNode.setCursor(Cursor.DEFAULT);
}
}
});
}
我正在将 FXML 与控制器一起使用,我想这是主要问题。我应该切换回单文件简单 JavaFX 吗?我知道 FXML 更适合布局 UI,但我无法让许多此类代码正常工作。
您的主要问题可能是缺乏对底层 JavaFX API 的理解和熟悉,而不是使用 FXML。然而,fxml 带来的额外复杂性以及网络上较轻的文档和示例可能会给您带来困难。如果使用 FXML 使您难以理解如何使某些 JavaFX 函数发挥作用,我建议暂时停止使用 FXML。使用 Java API 手动编写逻辑并参考Oracle JavaFX 教程 http://docs.oracle.com/javafx/和集成示例代码 http://www.oracle.com/technetwork/java/javafx/samples/index.html当你遇到对你来说困难的事情时。
一旦您习惯了直接使用 JavaFX API 进行编码,就可以切换回使用 FXML 来处理包含许多 GUI 元素的大型项目。 FXML 元素和属性本身几乎完全基于标准 JavaFX API 的反映而构建。因此,如果您了解核心 JavaFX API,您也就了解了有关 FXML 的几乎所有内容。
请不要对此答案发表后续评论(因为这个答案已经足够长了)。如果您有新问题,请创建一个新问题(每个问题一个问题)。