我正在尝试通过观察者模式更新文本字段。在单击另一个控制器类中的listItem之后,将调用观察器(FXML控制器)中的更新函数。这很好。唯一的问题是我的文本字段不会更新。
这是我在观察者中的更新功能。
@Override
public void update(Observable o, final Object arg) {
System.out.println("test"); // works
firstNameTextField.setText("test"); // doesn't work (text field is still empty)
System.out.println(firstNameTextField.getText()); //works and shows me the word "test" on my console
}
有趣的是,如果我从控制台上的文本字段打印文本,它会在控制台上打印“test”一词。看起来文本字段值已更新,但它没有显示在ui上。
修改 这是我的MainController
public class MainController extends Observable implements Initializable {
private ObservableList<String> items = FXCollections.observableArrayList("item1", "item2");
private List<UserProfile> userProfiles = new ArrayList<UserProfile>();
private String[] tabTitles = { "Profile"};
@FXML
private TabPane tabPane;
@FXML
ListView<String> listView;
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
for (String tabTitle : tabTitles) {
Tab tab = new Tab(tabTitle);
tab.setClosable(false);
tabPane.getTabs().add(tab);
}
tabPane.getSelectionModel().clearSelection();
for (Tab tab : tabPane.getTabs()) {
try {
String newStringValue = tab.getText();
Parent root = FXMLLoader.load(getClass().getResource("profile.fxml"));
tab.setContent(root);
FXMLLoader fxmlLoader = new FXMLLoader();
Object p = fxmlLoader.load(getClass().getResource("profile.fxml").openStream());
if (fxmlLoader.getController() instanceof ProfileController) {
ProfileController profileController = (ProfileController) fxmlLoader.getController();
this.addObserver(profileController);
}
} catch (IOException e) {
e.printStackTrace();
}
}
tabPane.getSelectionModel().selectFirst();
listView.setItems(items);
listView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
setChanged();
notifyObservers();
}
});
}
}
ProfileController可
public class ProfileController implements Initializable, Observer {
@FXML
TextField firstNameTextField;
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
}
@Override
public void update(Observable o, final Object arg) {
System.out.println("test"); // works
firstNameTextField.setText("test"); // doesn't work (text field is still empty)
System.out.println(firstNameTextField.getText()); //works and shows me the word "test" on my console
}
}
有人可以帮我解决这个问题吗?
谢谢!
答案 0 :(得分:1)
执行时
Object p = fxmlLoader.load(getClass().getResource("profile.fxml").openStream());
if (fxmlLoader.getController() instanceof ProfileController) {
ProfileController profileController = (ProfileController) fxmlLoader.getController();
this.addObserver(profileController);
}
加载profile.fxml表示的结构,并将该层次结构(包括firstNameTextField
)放在您调用的对象p
中。当您在update(...)
上调用profileController
时,它会更改文本字段中作为p
层次结构一部分的文本。但是,您永远不会对p
执行任何操作:您不会在UI中显示它。因此,当您更改文本字段的文本时,更改当然是不可见的(因为您正在更改未显示的文本字段)。
据推测,既然您说过显示了文本字段,那么代码中的任何地方都无法包含您正在加载profile.fxml
并在UI中显示内容。您需要获取那个控制器的引用,并将其注册为观察者。注册同一个类的任意实例将不会产生预期的效果。