Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法访问其他控制器的字段_Java_User Interface_Javafx - Fatal编程技术网

Java 无法访问其他控制器的字段

Java 无法访问其他控制器的字段,java,user-interface,javafx,Java,User Interface,Javafx,我正在尝试用JavaFX编写一个GUI应用程序。基本思想是有一个主GridPane视图,在它里面-另一个应该在按下按钮时更改的窗格。由于这个窗格必须从用户那里读取一些输入,所以我希望在控制器之间有流量,以便我可以在应用程序的不同部分之间传递数据。我的想法是将所有控制器保持在一个位置,并从任何位置引用它们的字段。它似乎不起作用-似乎我无法从外部修改窗格的内容,即使我可以访问其字段。它看起来或多或少像这样: main_view.fxml first_area.fxml second_area.fxm

我正在尝试用JavaFX编写一个GUI应用程序。基本思想是有一个主GridPane视图,在它里面-另一个应该在按下按钮时更改的窗格。由于这个窗格必须从用户那里读取一些输入,所以我希望在控制器之间有流量,以便我可以在应用程序的不同部分之间传递数据。我的想法是将所有控制器保持在一个位置,并从任何位置引用它们的字段。它似乎不起作用-似乎我无法从外部修改窗格的内容,即使我可以访问其字段。它看起来或多或少像这样:

main_view.fxml

first_area.fxml

second_area.fxml

Main.java

在我按下“附加到1区域”按钮后,什么也没有发生-文本不会显示在文本区域中。但是,当我添加一个只在FirstArea内部调用的方法时,该区域中的控制器文本会如预期的那样出现。如何修复它?

您正在加载second_area.fxml两次:一次在MainController中,加载second_area.fxml并显示它,一次在Main中。您正在访问的控制器是与您在Main中加载second_area.fxml时加载的UI关联的控制器,但您实际显示的UI是您在MainController中加载的UI。因此,当您在控制器上调用方法时,您正在更新一个从未显示过的UI

不管怎么说,使用遍布各地的公共字段的全局数据方法并不是一个特别好的主意,而且由于许多有充分记录的原因,从长远来看,不太可能非常容易维护

由于您仅从MainController访问这些字段,因此只需在MainController类中创建FirstAreaController和SecondAreaController字段,并在加载和显示相应的FXML文件时设置其值:

public class MainController {
    public TextField userInputTextField;
    public Pane content;

    private FirstAreaController firstAreaController ;
    private SecondAreaController secondAreaController ;



    public void appendToFirstArea(ActionEvent actionEvent) {
        String text = userInputTextField.getText();
        firstAreaController.firstTextArea.appendText(text + "\n");
    }

    public void appendToSecondArea(ActionEvent actionEvent) {
        String text = userInputTextField.getText();
        secondAreaController.secondTextArea.appendText(text + "\n");
    }

