У вас, похоже, проблемы с управлением контейнером.Остановитесь, сделайте шаг назад на секунду и переосмыслите свой подход.
У вас в основном есть панель "меню" и "игра".Это должны быть две отдельные панели / класс.
Затем они должны быть добавлены на панель "концентратор", которая управляет, когда и как они отображаются.
MainPane
Это «основная», «хаб» панель.Он отвечает за отображение как меню, так и игровых панелей.Он также отвечает за решение «как» это происходит, в этом примере я просто использовал CardLayout
public class MainPane extends JPanel {
public MainPane() {
setLayout(new CardLayout());
MenuPane menu = new MenuPane();
menu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (getLayout() instanceof CardLayout) {
CardLayout layout = (CardLayout) getLayout();
layout.show(MainPane.this, "game");
}
}
});
GamePane game = new GamePane();
add(menu, "menu");
add(game, "game");
((CardLayout) getLayout()).show(this, "menu");
}
}
MenuPane
«Меню» довольно простое.Он просто отображает доступные опции и предоставляет заинтересованным сторонам возможность получать уведомления при выборе опции
public class MenuPane extends JPanel {
private JButton btn;
public MenuPane() {
setLayout(new GridBagLayout());
setBackground(Color.BLUE);
btn = new JButton("Start");
add(btn);
}
public void addActionListener(ActionListener listener) {
btn.addActionListener(listener);
}
public void removeActionListener(ActionListener listener) {
btn.removeActionListener(listener);
}
}
Я не буду вдаваться в подробности по этому поводу, но вы должны взглянуть на Как использовать кнопки, флажки и радио-кнопки и Как написать слушатель действий для получения более подробной информации
Отказ от ответственности ...
I'mбыл ленив, прикрепляя ActionListener
s прямо к кнопкам.Вместо этого вы должны управлять слушателями кнопок и слушателями панели по отдельности, это предотвратит раскрытие кнопок и позволит вам лучше контролировать то, что генерируется при выполнении определенной операции.
GamePane
* 1033И, наконец, «игровая» панель.Как я уже говорил в последний день, вы должны использовать
пользовательский маршрут рисования и
Как использовать привязки клавиш .Вместе они решат чванство других вопросов, о которых мы обычно не хотели бы спрашивать, опять же
public interface Movable {
public void changeLocation(int xDelta, int yDelta);
}
public class GamePane extends JPanel implements Movable {
private Rectangle player;
public GamePane() {
String text = "X";
FontMetrics fm = getFontMetrics(getFont());
int width = fm.stringWidth(text);
int height = fm.getHeight();
player = new Rectangle(0, 0, width, height);
setupKeyBindings();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void setupKeyBindings() {
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "up");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "down");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "left");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "right");
int xDelta = player.width;
int yDelta = player.height;
am.put("up", new MoveAction(this, 0, -yDelta));
am.put("down", new MoveAction(this, 0, yDelta));
am.put("left", new MoveAction(this, -xDelta, 0));
am.put("right", new MoveAction(this, xDelta, 0));
}
@Override
public void changeLocation(int xDelta, int yDelta) {
int xPos = player.x + xDelta;
int yPos = player.y + yDelta;
if (xPos + player.width > getWidth()) {
xPos = getWidth() - player.width;
} else if (xPos < 0) {
xPos = 0;
}
if (yPos + player.height > getHeight()) {
yPos = getHeight() - player.height;
} else if (xPos < 0) {
yPos = 0;
}
player.setLocation(xPos, yPos);
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
g2d.draw(player);
FontMetrics fm = g2d.getFontMetrics();
g2d.drawString("X", player.x, player.y + fm.getAscent());
g2d.dispose();
}
}
public class MoveAction extends AbstractAction {
private Movable movable;
private int xDelta;
private int yDelta;
public MoveAction(Movable movable, int xDelta, int yDelta) {
this.movable = movable;
this.xDelta = xDelta;
this.yDelta = yDelta;
}
@Override
public void actionPerformed(ActionEvent e) {
movable.changeLocation(xDelta, yDelta);
}
}
Runnable Example ...
Собираем все вместе ....
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Game {
public static void main(String[] args) {
new Game();
}
public Game() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MainPane extends JPanel {
public MainPane() {
setLayout(new CardLayout());
MenuPane menu = new MenuPane();
menu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (getLayout() instanceof CardLayout) {
CardLayout layout = (CardLayout) getLayout();
layout.show(MainPane.this, "game");
}
}
});
GamePane game = new GamePane();
add(menu, "menu");
add(game, "game");
((CardLayout) getLayout()).show(this, "menu");
}
}
public class MenuPane extends JPanel {
private JButton btn;
public MenuPane() {
setLayout(new GridBagLayout());
setBackground(Color.BLUE);
btn = new JButton("Start");
add(btn);
}
public void addActionListener(ActionListener listener) {
btn.addActionListener(listener);
}
public void removeActionListener(ActionListener listener) {
btn.removeActionListener(listener);
}
}
public interface Movable {
public void changeLocation(int xDelta, int yDelta);
}
public class GamePane extends JPanel implements Movable {
private Rectangle player;
public GamePane() {
String text = "X";
FontMetrics fm = getFontMetrics(getFont());
int width = fm.stringWidth(text);
int height = fm.getHeight();
player = new Rectangle(0, 0, width, height);
setupKeyBindings();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void setupKeyBindings() {
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "up");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "down");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "left");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "right");
int xDelta = player.width;
int yDelta = player.height;
am.put("up", new MoveAction(this, 0, -yDelta));
am.put("down", new MoveAction(this, 0, yDelta));
am.put("left", new MoveAction(this, -xDelta, 0));
am.put("right", new MoveAction(this, xDelta, 0));
}
@Override
public void changeLocation(int xDelta, int yDelta) {
int xPos = player.x + xDelta;
int yPos = player.y + yDelta;
if (xPos + player.width > getWidth()) {
xPos = getWidth() - player.width;
} else if (xPos < 0) {
xPos = 0;
}
if (yPos + player.height > getHeight()) {
yPos = getHeight() - player.height;
} else if (xPos < 0) {
yPos = 0;
}
player.setLocation(xPos, yPos);
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
g2d.draw(player);
FontMetrics fm = g2d.getFontMetrics();
g2d.drawString("X", player.x, player.y + fm.getAscent());
g2d.dispose();
}
}
public class MoveAction extends AbstractAction {
private Movable movable;
private int xDelta;
private int yDelta;
public MoveAction(Movable movable, int xDelta, int yDelta) {
this.movable = movable;
this.xDelta = xDelta;
this.yDelta = yDelta;
}
@Override
public void actionPerformed(ActionEvent e) {
movable.changeLocation(xDelta, yDelta);
}
}
}
Помните, одна из ваших целей должна заключаться в «разделении ответственности», создании классов / компонентов, которые выполняют свою работу и делают это хорошо.Таким образом, вы можете использовать их как строительные блоки для разработки гораздо более сложных решений