Просто для ясности, "фактическая" ошибка ...
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at java.desktop/java.awt.AWTEventMulticaster.mouseMoved(AWTEventMulticaster.java:337)
at java.desktop/java.awt.AWTEventMulticaster.mouseMoved(AWTEventMulticaster.java:337)
Итак, просматривая код ...
public void assign() {
int randomButton = this.clickMeGenerator();
theChosenButton = buttons[randomButton];
theChosenButton.addMouseMotionListener(new MouseHover());
theChosenButton.setText("Click me");
}
Вы неоднократно добавляете новый MouseMotionListener
для вас кнопки, снова и снова, и ...
public void removeListener() {
theChosenButton.removeMouseMotionListener(new MouseHover());
//}
}
бессмысленно, так как вы пытаетесь удалить новый экземпляр MouseHover
с кнопки, но он никогда не будетприменяется в первую очередь.
Первое, что я хотел бы сделать, это создать экземпляр MouseHover
в качестве поля экземпляра в Game
private MouseHover mouseHover = new MouseHover();
и использовать его при вызове addMouseMotionListener
и removeMouseMotionListener
.
Затем я бы удалил слушателя из «текущей» активной кнопки перед добавлением его к следующей.
Лично я бы сделал это в assign
method
public void assign() {
int randomButton = this.clickMeGenerator();
if (theChosenButton != null) {
theChosenButton.removeMouseMotionListener(mouseHover);
}
theChosenButton = buttons[randomButton];
theChosenButton.addMouseMotionListener(mouseHover);
theChosenButton.setText("Click me");
}
Я бы также гарантировал, что assign
вызывается из потока диспетчеризации событий при первом создании класса, поскольку пользовательский интерфейс был реализован концом конструктора Game
Это означает, что первый вызов assign
находится вне контекста EDT, что не рекомендуется.
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Game myGame = new Game();
myGame.assign();
}
});
}