除非更改了ObjectProperty的源,否则不会触发ChangeListener

时间:2016-12-21 07:35:13

标签: java javafx observable

使用JavaFX8,如果只有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 s值的位置,之后删除了一个元素。只有在设置了ObjectProperty s值时才会通知changeListener,而在更改值时则不会通知。

我的问题是:即使引用的对象没有改变,如果KeyStore得到更新,我怎样才能收到通知? JavaFX中是否有内置方式?

我的目的是在ListView中显示所有包含的证书和密钥,并在每次从changeListener中将证书添加或删除到ListView时更新KeyStore。也许我完全错了,我应该完全不同?

其他信息:

this.getEntityController()

返回EntityController的实例,该实例本身保存在ObjectProperty<EntityController>

1 个答案:

答案 0 :(得分:0)

我不知道更好的方法来处理这个限制所以我所做的只是做一个修改过的对象的set(),这样引用就会保持不变,但变化会被传播。