Каков правильный способ обработки/реализации onMouseClick из компонентов JavaFX?

У меня был длинный подробный вопрос о том, почему мой пользовательский элемент управления не работает повсюду. Для тех, кто, возможно, сталкивался с чем-то подобным, я нашел ОТЛИЧНУЮ, ОЧЕНЬ недавнюю статью здесь.

Это было фантастически, я не шучу.

Но теперь у меня другая проблема. У меня есть несколько текстовых фигур на моем элементе управления, которые должны реагировать на щелчки мыши (как одиночные, так и двойные), а также сам элемент управления.

Раньше в инструменте JavaFX Scene Builder я устанавливал эти элементы управления On Mouse Clicked в разделе кода с тем же именем метода и реализовывал это имя в контроллере. Проблема в том, что именно из-за этого все ломалось и ломалось, а я плакал.

Например, в Конструкторе сцен все соответствующие элементы управления On Mouse Clicked были установлены на handleMouse (я знаю общее имя метода, но оно подходит для моих целей). Затем у меня был внутри контроллера другой метод, который обрабатывал (как я думал) событие мыши:

@FXML
protected void handleMouse(MouseEvent ME){
    if (ME.getClickCount() > 1) //Do stuff
    else if (/*Other Condition*/) //Do something else
    else if (/*Final Condition*/) //Do something else
}

Я думал, что это правильно, НО! Следуя руководству, которое я связал, я обнаружил, к своему огорчению, что, скорее всего, ошибаюсь. Когда я просмотрел скелет контроллера для интерфейса из JavaFX Scene Builder, я обнаружил, что он обрабатывает событие следующим образом:

@FXML
protected void handleMouse(ActionEvent e){
}

Сейчас это кажется неправильным. Если MouseEvent не расширен из ActionEvent? Так ли это?

В любом случае, я попытался проигнорировать это и сделать по-своему, и это взорвалось. Сюрприз-сюрприз, теперь я знаю, ПОЧЕМУ он взорвался.

Даже попытка установить каждое control.onMouseClicked с помощью лямбды приводит к взрыву:

this.texts.stream().foreach((Text txt -> { //texts stores all the controls Text objects for convenient access.
    txt.setOnMouseClicked((MouseEvent ME) -> {
        //Do stuff here (See above)
    };
});

Опять же, когда я убил этот код, он работал нормально (за исключением того, что на самом деле ничего не делал, я имею в виду, что работал нормально в относительном смысле, он ЗАГРУЗИЛСЯ без взрыва).

Итак, как я должен правильно захватить MouseEvent? Расширен ли он от ActionEvent? Это должно иметь значение? Это вообще НАСТОЯЩАЯ причина, почему он взорвался?

У меня есть больше кода, если нужно.


person Will    schedule 12.07.2014    source источник
comment
Ваш метод обработчика мыши, принимающий MouseEvent, кажется мне правильным. Что вы имеете в виду под взрывом? Что на самом деле идет не так?   -  person James_D    schedule 13.07.2014
comment
Чтобы еще немного сократить количество аварийных швов, возникающих в этом бите: this.Texts.stream().forEach((Text txt) -> {...}); Он никогда не делает это до того, как сломается, и выдает довольно общее исключение. См. этот pastebin: pastebin.com/92PEmQHQ   -  person Will    schedule 13.07.2014
comment
Хорошо, вопрос решен. Возможно, я добавлял тексты в массив ДО того, как вызывал загрузчик, но изменение этого порядка, похоже, исправило ситуацию. Ух!   -  person Will    schedule 13.07.2014


Ответы (1)


Я чувствую, что нашел проблему. До того, как мой код в конструкторе был установлен так:

this.texts = new ArrayList<>();
this.texts.add(this.shapeName);
this.texts.add(this.shapeNameValue);
this.texts.add(this.shapeScore);
this.texts.add(this.shapeScoreValue);

this.loader = new FXMLLoader(
    this.getClass().getResource("JPlayer.fxml")
);
this.loader.setController(this);
this.loader.setRoot(this);

try { this.loader.load(); }
catch( IOException ex ) { throw new RuntimeException(ex); }

Затем, когда я попытался передать массив массивов, это вызвало исключение. Я могу только догадываться, почему, но добавление элементов ПОСЛЕ, похоже, решило проблему. В любом случае, надеюсь, это окажется полезным для кого-то в будущем.

person Will    schedule 13.07.2014