Многопоточность JavaFX ListChangeListener - PullRequest
0 голосов
/ 02 декабря 2018

Я пытаюсь разработать приложение JavaFX для имитации системы лифта.

Каждый объект Elevator работает в своем собственном потоке, и я хочу отобразить каждый Elevator.toString () в виде списка.Проблема в том, что после некоторого запуска приложения я получу NullPointerException или IndexOutOfBounds из одного или нескольких потоков элеватора.Я создал ObservableList Лифтов, где я слушаю любые изменения свойств, затем у меня есть другой ObservableList типа string, который связан с listView.Второй - обновление каждый раз, когда слушатель изменений запускает функцию wasUpdated () из первого списка.

final ObservableList<String> elevators = FXCollections.observableArrayList();

    final ObservableList<Elevator> obsList = FXCollections.observableArrayList(
            new Callback<Elevator, Observable[]>() {
                @Override
                public Observable[] call(Elevator param) {
                    return new Observable[]{
                            param.getCurrentFloorProp(),
                            param.getDirProp(),
                            param.getSmallSchedule(),
                            param.getDoorsProp(),
                            param.getStatusProp()
                    };
                }
            }
    );

    obsList.addListener(new ListChangeListener<Elevator>() {
        @Override
        public void onChanged(Change<? extends Elevator> c) {
            c.reset();
            while (c.next()) {
                if (c.wasUpdated()) {
                        Platform.runLater(() -> {
                            elevators.set(c.getFrom(), obsList.get(c.getFrom()).toString());
                        });
                }
            }
        }
    });

При попытке исправить это у меня две мысли: либо ChangeListener запускает больше изменений, чем Platform.runLater успевает обработать, либо что-то в той же строке, что и https://stackoverflow.com/a/31414801/9696324. Однако я не могуЧтобы заставить предложенные решения работать, это обычно происходит через 2-3 минуты после запуска программы без проблем.

При возникновении первой ошибки графический интерфейс обычно зависает (пока программа работает нормально), а затем начинает рассылать те же ошибки.

Буду очень признателен за любые мысли или указатели, спасибо.

Свойства объявлены в конструкторе лифта:

currentFloor = new SimpleIntegerProperty(INITIAL_FLOOR);
    smallSchedule = new SimpleStringProperty("");
    status = new SimpleBooleanProperty(true);
    dir = new SimpleStringProperty("S");
    doors = new SimpleStringProperty("Doors closed");

И следующие методы получения и установки:

public StringProperty getSmallSchedule() {
    return smallSchedule;
}
public StringProperty getDoorsProp() {
    return doors;
}
public StringProperty getDirProp() {
    return dir;
}
public IntegerProperty getCurrentFloorProp() {
    return currentFloor;
}
public BooleanProperty getStatusProp() {
    return status;
} 

public void setCurrentFloor(int floorNr) { 
    currentFloor.set(floorNr);
}
public void setStatus(boolean status) {
    this.status.set(status);
}
public void setDir(char dir) {
    this.dir.set(Character.toString(dir));
}
public void setSmallSchedule() {
    String temp = "";
    for(int i = 0; i < travelSchedule.size()-1;i++) {
        if(travelSchedule.get(i)==INT_MAX || i > 2)
            break;
        temp += " " + travelSchedule.get(i);
    }
    smallSchedule.set(temp);
}
public void doors(){
    try {
        Thread.sleep(doorOpen);
        doors.set("Doors open");
        Thread.sleep(doorWait);
        checkMBox();
        Thread.sleep(doorClose);
        doors.set("Doors closed");
    } 
    catch (InterruptedException e) {
        e.printStackTrace();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...