JavaFX8を使用して、ObjectProperty
の1つの属性のみが変更されても参照は同じままであれば、どのように通知することができますか?ObjectPropertyのソースが変更されない限り、ChangeListenerが起動しない
ObjectProperty<KeyStore>
を使用した具体的な例に従います。 java.security.KeyStore
には、キーと証明書のリストが格納されています。エントリが追加、変更、削除された場合、通知を受けたい。 ObjectProperty
の値が最初に設定されます、その後、一つの要素が除去される
public abstract class EntityController {
protected ObjectProperty<KeyStore> trustStore = new SimpleObjectProperty<KeyStore>();
public EntityController() {
}
public KeyStore getTrustStore() {
return this.trustStore.getValue();
}
public void setTrustStore(KeyStore trustStore) {
this.trustStore.set(trustStore);
}
public ObjectProperty<KeyStore> trustStoreProperty() {
return this.trustStore;
}
}
public class CertificatesTabPresenter extends PKIPresenter implements Initializable {
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
this.getEntityController().trustStoreProperty().addListener((observableVal, oldTrustStore, newTrustStore) -> {
trustStoreChanged(oldTrustStore, newTrustStore);
});
}
@FXML
private void addTrustStore(MouseEvent e) {
File keyStoreFile = selectKeyStoreFile();
if (keyStoreFile != null) {
Optional<String> keyStoreType = selectKeyStoreType();
if(keyStoreType.isPresent()) {
Optional<char[]> password = insertPassword();
if(password.isPresent()) {
try {
KeyStore trustStore = KeyStore.getInstance(keyStoreType.get());
trustStore.load(null, null);
FileInputStream fis = new FileInputStream(keyStoreFile);
trustStore.load(fis, password.get());
//This causes the changeListener to be notified because the reference changed
this.getEntityController().setTrustStore(trustStore);
//The changeListener won't be notified, because only the KeyStore changes internally but the reference stays the same
trustStore.deleteEntry(trustStore.aliases().nextElement());
this.getEntityController().setTrustStore(trustStore);
//This also won't notify the changeListener
String a = this.getEntityController().getTrustStore().aliases().nextElement();
this.getEntityController().getTrustStore().deleteEntry(a);
} catch (KeyStoreException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (NoSuchAlgorithmException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (CertificateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
//TODO: password was wrong -> show error message
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
}
}
関連するコードです。 changeListenerは、ObjectProperty
の値が設定されている場合にのみ通知されますが、値が変更された場合は通知されません。
私の質問は:KeyStore
が参照オブジェクトが変更されなくても更新された場合、どうすれば通知を受けることができますか? JavaFXには組み込みの方法がありますか?
私が意図しているのは、ListView
に含まれているすべての証明書とキーを表示し、証明書がchangeListener内からKeyStore
に追加または削除されるたびにListView
を更新することです。たぶん私は完全に間違った方法でやっていると私は完全に異なる必要がありますか?
追加情報:
this.getEntityController()
はObjectProperty<EntityController>
に保持され、それ自体EntityController
のインスタンスを返します。
ラップされたオブジェクトにすべてのメソッド呼び出しを転送し、 'PropertyChangeEvent'を発生させる単純なラッパークラスを書く考えはどう思いますか?現在私はset()呼び出しもしています。 –
私はその解決策を何度か考えてきましたが、私はいつもそれが価値がないと思ってしまいます。ラッパーの問題は、すべてのメソッドを委任する必要があるため、保守が問題になることです。プロキシ経由では可能かもしれないが、私はそれが過度だと思う。 おそらく、プロパティの再割り当てを行うメソッドforceChange()を公開するユーティリティを作成するだけです。 – Rubasace