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