2016-08-17 56 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,这是我的要求)。不过,谢谢你的注意,但我会记住这一点,并在出现问题时找到解决办法。 –