2016-12-21 64 views
0

使用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的實例。

回答

0

我不知道處理這個限制的更好方法,所以我所做的只是做一個修改對象的set(),以便引用保持相同,但變化得到傳播。

+0

您認爲如何編寫一個簡單的包裝類,將每個方法調用轉發給包裝對象並觸發'PropertyChangeEvent'?目前我也做一個set()調用。 –

+0

我曾多次想過這個解決方案,但我總是認爲這不值得。包裝的問題是你必須委託每一種方法,所以維護成爲一個問題。通過代理可能是可能的,但我認爲這是一個矯枉過正。 也許最好的辦法就是創建一個公開方法forceChange()來實現屬性的重新分配。 – Rubasace

相關問題