2015-06-29 27 views
-1

我試圖通過觀察者模式更新文本字段。點擊另一個控制器類中的listItem後,將調用觀察器(FXML控制器)中的更新功能。這工作正常。唯一的問題是我的文本字段不會更新。JavaFX - 通過觀察者模式更新文本字段

這裏是我的觀察者更新函數。

@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」。它看起來像文本字段值更新,但它不顯示在用戶界面上。


編輯: 這是我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

你能告訴你如何將引用傳遞給一個控制器到另一個控制器嗎? –

+0

@James_D我編輯了我的問題 – stefOCDP

+0

是的,那真的沒有幫助。您應該創建一個[MCVE](http://stackoverflow.com/help/mcve),而不是發佈不相關的代碼片段,以顯示足以完全重現問題的內容。它看起來像是有一個控制器類的實例與實際連接到UI的實例的引用,但無法從您發佈的代碼中知道該實例。 (例如,你從裝載程序中得到了'p',你在做什麼?) –

回答

1

當執行

Object p = fxmlLoader.load(getClass().getResource("profile.fxml").openStream()); 
    if (fxmlLoader.getController() instanceof ProfileController) { 
     ProfileController profileController = (ProfileController) fxmlLoader.getController(); 
     this.addObserver(profileController); 
    } 

加載在你稱爲p對象該層次結構(包括firstNameTextField)由profile.fxml表示的結構,和地點。當您在profileController上調用update(...)時,它會更改作爲p層次結構一部分的文本字段中的文本。但是,您絕對不會對p做任何事情:您不會在用戶界面中顯示它。因此,當您更改文本字段的文本時,更改當然是不可見的(因爲您正在更改未顯示的文本字段)。

據推測,既然你說你有顯示的文本字段,在某處你的代碼不能打擾到包括要加載profile.fxml並顯示在UI內容。您需要獲得對的參考控制器,並將其註冊爲觀察者。註冊同一類的任意實例不會產生預期的效果。