Я пытаюсь разработать приложение 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();
}
}