2016-08-17 59 views
0

我的問題是當ObservableList更改時,我的ListView(複選框列表視圖)不會更新。當JRE6上的ObservableList更改時,JavaFX ListView未更新JavaFX2.2

只有當我使用JavaFX的日期版本和日期JRE(jre6和jfx2.2)時,纔會出現此問題。當我使用jre8和它包含的JavaFX時,問題消失了,列表刷新得很好。上最新上述JavaFX的

工作源代碼:

列表:

public ObservableList<TestCaseCheckboxModel> TestCases; 

//Constructor 
public SessionTestCaseModel() { 
    TestCases = FXCollections.observableArrayList(new Callback<TestCaseCheckboxModel, Observable[]>(){ 
     @Override 
     public Observable[] call(TestCaseCheckboxModel model) { 
      return new Observable[]{model.TestCaseName, model.TestCaseStatus, model.TestCaseSelected};//selected might not be needed since it's bound to the listview anyways 
     } 
    }); 
} 

列表使用類具有以下屬性:

public StringProperty TestCaseName = new SimpleStringProperty(); 
public IntegerProperty TestCaseStatus = new SimpleIntegerProperty(); 
public BooleanProperty TestCaseSelected = new SimpleBooleanProperty(); 

列表是外部填充。

ListView

@FXML 
private ListView<TestCaseCheckboxModel> testcaseListView; 

//bind the checkbox select to the model property 
testcaseListView.setCellFactory(CheckBoxListCell.forListView(new Callback<TestCaseCheckboxModel, ObservableValue<Boolean>>() { 
    @Override 
    public ObservableValue<Boolean> call(TestCaseCheckboxModel item) { 
     return item.TestCaseSelected; 
    } 
})); 

//initiate the checkbox list view with the model items 
testcaseListView.setItems(getModel().TestCases); 

的問題是,當我改變列表項,ListView中不會對舊版本的JavaFX改變。

值得一提的是,當我從列表中添加/刪除一個項目後,列表中的項目會更新(就像他們自己更改時所預期的那樣)。但據我所知,無論如何,調用列表的add函數都會觸發ListView更新。

在另一方面,當項目屬性改變,這將觸發,與新舊和JavaFX版本,所以Callback提取正在按預期:

getModel().TestCases.addListener(new ListChangeListener<TestCaseCheckboxModel>(){ 
     @Override 
      public void onChanged(Change change) { 
       System.out.println(change); 
     } 
    }); 

是否存在已知的解決方法這個?

謝謝你的幫助。

+0

你可以發佈修改數據的示例代碼嗎?此外,**如果**你使這些屬性字段爲'public',你還應該添加'final'修飾符,以確保屬性不被替換。 – fabian

+0

謝謝你的建議,我一定會包括安全措施,但我寧願先解決這個問題。一個例子可以簡單地爲'getModel()。TestCases.get(0).TestCaseName.set(「New name」)'。像這樣,任何屬性都可以從'TestCases'列表中修改。所以沒有特別的竅門。 –

+0

如果您想知道錯誤是否在修改數據,請務必檢查我發佈的解決問題的答案。它不是,我也找到了解決方案(下面的答案)。我會盡快接受它(後天),所以它會很明顯。 –

回答

1

從這個線程回答我的問題有幫助: https://stackoverflow.com/a/25962110/4073727

我實現了自定義ListViewSkin是能夠更新「從內部」的ListView:

public class UpdateableListViewSkin<T> extends ListViewSkin<T> { 

    public UpdateableListViewSkin(ListView<T> arg0) { 
     super(arg0); 
    } 

    public void refresh() { 
     super.flow.recreateCells(); 
    } 

} 

然後我添加ObservableListListView,實例化Skin並將其設置爲ListView

//initiate the checkbox list view with the model items 
testcaseListView.setItems(getModel().TestCases); 

UpdateableListViewSkin<TestCaseCheckboxModel> skin = new UpdateableListViewSkin<TestCaseCheckboxModel>(testcaseListView); 
testcaseListView.setSkin(skin); 

的關鍵是,你需要一個工作onChange監聽器添加到ObservableList,這將觸發Skin.refresh()方法。我這樣做是對的,我設置SkinListView後:

getModel().TestCases.addListener(new ListChangeListener<TestCaseCheckboxModel>(){ 
    @SuppressWarnings("unchecked") 
    @Override 
     public void onChanged(Change change) { 
      ((UpdateableListViewSkin<TestCaseCheckboxModel>)testcaseListView.getSkin()).refresh(); 
     } 
    }); 

此解決方案將觸發ListView的更新功能,像它的JavaFX的新版本。

+0

您可能遇到的問題是,在Java 9中,'ListViewSkin'將更改包,因此此解決方案將無法在該版本中運行。你真的還需要支持Java 6嗎? –

+0

是的,我絕對會這樣做,應用程序必須運行在過時的JVM上(舊的MATLAB版本使用jre6,這是我的要求)。不過,謝謝你的注意,但我會記住這一點,並在出現問題時找到解決辦法。 –