В вашем коде много чего происходит и слишком много "угадай работы".Вы также объединили свой код, что сделало практически невозможным его обслуживание или управление.
Отойдите назад и пересмотрите свой дизайн.Вам необходимо:
- Контейнер, который выступает в качестве «основного вида», это контейнер, который используется для переключения между различными представлениями, он выступает в качестве основного «контроллера» для навигации
- Компонент меню
- Игровой компонент
- Рамка для хранения "основного вида"
Давайте начнем с рамки.Рама должна быть максимально тупой.Его единственная задача - получить «главный вид» на экране, совсем немного
Может быть, что-то вроде ...
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
MainPane
(или основной вид) не 'не заботиться о кадре, поэтому нам не нужно ничего передавать ему.Поскольку «главный вид» выступает в качестве нашего контроллера навигации, вы не должны подвергать его другим видам.Этим представлениям не важно, как работает навигация, только то, что они могут перемещаться между представлениями.
Таким образом, вместо передачи MainPane
в подпредставления, мы создаем концепцию «контроллера навигации», которая используется дляразрешите подпредставлениям делать запросы о том, что они хотели бы сделать, и затем реализация должна выполнить эту работу.
public interface NavigationController {
public void showGame();
public void showMenu();
}
MainPane
затем выступает в качестве "основного контейнера" для всех остальных топов.подвиды уровня и NavigationController
public class MainPane extends JPanel implements NavigationController {
public MainPane() {
setLayout(new CardLayout());
add(new MenuPane(this), "menu");
add(new GamePane(this), "game");
}
protected CardLayout getCardLayout() {
return (CardLayout) getLayout();
}
@Override
public void showGame() {
getCardLayout().show(this, "game");
}
@Override
public void showMenu() {
getCardLayout().show(this, "menu");
}
}
Вся ответственность заключается в том, чтобы облегчить переключение между подпредставлениями верхнего уровня
Тогда наши подпредставления ....
public class MenuPane extends JPanel {
private NavigationController controller;
public MenuPane(NavigationController controller) {
this.controller = controller;
setLayout(new GridBagLayout());
JButton btn = new JButton("Do you want to play a game?");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
controller.showGame();
}
});
add(btn);
}
}
public class GamePane extends JPanel {
private NavigationController controller;
public GamePane(NavigationController controller) {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.weighty = 1;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel("Ready player one"), gbc);
gbc.weighty = 0;
JButton btn = new JButton("Had enough");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
controller.showMenu();
}
});
add(btn, gbc);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
Эти представления выполняют одну работу (что бы это ни было) и делегируют ответственность за навигацию обратно к NavigationController
Если вам интересно, MenuPane
будет вашим эквивалентом ButtonPane
Пример выполнения ...
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface NavigationController {
public void showGame();
public void showMenu();
}
public class MainPane extends JPanel implements NavigationController {
public MainPane() {
setLayout(new CardLayout());
add(new MenuPane(this), "menu");
add(new GamePane(this), "game");
}
protected CardLayout getCardLayout() {
return (CardLayout) getLayout();
}
@Override
public void showGame() {
getCardLayout().show(this, "game");
}
@Override
public void showMenu() {
getCardLayout().show(this, "menu");
}
}
public class MenuPane extends JPanel {
private NavigationController controller;
public MenuPane(NavigationController controller) {
this.controller = controller;
setLayout(new GridBagLayout());
JButton btn = new JButton("Do you want to play a game?");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
controller.showGame();
}
});
add(btn);
}
}
public class GamePane extends JPanel {
private NavigationController controller;
public GamePane(NavigationController controller) {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.weighty = 1;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel("Ready player one"), gbc);
gbc.weighty = 0;
JButton btn = new JButton("Had enough");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
controller.showMenu();
}
});
add(btn, gbc);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}