custom-controls - 如何在JavaFX中获取鼠标的位置?

标签 custom-controls mouse customization javafx draggable

我是java(fx)的初学者。
你如何在 JavaFX 中获得 x 和 y 中的鼠标位置?我尝试使用 AWT 的 MouseInfo (也导入了它),但它不起作用。我还在 Ensembles 中看到了它的代码(在“高级阶段”中拖动球窗,这就是我需要做的,拖动我未修饰的 JavaFX 阶段),但它也不起作用。我正在将 FXML 与 Controller 一起使用,我想这是主要问题。我应该切换回单文件的简单 JavaFX 吗?我知道 FXML 更适合布置 UI,但我无法让很多这样的代码工作。或者我的 Controller 需要其他类型的代码吗?请尽可能给出带有注释的正确代码。
如果您需要一些我的代码来检查,请随时询问。

最佳答案

您的问题中有几个项目 - 我将一次解决它们。

How do you get the mouse location in x and y in JavaFX?



将鼠标事件处理程序添加到要在其中跟踪鼠标位置的相应 JavaFX 组件。JavaFX 鼠标事件将报告多种不同类型的坐标。 x 和 y 坐标相对于其位置被监控的节点的左上角。 sceneX 和 sceneY 坐标是相对于场景左上角 0,0 坐标的。 screenX 和 screenY 坐标相对于当前屏幕的左上角 0,0 坐标。

这些坐标记录在 MouseEvent 中。文档。在 Node 中有关于理解坐标系的额外信息。和 Scene文档。

mouselocationmonitor
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;
  }
}

I tried using AWT's MouseInfo(also imported it), but it's not working.



不要这样做。混合不同的图形工具包(例如 Swing/AWT 和 JavaFX)是一个高级主题。通常,如果您正在编写 JavaFX 应用程序,请避免从 java.awt 导入任何内容。命名空间和 javax.swing命名空间。如果您有一个大型的、现有的基于 Swing 的应用程序或框架,您需要与 JavaFX 应用程序进行互操作,那么您才真正需要使用它们。在这种情况下,您没有这种情况。

I also saw the code for it in Ensembles(that dragging the ball-window in "advanced stage", that's what I need to do, drag my undecorated JavaFX stage), but it also doesn't work.



我尝试了 Ensemble Advanced Stage 示例并拖动该舞台对我有用。

在 JavaFX 中拖动未装饰舞台的另一个示例是对 How to draw a clock with JavaFX 2? 的回答。其中有 associated sample code .用于使未装饰的舞台可拖动时钟样本的方法是:
/** 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);
      }
    }
  });
}

I am using FXML with controller, and I guess that's the main problem. Should I switch back to the single-file simple JavaFX? I know FXML is better for laying out the UI, but I can't get many of such codes to work.



缺乏对底层 JavaFX API 的理解和熟悉可能是您的主要问题,而不是 FXML 的使用。然而,fxml 所暗示的额外复杂性以及网络上较轻的文档和示例可能会导致您的困难。如果使用 FXML 使您难以理解如何使某些 JavaFX 函数工作,我建议现在停止使用 FXML。使用 Java API 手工编写逻辑代码并引用 Oracle JavaFX tutorialsEnsemble sample code当你遇到对你来说困难的事情时。

一旦您习惯于直接编码到 JavaFX API,请切换回使用 FXML 处理包含许多 GUI 元素的大型项目。 FXML 元素和属性本身几乎完全基于标准 JavaFX API 的反射(reflect)而构建。因此,如果您了解核心 JavaFX API,您也几乎了解 FXML 的所有内容。

请不要对这个答案发表后续评论(因为这个答案已经足够长了)。如果您有新问题,请创建一个新问题(每个问题一个问题)。

关于custom-controls - 如何在JavaFX中获取鼠标的位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16635514/

相关文章:

c# - Unity 2D Mouse Zoom,但放大到鼠标点的位置

java - JInput 的 getPollData() 不起作用

java - 使用 Java 自定义 Pentaho Spoon 组件

android - 具有标准图标、标题和按钮的独立于平台版本的自定义对话框

c# - 指定从基本形式到继承的属性

未应用 WPF 自定义控件模板

vb.net - 如何模拟鼠标点击?

c# - 创建自定义按钮控件

android - android中的自定义切换按钮

php - 如何为横幅添加自定义列而不是右列、左列、顶部列和底部列?