0

我有一个列出月份值的选择框,当用户选择一个值时,它会执行这个 lambda 表达式:

private TableView<IncomeFX> tableIncome;
private ChoiceBox<Month> choiceBoxIncomeMonths;

private ChangeListener<Month> setChoiceBoxIncomeMonthsBehaviour(){
    ChangeListener<Month> months = (ObservableValue<? extends Month> observable, Month oldValue, Month newValue) -> {
            incomesData.clear();
            Year selectedYear = choiceBoxIncomeYears.getSelectionModel().getSelectedItem();
            ObservableList<IncomeFX> temp = incomeManager.getIncomesOf(selectedYear, newValue);
            incomesData.addAll(temp);

    };
    return months;
}

以及我如何添加监听器:

choiceBoxIncomeMonths.getSelectionModel().selectedItemProperty().addListener(setChoiceBoxIncomeMonthsBehaviour());

当我单击选择框时,我得到:

Exception in thread "JavaFX Application Thread" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:386)
at java.util.AbstractList$Itr.next(AbstractList.java:355)
at java.util.AbstractCollection.addAll(AbstractCollection.java:343)
at javafx.collections.ModifiableObservableListBase.addAll(ModifiableObservableListBase.java:99)
at lite.money.ui.MainUI.lambda$1(MainUI.java:160)
at lite.money.ui.MainUI$$Lambda$120/1680764266.changed(Unknown Source)

它表明问题出在我调用的行中: addAll(temp) 我该如何解决?谢谢

4

3 回答 3

0

由于您尚未发布所有代码,我猜您正在尝试与 JavaFX 数据交互的另一个线程上运行代码。当另一个线程尝试执行此操作时,它将引发异常,因为只有 JavaFX 线程应该与数据交互。

我真的无法提供更多建议,因为我没有完整的代码库来说明你正在做什么来真正说“是的,在第 X 行,你有线程 Y 访问位置 X,而它不应该是。”

您是否将其添加到另一个线程上?你会比我更了解这个应用程序,因为我没有更多的代码可以使用。

于 2015-05-23T17:30:38.277 回答
0

这是我解决它的方法,我知道这是一个糟糕的代码,但我不知道任何其他解决方案,我必须清除它两次,否则如果我没有清除它,项目将被添加,如果你有其他解决方案我会很高兴:

private ChangeListener<Month> setChoiceBoxIncomeMonthsBehaviour(){
    ChangeListener<Month> months = (ObservableValue<? extends Month> observable, Month oldValue, Month newValue) -> {
        if (!lastMonthValuesFired) {
            incomesData.clear();
            Year selectedYear = choiceBoxIncomeYears.getSelectionModel().getSelectedItem();
            ObservableList<IncomeFX> temp = incomeManager.getIncomesOf(selectedYear, newValue);
            ObservableList<IncomeFX> temp2 = FXCollections.observableList(new ArrayList<IncomeFX>());

            for (IncomeFX t : temp) {
                temp2.add(t);
            }
            incomesData.clear();
            incomesData.addAll(temp2);
        }
    };
    return months;
}
于 2015-05-24T10:44:29.160 回答
0

我遇到了同样的问题并做了一些研究,这是我发现对我有用的解决方案:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * Java Program to demonstrate how to deal with
 * ConcurrentModificationException.
 * Unlike the name suggests, this error can come even if only 
 * one thread is modifying the collection e.g. List. 
 * It happens when you modify collection 
 * while iterating over it e.g. adding new element or removing elements.
 * 
 * If you want to remove elements while traversing list then 
 * make sure you use Iterator's remove() method or not ArrayList's remove()
 * method() to avoid ConcurrentModificationExcetpion.
 * 
 * @author WINDOWS 8
 *
 */
public class ConcurrentModExceptionDemo{

    public static void main(String args[]) {

        List<String> listOfPhones = new ArrayList<String>(Arrays.asList(
                "iPhone 6S", "iPhone 6", "iPhone 5", "Samsung Galaxy 4",
                 "Lumia Nokia"));
        
        System.out.println("list of phones: " + listOfPhones);
        
        // Iterating and removing objects from list
        // This is wrong way, will throw ConcurrentModificationException
        for(String phone : listOfPhones){
            if(phone.startsWith("iPhone")){
               // listOfPhones.remove(phone); // will throw exception
            }
        }
        
        // The Right way, iterating elements using Iterator's remove() method
        
        for(Iterator<String> itr = listOfPhones.iterator();
                                   itr.hasNext();){            
            String phone = itr.next();            
            if(phone.startsWith("iPhone")){
                // listOfPhones.remove(phone);  // wrong again
                itr.remove(); // right call
            }
        }
        
        System.out.println("list after removal: " + listOfPhones);

    }

}

资源

于 2022-01-24T13:37:27.057 回答