java - 如何从 X、Y 坐标中检索舞台?
问题描述
我正在尝试将 JavaFX 中的事件从一个离散阶段发送到另一个阶段。这些 Stage 没有任何共同的父级链接,也不是另一个的子级,因此没有层次结构或树可供我尝试遍历以找到 Stage。
在这一点上,我试图能够从我的屏幕上的 X、Y 坐标获取舞台。我认为这将是一种获取可以用作 EventTarget 的东西的方法。
但是,我对这个特定问题一无所获。我发现的问题都涉及同一父级的组件之间的事件触发。实际上有没有办法从坐标中获取舞台?
到目前为止,我已经尝试获取一个节点并触发该事件,但它会导致 InvocationReflectionException。我认为这是因为我单击的节点(显然)是 MouseEvent 的目标,并且最终会调用自身直到它中断?
除此之外,我尝试过 stage.fireEvent(),但实际上什么也没做。
这是我正在尝试做的示例。
示例.fxml
<?import javafx.scene.layout.GridPane?>
<GridPane fx:controller="sample.Controller"
xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10 vgap="10"
onMouseClicked="#onMouseClicked">
</GridPane>
控制器.java
package sample;
import javafx.scene.input.MouseEvent;
public class Controller
{
//Just noting that it has been clicked
public void onMouseClicked(MouseEvent mouseEvent)
{
System.out.println("MOUSE CLICKED!");
{
}
例子.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="sample.ExController"
prefHeight="400.0" prefWidth="600.0"
onMouseClicked="#onMouseClicked"
onMouseEntered="#onMouseEntered"
onMouseMoved="#onMouseMoved">
</AnchorPane>
ExController.java
package sample;
import javafx.geometry.Rectangle2D;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.stage.Popup;
import javafx.stage.Screen;
//This is the controller that fires the mouse click Event
public class ExController
{
double cursorPosX;
double cursorPosY;
double mouseEnterX;
double mouseEnterY;
//Fake cursor placeholder
Popup popupCursor;
//Just fills the placeholder
Label label = new Label();
//Creates a placeholder fake cursor
//This can be safely ignored for the purposes of the question
public void onMouseEntered(MouseEvent mouseEvent)
{
mouseEnterX = mouseEvent.getX();
mouseEnterY = mouseEvent.getY();
if(popupCursor == null)
{
//Initial Cursor position
cursorPosX = 0;
cursorPosY = 0;
//Set up label stuff
label.setPrefHeight(100);
label.setPrefWidth(100);
label.setStyle("-fx-background-color: #" + "0f0f0f);
//Create popup window
popupCursor = new Popup();
popupCursor.getContent().add(label);
popupCursor.show((Node)mouseEvent.getSource(), 100, 100);
}
}
//This is a poor attempt at making a fake cursor move
//This can also be safely ignored
public void onMouseMoved(MouseEvent mouseEvent)
{
if(popupCursor != null)
{
Rectangle2D bounds = Screen.getPrimary().getVisualBounds();
//delta between mouseEvent and the point the screen was entered at
double deltaX = mouseEvent.getSceneX() - mouseEnterX;
double deltaY = mouseEvent.getSceneY() - mouseEnterY;
//Movement increment - poorly done, but sorta functional
double incrementX = (bounds.getWidth() / 500);
double incrementY = (bounds.getHeight() / 500);
if(deltaX > 0)
{
cursorPosX += incrementX;
}
else if(deltaX < 0)
{
cursorPosX -= incrementX;
}
if(deltaY > 0)
{
cursorPosY += incrementY;
}
else if(deltaY < 0)
{
cursorPosY -= incrementY;
}
if(cursorPosX < bounds.getMaxX() || cursorPosX > bounds.getMinX())
{
popupCursor.setX(cursorPosX);
}
if(cursorPosY < bounds.getMaxY() || cursorPosY > bounds.getMinY())
{
popupCursor.setY(cursorPosY);
}
mouseEvent.consume();
}
}
//THIS is the problem method. It creates a mouse event and attempts
// to fire it off to a different Stage it literally knows nothing about
public void onMouseClicked(MouseEvent mouseEvent)
{
//Creating a Mouse Event to fire
MouseEvent click = new MouseEvent(MouseEvent.MOUSE_CLICKED,
cursorPosX, cursorPosY, cursorPosX, cursorPosY,
MouseButton.PRIMARY, 1, true, true, true, true, true,
true, true, true, true, true, null);
//Causes InvocationReflectionError
Node source = (Node) mouseEvent.getSource();
source.fireEvent(click);
}
}
主.java
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
//Stage 1
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Receiver");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
//Stage 2
Parent otherRoot =
FXMLLoader.load(getClass().getResource("example.fxml"));
Stage otherStage = new Stage();
otherStage.setTitle("Sender");
otherStage.setScene(new Scene(otherRoot, 300, 275));
otherStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
解决方案
推荐阅读
- java - ]将2个整数组合成1个字节
- devexpress - 无法将 XtraReport 连接到 Firebird 数据库
- android-studio - Android Studio中使用WIFI调试时无法到达断点
- python - AWS DocumentDB 语法与用于 UpdateMany 的 MongoDB 不同
- typescript - 具有模板文字类型的属性路径
- c++ - 为什么我的编译器说我的函数被定义了多次?
- arrays - 按顺序对字符串进行排序
- javascript - VueJS插件初始化中的竞争条件
- python - 使枚举在 pydantic 中更加灵活
- python - 类型错误:create_estimator_and_inputs() 缺少 1 个必需的位置参数:'hparams',model_main.py 文件中的 hparams 错误