2016-03-18 28 views
1

私はJavaFXで遊んでいて、変更直後に状態を保存するGUIを作成しようとしています。JavaFX:双方向バインディングでTextFieldが更新されない

クラスUiStateは、すべてのプロパティをカプセル化:

public class UiState { 

    private static final Preferences PREFS = Preferences.userNodeForPackage(UiState.class); 
    public static final StringProperty FOLDER_PROP_STATISTICS = new BindingProperty("FOLDER_PROP_STATISTICS", 
     "C:\\Temp\\"); 

    //This is a Stringproperty, which accesses the Preferences 
    protected static class BindingProperty extends SimpleStringProperty { 
     private final String def; 
     private final String bindingName; 

     public BindingProperty(final String bindingName) { 
      this(bindingName, ""); 
     } 

     public BindingProperty(final String bindingName, final String def) { 
      this.def = def; 
      this.bindingName = bindingName; 
     } 

     @Override 
     public String get() { 
      return PREFS.get(bindingName, def); 
     } 

     @Override 
     public void set(final String newValue) { 
      PREFS.put(bindingName, newValue); 

     } 

    } 

GUIは、次のように作成されます。フォルダがDirectoryChooserを経由して選択される

protected void configFileComponents() { 

    final TextField folderTextField = getPropertyTextFieldWithLabel("Target folder", UiState.FOLDER_PROP_STATISTICS); 

    folderTextField.setOnMouseClicked(target -> { 
     onFileChooseButtonClicked(); 

    }); 
} 

private void onFileChooseButtonClicked() { 
    final DirectoryChooser chooser = new DirectoryChooser(); 
    chooser.setTitle("Select target folder"); 
    final String folder = getFolderProperty().get(); 
    if (!(folder == null || folder.isEmpty())) { 
     chooser.setInitialDirectory(new File(folder)); 
    } 

    final File result = chooser.showDialog(getScene().getWindow()); 
    if (result != null) { 
     getFolderProperty().set(result.getAbsolutePath()); 
    } 
} 

protected TextField getPropertyTextFieldWithLabel(final String label, final StringProperty property) { 
    final Label fileLabel = new Label(label); 
    addLeft(fileLabel); 
    final TextField result = new TextField(); 
    result.setText(property.get()); 
    addRight(result); 
    //I thought this would be enough 
    result.textProperty().bindBidirectional(property); 
    return result; 
} 

たら、StringProperty FOLDER_PROP_STATISTICSが更新されます。しかし、TextFieldは新しい値を表示しません。私は何かを逃しましたか、または私は根本的な間違いを犯しましたか?

+1

あなたの 'set'メソッドは、ChangeListenersまたはInvalidationListenersを起動しません。あなたの問題が示すように、StringPropertyを拡張するのは良い考えではありません。より良いアイデアは、Preferencesノードのキーと値から通常のStringProperty(またはObservableMap)を初期化し、そのノードにリスナーを追加して、そのPreferencesノードで変更を反映できるようにすることです。 – VGR

+0

ありがとうございました。すべて今はうまく動作します:) – samjaf

答えて

1

VGRが正しかった、それはget()とset()をオーバーライドするnaivだったBindingProperty。私の新しいクラスはこのように見え、魅力的に機能します:

protected static class BindingProperty extends SimpleStringProperty { 

    public BindingProperty(final String bindingName, final String def) { 
     super(PREFS.get(bindingName, def)); 
     this.addListener(
       (ChangeListener<String>) (observable, oldValue, newValue) -> PREFS.put(bindingName, newValue)); 
    } 

    public BindingProperty(final String bindingName) { 
     this(bindingName, ""); 
    } 

} 
関連する問題