如何在JavaFX的控制器文件中调用舞台上的函数

Pra*_*and 10 location javafx javafx-2 fxml

我使用javafx 和fxml,所以我使用控制器进行实际编码.我需要在舞台上做一些操作,例如获得x轴或y轴位置.我曾尝试stage.getX()stage.getY,但他们不工作(艺名为高lited为错误).如何在控制器中使用此类功能?我尝试在我的主文件中执行此操作:

 public int locationX = stage.getX();
Run Code Online (Sandbox Code Playgroud)


public double locationX = stage.getX();
Run Code Online (Sandbox Code Playgroud)

但它不起作用,反而使整个程序成为一个大错误.
那么如何在我的控制器文件中执行此类功能呢?我是否需要以其他方式导入某些内容或执行上述操作?

error: cannot find symbol
    locationX = stage.getX();
symbol:   variable stage
location: class FXMLController
Run Code Online (Sandbox Code Playgroud)


我知道"舞台"缺失了.但是如何在我的控制器中获得"舞台"?

tar*_*lah 25

从文件中的窗格fxml:

@FXML
Parent root
Run Code Online (Sandbox Code Playgroud)

您可以通过以下方式获得舞台:

Stage stage = (Stage) root.getScene().getWindow()
Run Code Online (Sandbox Code Playgroud)

你有一个参考你的舞台,你可以做你想要的.


jew*_*sea 14

样品溶液

您可以使用以下技术初始化控制器中的阶段:传递参数JavaFX FXML.

这是一个示例程序,它创建一个实用程序窗口,在您拖动实用程序窗口时跟踪屏幕的x和y坐标.实用程序窗口的内容在fxml定义的窗格中呈现.

stagecoords

StageTrackingSample.java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.*;
import javafx.stage.*;

public class StageTrackingSample extends Application {

  @Override public void start(final Stage stage) throws Exception {
    final FXMLLoader loader = new FXMLLoader(
      getClass().getResource(
        "stagetracking.fxml"
      )
    );

    final Parent root = (Parent) loader.load();
    final StageTrackingController controller = loader.getController();
    controller.initData(stage);

    stage.initStyle(StageStyle.UTILITY);
    stage.setResizable(false);
    stage.setScene(new Scene(root));
    stage.show();
  }

  public static void main(String[] args) { launch(args); }
}
Run Code Online (Sandbox Code Playgroud)

StageTrackingController.java

import javafx.beans.binding.Bindings;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.stage.Stage;

public class StageTrackingController {
  @FXML private Label stageX;
  public void initialize() {}  
  public void initData(final Stage stage) {
    stageX.textProperty().bind(
      Bindings.format(
        "(%1$.2f, %2$.2f)", 
        stage.xProperty(), 
        stage.yProperty()
      )
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

stagetracking.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="30" minWidth="100" xmlns:fx="http://javafx.com/fxml" fx:controller="test.StageTrackingController">
  <Label fx:id="stageX" layoutX="0" layoutY="0"/>
</AnchorPane>
Run Code Online (Sandbox Code Playgroud)

替代解决方案

如果您知道控制器的根组件已经添加到已经添加到舞台的场景中,那么tarrsalah从@FXML组件中获取舞台的答案也是一个很好的方法(通常情况下就是这种情况)像一个按钮事件处理程序被触发).

另一种方法类似于tarrsalah的答案,但是在@FXML节点的scene属性和更改的场景的window属性上使用ChangeListeners.这使您可以在窗格移动到新场景或舞台时跟踪场景和舞台的更改.大多数情况下,您不需要跟踪这些更改,因为大多数窗格只是添加到一个停留在一个舞台上的场景中.

其他问题和评论的答案

我可以得到一个更简单的答案吗?

塔尔萨拉已经提供了一个更简单的答案.

在这种情况下,回答更简单的唯一问题是它可能无法提供足够的上下文来复制答案的解决方案并使其适应您的工作.

我尽可能简单地完成了当前的答案,但不幸的是,即使是最基本的JavaFX FXML应用程序也需要相当多的代码和标记才能工作.

我只是java的初学者

首次开始开发初始Java和JavaFX应用程序时,请勿使用FXML.相反,只需在JavaFX代码中坚持使用标准Java API,其中有更多教程以及要参考的优秀Ensemble示例.

确保在开始JavaFX之前,您已经完成了涵盖基础知识的所有Java Tutorial Trails.只需要Java的基础知识就可以开始使用JavaFX,您不需要分支学习Java Enterprise Edition并且可以忘记Swing.

一旦编写了一些基本的JavaFX应用程序,就可以考虑将SceneBuilder和FXML用于更大的应用程序,根据Java API对一些布局进行手工编码,并使核心技术达到一定程度的舒适度.那时您可能会发现学习FXML非常简单.FXML属性和元素只是Java API的反映.

请解释代码的其他部分

我真的不能这样做,因为我不知道你有什么不寻常之处.

如果您通过自己的知识或研究无法理解代码的特定部分,请为每个困难概念创建一个新的StackOverflow问题.