如何在JavaFX中获取鼠标的位置? [英] How to get location of mouse in JavaFX?

查看:3876
本文介绍了如何在JavaFX中获取鼠标的位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是java(fx)的初学者。

如何在JavaFX中获得x和y中的鼠标位置?我尝试使用AWT的 MouseInfo (也导入它),但它无法正常工作。我也在Ensembles中看到了它的代码(在高级阶段拖动球窗,这就是我需要做的,拖动我未修饰的JavaFX阶段),但它也不起作用。我正在使用带控制器的FXML,我猜这是主要问题。我应该切换回单文件简单的JavaFX吗?我知道FXML更适合布局用户界面,但我不能让很多这样的代码工作。或者我的控制器是否需要其他类型的代码?请尽可能给出带有注释的正确代码。

如果您需要我的代码进行检查,请随时询问。

解决方案

你的问题中有几个项目 - 我会一次解决一个问题。


如何在JavaFX中获取x和y中的鼠标位置?


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



这些坐标记录在,其中包含相关示例代码。用于使时钟样本可拖动的未修饰阶段的方法是:

  / **使用给定节点使一个阶段可拖动* / 
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){
//记录拖放操作的增量距离。
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更适合布局用户界面,但我不能让很多这样的代码工作。


缺乏理解熟悉底层JavaFX API可能是你的主要问题,而不是使用FXML。然而,fxml的额外复杂性意味着更轻的文档和网上的样本可能会助长您的艰辛。如果使用FXML使您难以理解如何使某些JavaFX功能起作用,我建议暂时停止使用FXML。使用Java API手动编写逻辑代码,并参考 Oracle JavaFX教程合奏示例代码



一旦您熟悉直接编写JavaFX API,请切换回使用FXML来处理包含许多GUI元素的大型项目。 FXML元素和属性本身几乎完全是在反映标准JavaFX API的基础上构建的。所以,如果您了解核心JavaFX API,您几乎可以理解FXML的所有内容。



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


I am a beginner in java(fx).
How do you get the mouse location in x and y in JavaFX? I tried using AWT's MouseInfo(also imported it), but it's not working. 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. 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. Or do I need some other sort of code for my controller? Please give proper codes with comments wherever possible.
If you need a bit of my code to inspect, feel free to ask.

解决方案

There are a few items in your question - I'll tackle them one at a time.

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

Add a mouse event handler to the appropriate JavaFX component that you want to track the mouse location in. A JavaFX mouse event will report multiple different kinds of co-ordinates. The x and y co-ordinates are relative to the top left corner of the node whose location is being monitored. The sceneX and sceneY co-ordinates are relative to the scene's top left 0,0 co-ordinates. The screenX and screenY co-ordinates are relative to the top left 0,0 co-ordinates of the current screen.

These co-ordinates are documented in the MouseEvent documentation. There is extra information in understanding co-ordinate systems in the Node and Scene documentation.

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.

Don't do this. Mixing different graphical toolkits (for example Swing/AWT and JavaFX) is an advanced topic. In general, if you are writing a JavaFX application, avoid importing anything from the java.awt namespace and the javax.swing namespace. You only really need to use those if you have a large, existing Swing based application or framework that you need to inter-operate with your JavaFX application. In this case, you don't have that situation.

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.

I tried the Ensemble Advanced Stage sample and dragging that stage around worked for me.

Another sample for dragging an undecorated stage in JavaFX is in the answer to How to draw a clock with JavaFX 2? which has associated sample code. The method used to make the undecorated stage draggable for the clock sample is:

/** 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.

Lack of understanding and familiarity with the underlying JavaFX APIs is probably your main problem rather than use of FXML. However the additional complexity fxml implies together with the lighter documentation and samples for it on the web may be contributing to your hardships. If use of FXML is making it difficult for you to understand how to get some JavaFX functions to work, I advise to stop using FXML for now. Code the logic by hand using the Java APIs and refer to the Oracle JavaFX tutorials and the Ensemble sample code when you encounter things which are difficult for you.

Once you are comfortable coding directly to the JavaFX API, switch back to using FXML for larger projects which contain many GUI elements. The FXML elements and attributes themselves are built almost completely upon reflection of the standard JavaFX APIs. So, if you understand the core JavaFX APIs, you also understand almost everything about FXML.

Please do not post follow up comments to this answer (as this answer is long enough as it is). If you have new questions, create a new question (one question per question).

这篇关于如何在JavaFX中获取鼠标的位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