    public void moveToFirstArea(ActionEvent actionEvent) {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("first_area.fxml"));
            GridPane firstArea = loader.load();
            firstAreaController = loader.getController();
            content.getChildren().clear();
            content.getChildren().add(firstArea);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void moveToSecondArea(ActionEvent actionEvent) {
        try {
            FXMLLoader loader = getClass().getResource("second_area.fxml");
            GridPane secondArea = loader.load();
            secondAreaController = loader.getController();
            content.getChildren().clear();
            content.getChildren().add(secondArea);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

如果需要从更远处的对象更新UI,请考虑使用数据模型和MVC方法。参见,例如

package main;

import javafx.event.ActionEvent;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;

import java.io.IOException;

public class MainController {
    public TextField userInputTextField;
    public Pane content;

    private FirstAreaController getFirstAreaController() {
        return Main.firstAreaController;
    }

    private SecondAreaController getSecondAreaController() {
        return Main.secondAreaController;
    }

    public void appendToFirstArea(ActionEvent actionEvent) {
        String text = userInputTextField.getText();
        getFirstAreaController().firstTextArea.appendText(text + "\n");
    }

    public void appendToSecondArea(ActionEvent actionEvent) {
        String text = userInputTextField.getText();
        getSecondAreaController().secondTextArea.appendText(text + "\n");
    }

    public void moveToFirstArea(ActionEvent actionEvent) {
        try {
            GridPane firstArea = FXMLLoader.load(getClass().getResource("first_area.fxml"));
            content.getChildren().clear();
            content.getChildren().add(firstArea);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void moveToSecondArea(ActionEvent actionEvent) {
        try {
            GridPane secondArea = FXMLLoader.load(getClass().getResource("second_area.fxml"));
            content.getChildren().clear();
            content.getChildren().add(secondArea);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>

<GridPane onKeyPressed="#appendTest" maxHeight="-Infinity" maxWidth="-Infinity"
          minHeight="-Infinity" minWidth="-Infinity"
          prefHeight="300.0" prefWidth="280.0"
          xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.111"
          fx:controller="main.FirstAreaController">
    <columnConstraints>
        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
    </columnConstraints>
    <rowConstraints>
        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
    </rowConstraints>
    <children>
        <TextArea fx:id="firstTextArea" prefHeight="200.0" prefWidth="200.0">
            <GridPane.margin>
                <Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
            </GridPane.margin>
        </TextArea>
    </children>
</GridPane>
package main;

import javafx.scene.control.TextArea;

public class FirstAreaController {
    public TextArea firstTextArea;
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>

<GridPane maxHeight="-Infinity" maxWidth="-Infinity"
          minHeight="-Infinity" minWidth="-Infinity"
          prefHeight="300.0" prefWidth="280.0"
          xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.111"
          fx:controller="main.SecondAreaController">
    <columnConstraints>
        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
    </columnConstraints>
    <rowConstraints>
        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
    </rowConstraints>
    <children>
        <TextArea fx:id="secondTextArea" prefHeight="200.0" prefWidth="200.0">
            <GridPane.margin>
                <Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
            </GridPane.margin>
        </TextArea>
    </children>
</GridPane>
package main;

import javafx.scene.control.TextArea;

public class SecondAreaController {
    public TextArea secondTextArea;
}
package main;

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

public class Main extends Application {

    public static MainController mainController;
    public static FirstAreaController firstAreaController;
    public static SecondAreaController secondAreaController;

    @Override
    public void start(Stage primaryStage) throws Exception {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("main_view.fxml"));
        Parent root = loader.load();
        primaryStage.setTitle("Test");
        primaryStage.setScene(new Scene(root, 400, 300));
        mainController = loader.getController();

        FXMLLoader firstLoader = new FXMLLoader();
        firstLoader.setLocation(getClass().getResource("first_area.fxml"));
        firstLoader.load();
        firstAreaController = firstLoader.getController();

        FXMLLoader secondLoader = new FXMLLoader();
        secondLoader.setLocation(getClass().getResource("second_area.fxml"));
        secondLoader.load();
        secondAreaController = secondLoader.getController();

        primaryStage.setResizable(false);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
public class MainController {
    public TextField userInputTextField;
    public Pane content;

    private FirstAreaController firstAreaController ;
    private SecondAreaController secondAreaController ;



    public void appendToFirstArea(ActionEvent actionEvent) {
        String text = userInputTextField.getText();
        firstAreaController.firstTextArea.appendText(text + "\n");
    }

    public void appendToSecondArea(ActionEvent actionEvent) {
        String text = userInputTextField.getText();
        secondAreaController.secondTextArea.appendText(text + "\n");
    }

    public void moveToFirstArea(ActionEvent actionEvent) {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("first_area.fxml"));
            GridPane firstArea = loader.load();
            firstAreaController = loader.getController();
            content.getChildren().clear();
            content.getChildren().add(firstArea);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void moveToSecondArea(ActionEvent actionEvent) {
        try {
            FXMLLoader loader = getClass().getResource("second_area.fxml");
            GridPane secondArea = loader.load();
            secondAreaController = loader.getController();
            content.getChildren().clear();
            content.getChildren().add(secondArea);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}