Я хочу вызвать «основной поток» (начальный поток, который запускает main()
), чтобы выполнить некоторую работу с помощью метода ActionListener кнопки, но я не знаю, как этого добиться.Java Swing: Как просыпаться основной поток из потока событий?
Побольше контекст:
Я в настоящее время программирования 2D игры с использованием свинга (аромат тетриса).
Когда приложение запускается, открывается окно с отображением главного меню игры. Пользователю предлагается несколько возможностей, один из которых - начать игру, нажав кнопку «Пуск», которая вызывает отображение игровой панели и запускает основной цикл игры.
Чтобы иметь возможность переключаться между двумя панелями (в главном меню и в игре), я использую диспетчер CardLayout, после чего я могу отобразить одну панель, вызвав show()
.
Идея заключается в том, что я хотел бы мою кнопку запуска, чтобы слушатель, который выглядит следующим образом:
public class StartListener implements ActionListener {
StartListener() {}
public void actionPerformed(ActionEvent e) {
displayGamePanel();
startGame();
}
}
, но это не работает, потому что actionPerformed()
вызывается из событий отправки потока, поэтому вызов startGame()
(который запускает основной цикл: обновление логической игры + repaint()
вызов в каждом кадре) блокирует весь поток.
Путь, я обработки это прямо сейчас, что actionPerformed()
просто меняет логическое значение флага: public void actionPerformed(ActionEvent e) { startPushed = true; }
, который затем в конечном счете проверяется основным потоком:
while (true) {
while (!g.startPushed) {
try {
Thread.sleep(100);
} catch (Exception e) {}
}
g.startPushed = false;
g.startGame();
}
Но я считаю это решение очень безвкусный.
Я прочитал урок Concurrency in Swing, но я все еще смущен (должен ли я реализовать Рабочую нить - не так ли немного перебор?). Я еще не выполнял многопоточную работу, поэтому я немного потерялся.
Нет ли способа рассказать основную тему (которая будет спать бесконечно, ожидая действия пользователя) «ОК, проснись сейчас и сделай это (покажите панель игры и начните игру)» ?.
Благодарим за помощь.
EDIT: Просто чтобы быть ясно, это то, что моя игра цикл выглядит следующим образом:
long lastLoopTime = System.currentTimeMillis();
long dTime;
int delay = 10;
while (running) {
// compute the time that has gone since the last frame
dTime = System.currentTimeMillis() - lastLoopTime;
lastLoopTime = System.currentTimeMillis();
// UPDATE STATE
updateState(dTime);
//...
// UPDATE GRAPHICS
// thread-safe: repaint() will run on the EDT
frame.repaint()
// Pause for a bit
try {
Thread.sleep(delay);
} catch (Exception e) {}
}
Спасибо, я смотрю на эту возможность прямо сейчас, это похоже на то, что я ожидал :) – Rez