当前位置: 首页 > 知识库问答 >
问题:

无法通过其他控制器控制其他fxml文件的元素

袁阿苏
2023-03-14

我正在做一个项目,处理多个fxml和相应的控制器文件。我需要以某种方式从b.fxml的控制器访问定义在例如a.fxml中的fxml元素并使用它。

我不允许展示实际代码。但是,为此目的,我构建了一个简单的应用程序,其中包含两个FXML及其相应的控制器。

此应用程序具有带有ButtonController.java的Button.fxml和带有ProgressIndicator.fxml的ProgressIndicatorController.java

点击按钮后,进度指示器就会显示出来。

下面是代码:

button.fxml

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>

<AnchorPane xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.ButtonController">
   <children>
      <Pane prefHeight="206.0" prefWidth="281.0">
         <children>
            <Button fx:id="button1" layoutX="59.0" layoutY="63.0" mnemonicParsing="false" prefHeight="63.0" prefWidth="164.0" text="Button" onAction="#onButton1Clicked" />
         </children>
      </Pane>
   </children>
</AnchorPane>

ButtonController.java

package application;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class ButtonController implements Initializable{

    @FXML
    private Button button1;

    private ProgressIndicator progressIndicator;

    private ProgressIndicatorController progressIndicatorController;

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        try {
            Object loader = FXMLLoader.load(getClass().getResource("ProgressIndicator.fxml"));
            Scene sceneProgressIndicator = new Scene((Parent) loader, 1400, 800);
            sceneProgressIndicator.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            sceneProgressIndicator.setFill(Color.TRANSPARENT);
            Stage primaryStageProgressIndicator = new Stage();
            primaryStageProgressIndicator.setScene(sceneProgressIndicator);
            primaryStageProgressIndicator.setResizable(false);
            primaryStageProgressIndicator.setHeight(311);
            primaryStageProgressIndicator.setWidth(523);
            primaryStageProgressIndicator.show();
        } catch (IOException e) {

            e.printStackTrace();
        }




        // TODO Auto-generated method stub



    }

    public void onButton1Clicked() {

        FXMLLoader fxmlLoaderProgressIndicator = new FXMLLoader();
        fxmlLoaderProgressIndicator.setLocation(getClass().getResource("ProgressIndicator.fxml"));
        try {
            Parent root = fxmlLoaderProgressIndicator.load();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        progressIndicatorController = (ProgressIndicatorController) fxmlLoaderProgressIndicator.getController();



        for(double  i = 0.0; i <= 1.0 ; i+=0.2) {
            progressIndicator = progressIndicatorController.getProgressIndicator1();
            progressIndicator.setProgress(i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }


}

ProgressIndicator.fxml

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

<?import javafx.scene.control.ProgressIndicator?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>


<AnchorPane xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.ProgressIndicatorController">
   <children>
      <Pane prefHeight="200.0" prefWidth="200.0">
         <children>
            <ProgressIndicator fx:id="progressIndicator1" layoutX="47.0" layoutY="31.0" prefHeight="103.0" prefWidth="106.0" progress="0.0" />
         </children>
      </Pane>
   </children>
</AnchorPane>
package application;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class ProgressIndicatorController implements Initializable {


    @FXML
    private ProgressIndicator progressIndicator1;

    @Override
    public void initialize(URL location, ResourceBundle resources) {




        // TODO Auto-generated method stub

    }

    public ProgressIndicator getProgressIndicator1() {

        System.out.println("getteeerrrrrrrr");
        return progressIndicator1;
    }

    public void setProgressIndicator1(ProgressIndicator progressIndicator1) {
        this.progressIndicator1 = progressIndicator1;
    }

}

我也没有收到任何类型的错误消息。

我遇到了javafx-how to acces FXML“objects”这一链接,它确实在很大程度上帮助了我,但我也无法完成这项工作。我只是尝试修改按钮点击方法,如下所示:

onButton1Cliked()

public void onButton1Clicked() {

        progressIndicator = (ProgressIndicator) sceneProgressIndicator.lookup("#progressIndicator1");

        for(double  i = 0.0; i <= 1.0 ; i+=0.2) {
            try {
                System.out.println("Progressingggg   " + i);
                progressIndicator.setProgress(i);
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

欢迎提出任何意见或建议。这件事已经有好几个小时了。Stackoverflow似乎是最后的手段。

编辑1:开始

原来进度指标没有更新,是因为Zephyr第一条评论中解释的原因。所以我为我的应用程序创建了一个分离线程,当进度指示器按预期更新时,这似乎可以很好地工作。

正在成功更新进度指示器的onButton1Clicked()方法的工作版本:

public void onButton1Clicked() {

        progressIndicator = (ProgressIndicator) sceneProgressIndicator.lookup("#progressIndicator1");

        Runnable runnable = new Runnable() {

            @Override
            public void run() {

                for(double  i = 0.0; i <= 1.0 ; i+=0.2) {               
                    try {
                        System.out.println("Progressingggg   " + i);
                        progressIndicator.setProgress(i);
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
        }   

            }
        };

        Thread thread = new Thread(runnable);
        thread.start();

    }

解决了这个线程问题后,我再次尝试使用我的OP中提到的原始方法(即获取ProgressIndicatorController实例并访问其进度指示器,然后尝试更新它)。然而,这对我不起作用。我尝试调试,发现我正在取回ProgressIndicatorController和ProgressIndicator实例。

为什么我的代码不能更新进度指示器,如果它对进度指示器实例有保留。println方法执行成功,只是进度指示器根本没有更新,一直处于“0”。

public void onButton1Clicked() {        

        FXMLLoader fxmlLoaderProgressIndicator = new FXMLLoader();
        fxmlLoaderProgressIndicator.setLocation(getClass().getResource("ProgressIndicator.fxml"));
        try {
            Parent root = fxmlLoaderProgressIndicator.load();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        progressIndicatorController = (ProgressIndicatorController) fxmlLoaderProgressIndicator.getController();



        progressIndicator = progressIndicatorController.getProgressIndicator1();

        Runnable runnable = new Runnable() {

            @Override
            public void run() {

                for(double  i = 0.0; i <= 1.0 ; i+=0.2) {               
                    try {
                        System.out.println("Progressingggg   " + i);
                        progressIndicator.setProgress(i);
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
        }   

            }
        };

        Thread thread = new Thread(runnable);
        thread.start();

    }

编辑2:开始

正在添加运行此示例应用程序所需的其他文件

main.java

package application;

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.fxml.FXMLLoader;


public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            Object root =FXMLLoader.load(getClass().getResource("Button.fxml"));
            Scene scene = new Scene((Parent) root,400,400);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }


    }

    public static void main(String[] args) {
        launch(args);
    }
}

我的application.css文件中什么也没有。它是空的。

我在Java8上使用JavaFX8。IDE是Eclipse Photon

我使用e(fx)clipse插件创建了我的项目,并在create new project窗口中选择JavaFX project。

编辑2:结束

编辑3:开始

在EDIT 1部分下,在尝试测试成功更新进度指示器的onButton1Clicked()版本时,请不要忘记包含private Scene sceneProgressIndicator作为ButtonController.java类的成员变量。

编辑3:结束

共有1个答案

云建木
2023-03-14

我想你想要这样的东西(注意注释):

import java.io.IOException;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class ButtonController {

    @FXML
    private Button button1;
    private ProgressIndicator progressIndicator;
    private Scene sceneProgressIndicator;

    @FXML
    public void initialize() {

        try {

            FXMLLoader loader = new FXMLLoader(getClass().getResource("ProgressIndicator.fxml"));
            Pane progressIndicatorPane = loader.load();
            ProgressIndicatorController progressIndicatorController  = loader.getController(); //get a reference to the progress indicator controller
            progressIndicator = progressIndicatorController.getProgressIndicator1(); //get the progress indicator 

            sceneProgressIndicator = new Scene(progressIndicatorPane, 1400, 800);
            sceneProgressIndicator.setFill(Color.TRANSPARENT);
            Stage primaryStageProgressIndicator = new Stage();
            primaryStageProgressIndicator.setScene(sceneProgressIndicator);
            primaryStageProgressIndicator.setResizable(false);
            primaryStageProgressIndicator.setHeight(311);
            primaryStageProgressIndicator.setWidth(523);
            primaryStageProgressIndicator.show();
        } catch (IOException e) {

            e.printStackTrace();
        }
    }

    public void onButton1Clicked() {

        Runnable runnable = () -> {

            for(double  i = 0.0; i <= 1.0 ; i+=0.2) {

                final double fD = i;
                Platform.runLater(() -> progressIndicator.setProgress(fD));//update done on javafx thread 

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        Thread thread = new Thread(runnable);
        thread.start();
    }
}
 类似资料:
  • 调用其他控制器 在控制器内直接使用 new 关键字实例化其他控制器类即可完成对其他控制器的调用 演示代码 在 index 控制器内调用 test 控制器并执行其 runme 方法 : test.php 源码 <?php class testController extends grace{ public function runme(){ echo 'run...'; } } index

  • 我从另一个开发人员那里接手了一个项目,所以我想把他的很多代码移到一个临时文件夹中,把事情弄清楚,如果我需要任何例子,我会回到他的东西上去。 因此,在将他的一个控制器类移动到临时文件夹“src/controller/temp”时,我得到以下消息: 自动加载程序需要在文件“/var/www/vhosts/mywebsite.com/vendor/composer/./../src/Controller

  • 如何解释文件与其对应的控制器类之间的关系

  • 问题内容: 我有一个具有自己的控制器的指令。请参见以下代码: 这旨在成为错误/通知/警告的通知系统。我想做的是从另一个控制器(不是指令控制器)调用此控制器上的函数。当我这样做时,我还希望我的链接函数检测到某些属性已更改并执行了一些动画。 这是一些代码来举例说明我要的内容: 所以打电话时开启指令控制器,链接功能也应该被触发,执行动画。我该如何实现? 问题答案: 这是一个有趣的问题,我开始考虑如何实现

  • null 我在TopMenuButtons中有一个按钮,它具有openAssisstantStage()方法,打开新的小阶段: 对于这个阶段,我还有FXML文件和控制器(AssisstantController)。只有2个按钮-第一个按钮应该打开前一个阶段和关闭电流,但第二个按钮也应该打开普雷沃阶段,关闭电流,也打开一个特定的标签在我的标签视图和做一些其他逻辑例如。获取实际localDate: 我

  • 我是的新手,我有一个和多个场景,我可以使用在它们之间切换,所有工作都很好,直到我尝试在单击菜单项时做一些事情而不是显示场景。 我试图通过使用方法类中调用,在那里我有菜单项action methods,我调用在单击菜单项时将文本写入方法中的文本字段,但在加载该场景的控制器后,什么都没有发生。这是我的代码: 类 家庭控制器类 我知道我可能忽略了一些东西,但我不知道它是什么,帮助将不胜感激。