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

时间:2013-05-19 15:27:26

标签: location javafx-2 javafx fxml

我在和fxml 一起使用javafx,所以我使用控制器进行实际编码。我需要在舞台上做一些操作,例如获得x轴或y轴位置。我试过了stage.getX()& stage.getY,但它们不起作用(阶段名称因错误而异常引人注目)。如何在控制器中使用此类功能?我尝试在我的主文件中执行此操作:

 public int locationX = stage.getX();


public double locationX = stage.getX();

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

error: cannot find symbol
    locationX = stage.getX();
symbol:   variable stage
location: class FXMLController


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

6 个答案:

答案 0 :(得分:25)

来自fxml文件中的 root 窗格:

@FXML
Parent root

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

Stage stage = (Stage) root.getScene().getWindow()

你可以参考你的舞台,你可以做你想做的事。

答案 1 :(得分:14)

示例解决方案

您可以使用以下技术初始化控制器中的舞台:Passing Parameters 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); }
}

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()
      )
    );
  }
}

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>

替代解决方案

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

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

其他问题和评论的答案

  

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

tarrsalah已经提供了一个更简单的答案。

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

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

  

我只是java的初学者

首次开始开发初始Java和JavaFX应用程序时,请勿使用FXML。相反,只需在JavaFX代码中坚持使用标准Java API,其中还有更多tutorials以及要引用的优秀Ensemble Sample

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

在编写了一些基本的JavaFX应用程序之后,考虑使用SceneBuilder和FXML用于大型应用程序,根据Java API手动编写一些布局并使核心技术达到一定程度的舒适度。那时您可能会发现学习FXML非常简单。 FXML属性和元素只是Java API的反映。

  

请解释代码的其他部分

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

如果您通过自己的知识或研究无法理解代码的特定部分,create a new StackOverflow question针对每个困难的概念。

答案 2 :(得分:3)

嗯,最简单的答案......

Main class 中创建Controller类的实例(对象):



    FXMLLoader loader = new FXMLLoader(getClass().getResource("Example.fxml"));
    MyController controller = loader.getController();
    controller.setStage(this.stage);

控制器类中,您应该使用&#34;提取&#34; (一个二传手):



    private Stage primaryStage;

    public void setStage(Stage stage) {
         this.primaryStage = stage;
    }

然后你可以添加一个全屏按钮;)



    @FXML
    private Button btnFullScreen = new Button();

    public void setFullscreen(ActionEvent event){       
         if(primaryStage.isFullScreen()){
              primaryStage.setFullScreen(false);
         } else {
              primaryStage.setFullScreen(true);
         }
    }

答案 3 :(得分:1)

这个帖子很老了,但我偶然发现了与之相关的东西。我认为是一个不应该有效的编码错误,但确实如此。在控制器类中,只需声明以下成员变量:

@FXML私人舞台舞台;

让我可以访问控制器中的舞台,就像我可以访问fxml文档中的小部件一样。我还没有发现任何文档都是这种情况,但我会承认我是JavaFX的老手(尽管在Swing中是老手)。但似乎有效。也许依靠它可能有危险吗?

答案 4 :(得分:1)

使用* .FXML文件和控制器以及不使用Main或事件,请使用:

@FXML private Stage stage;
stage = (Stage) elemen.getScene().getWindow();

元素,可以是你FXML中的任何控件或元素,在我的例子中是一个AnchorPane:

@FXML  private AnchorPane element;

答案 5 :(得分:0)

最好的方法是创建一个新的控制器并通过构造函数传递stage(不要在FXML文件上使用fx:controller),否则stage将是{ {1}}在调用null时(在initialize()调用load()的那一刻,initialize()没有附加stage,因此scene scenestage)。

null
public class AppEntryPoint extends Application
{
    private FXMLLoader loader;

    @Override
    public void init() throws Exception
    {
        loader = new FXMLLoader(getClass().getResource("path-to-fxml-file"));
    }

    @Override
    public void start(Stage initStage) throws Exception
    {
        MyController controller = new MyController(initStage);
        loader.setController(controller);
        Scene scene = loader.load();
        initStage.setScene(scene);
        initStage.show();
    }

    public static void main(String[] args)
    {
        launch(args);
    }
}
相关问题