Я какое-то время работал над Java-игрой, которую начал еще в студенческие годы. После значительных перерывов, связанных с моей профессиональной карьерой, я вернулся к этому и понял, насколько ужасен код. У меня в основном был «монолитный основной» с графическим интерфейсом и игровой логикой в одном файле классов. То, что я пытаюсь сделать, это абстрагировать и «разбить» GUI на более мелкие куски. Мой исполняемый класс расширяет JFrame , который я добавляю и удаляю панели в / из при нажатии кнопок. Ex.
public class GameFrame extends JFrame{
private JPanel[] _panels = {new MainPanel(), new OptionsPanel(), new DifficultyPanel()};
private int _currentPanelIndex = 0;
public GameFrame(){
...
add(_panels[_currentPanelIndex]);
...
}
}
В каждом классе панели у меня есть приватные ActionListeners для кнопок. В MainPanel я получаю экземпляр singleton GameFrame и устанавливаю текущую панель вроде:
class SinglePlayerButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e){
GameFrame instance = GameFrame.getInstance();
JPanel[] panels = instance.getPanels();
int currentPanelIndex = instance.getCurrentPanelIndex();
instance.remove(panels[currentPanelIndex]);
int newPanelIndex;
for(newPanelIndex = 0; newPanelIndex < panels.length; newPanelIndex++){
if(panels[newPanelIndex] instanceof DifficultyPanel){
break;
}
}
instance.add(panels[newPanelIndex]);
}
}
Мне не нравится эта глубокая связь в моих классах, но я могу жить с этим. Однако реальная проблема заключается в том, что когда я нажимаю последнюю кнопку, которая приводит меня в игру, у меня не может быть:
public void actionPerformed(ActionEvent e){
GameFrame.getInstance().startGame();
}
потому что это приведет к тому, что моя игра будет запущена в потоке Java Event , что не позволит обрабатывать любые другие события. Ранее у меня был занят цикл while:
...
while(waiting){
//Do nothing
}
remove(_panels[_currentPanelIndex]);
startGame();
...
...
public void actionPerformed(ActionEvent e){
waiting = false;
}
Как лучше всего сообщить классу GameFrame , что я нажал кнопку воспроизведения? Могу ли я отправить ему событие или сообщение с одной из его подпанелей с указанием запустить его, и если да, как я могу предотвратить запуск игры в потоке Event ? Должен ли я обработать это в методе actionPerformed () и просто создать новый поток? Я бы предпочел оставить это в главной теме. Спасибо.