使用JavaFX8,如果只有ObjectProperty
的一個屬性發生變化,但引用保持不變,如何通知它?ChangeListener不會被觸發,除非ObjectProperty的源發生改變
以下使用ObjectProperty<KeyStore>
的具體示例。 java.security.KeyStore
包含密鑰和證書的列表。我希望得到通知,如果條目被添加,更改或刪除。
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();
}
}
}
}
}
}
相關的代碼是其中ObjectProperty
價值獲取設置在第一次和隨後的一個元件被移除。只有在設置了ObjectProperty
的s值時才通知changeListener,但在值更改時不會發送。
我的問題是:如果KeyStore
得到更新,即使引用的對象沒有更改,我如何才能實現通知? JavaFX中是否有內置的方法?
我的目的是顯示包含的所有證書和密鑰在一個ListView
並更新ListView
每次一個證書被從內的ChangeListener添加或移除到KeyStore
。也許我完全走錯了方向,我應該完全不同?
其他信息:
this.getEntityController()
返回其本身在ObjectProperty<EntityController>
舉行EntityController
的實例。
您認爲如何編寫一個簡單的包裝類,將每個方法調用轉發給包裝對象並觸發'PropertyChangeEvent'?目前我也做一個set()調用。 –
我曾多次想過這個解決方案,但我總是認爲這不值得。包裝的問題是你必須委託每一種方法,所以維護成爲一個問題。通過代理可能是可能的,但我認爲這是一個矯枉過正。 也許最好的辦法就是創建一個公開方法forceChange()來實現屬性的重新分配。 – Rubasace