JavaFX - 通过观察者模式更新文本字段

时间:2015-06-29 13:39:59

标签: javafx javafx-2 textfield observer-pattern

我正在尝试通过观察者模式更新文本字段。在单击另一个控制器类中的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
    }
}

有人可以帮我解决这个问题吗?

谢谢!

1 个答案:

答案 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中显示内容。您需要获取那个控制器的引用,并将其注册为观察者。注册同一个类的任意实例将不会产生预期的效果。