我有一个JFrame和2个JPanel。一个面板是带按钮的开始屏幕。另一个面板是游戏画面。当我删除开始屏幕并显示游戏屏幕时,JFrame没有任何反应。开始屏幕是持久的但不可用,游戏在后台运行而不更新屏幕。当游戏完成时,开始屏幕再次可用。我在网上到处寻找解决方案。他们都说removeAll,revalidate,repaint,pack或getContentPane.removeAll。我还没有能够使用这些解决方案。这是驱动程序类:
public class BallDriver extends JFrame {
private static final long serialVersionUID = 1L;
int width = 500;
int height = 500;
Container cont;
StartScreen start;
BallGame ballGame;
public BallDriver() {
cont = getContentPane();
startScreen();
}
private void startScreen() {
setTitle("BallGame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(new Dimension(width, height));
setPreferredSize(new Dimension(500,500));
start = new StartScreen();
JButton[] startButtons = start.getButtons();
setupButtons(startButtons);
add(start, BorderLayout.CENTER);
}
private void startGame(String difficulty) throws InterruptedException {
removeAll();
setSize(new Dimension(width, height));
setPreferredSize(new Dimension(width, height));
ballGame = new BallGame(width, height);
ballGame.setPreferredSize(new Dimension(width, height));
add(ballGame, BorderLayout.CENTER);
revalidate();
repaint();
while(!ballGame.endGame()) {
ballGame.moveBall();
ballGame.repaint();
try {
Thread.sleep(2);
} catch (InterruptedException e) { e.printStackTrace(); }
}
removeAll();
add(start, BorderLayout.CENTER);
revalidate();
repaint();
}
private void setupButtons(final JButton[] buttons) {
for (JButton button : buttons) {
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Object object = e.getSource();
try {
if (object == buttons[0])
startGame(StartScreen.MODE_EASY);
if (object == buttons[1])
startGame(StartScreen.MODE_NORMAL);
if (object == buttons[2])
startGame(StartScreen.MODE_HARD);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
});
}
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
BallDriver ballDriver = new BallDriver();
ballDriver.setVisible(true);
}
});
}
}
编辑: 我已经更新了类以使用cardlayout,但同样的事情发生了。
public class BallDriver extends JFrame {
private static final long serialVersionUID = 1L;
int width = 500;
int height = 500;
JPanel cardPanel = new JPanel();
Container cont;
StartScreen start;
BallGame ballGame;
CardLayout cardLayout = new CardLayout();
public BallDriver() {
setTitle("BallGame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(new Dimension(width, height));
setPreferredSize(new Dimension(width, height));
cardPanel.setLayout(cardLayout);
cont = getContentPane();
add(cardPanel, BorderLayout.CENTER);
startScreen();
}
private void startScreen() {
start = new StartScreen();
JButton[] startButtons = start.getButtons();
setupButtons(startButtons);
cardPanel.add(start, "start");
cardLayout.show(cardPanel, "start");
}
private void startGame(String difficulty) throws InterruptedException {
ballGame = new BallGame(width, height);
cardPanel.add(ballGame, "game");
cardLayout.show(cardPanel, "game");
cardPanel.revalidate();
cardPanel.repaint();
while(!ballGame.endGame()) {
System.out.println("Running");
ballGame.moveBall();
ballGame.repaint();
try {
Thread.sleep(2);
} catch (InterruptedException e) { e.printStackTrace(); }
}
}
private void setupButtons(final JButton[] buttons) {
for (JButton button : buttons) {
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Object object = e.getSource();
try {
if (object == buttons[0])
startGame(StartScreen.MODE_EASY);
if (object == buttons[1])
startGame(StartScreen.MODE_NORMAL);
if (object == buttons[2])
startGame(StartScreen.MODE_HARD);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
});
}
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
BallDriver ballDriver = new BallDriver();
ballDriver.setVisible(true);
}
});
}
}
答案 0 :(得分:2)
CardLayout
允许您向Container
添加多个面板,一次只显示1个面板,并且可以在面板之间切换。您将父级布局设置为CardLayout
,向您的帧添加面板,指定名称作为约束:
CardLayout layout = new CardLayout();
JFrame frame = new JFrame();
frame.setLayout(layout);
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
frame.add(panel1, "first");
frame.add(panel2, "second");
添加的第一个面板是第一个显示的tk。要在面板之间切换,请调用CardLayout#show(Container, String)
,传递面板的父级(考虑" deck ")和所需的特定面板的名称(考虑" 卡")。
layout.show(frame, "second");
人们对CardLayout
的一个常见问题是让父级调整大小为当前面板的大小。这可以通过extending upon CardLayout