如何修复 JPanel 循环?
How to fix JPanel loop?
我已经完成了简单的形状游戏。代码有 3 个 JPanel,其中包含开始、游戏和游戏结束。在代码中,一切都是完美的,但游戏结束时我必须包括计算鼠标点击的游戏得分 score.I 不能包括最后一个面板 JPanel 中的 score.That 得分页面。并且我包含了 JButton,例如 {try again} 和 {exit}。当我按下重试按钮时,我无法完美地看到我的第一个 Jpanel,它包含开始按钮。我该如何解决?
这是沉重的代码,我希望它不是乱七八糟的
public class myshapestry implements ActionListener {
JFrame frame= new JFrame();
MyPanel panel=new MyPanel();
Container l ;
private int ballXSpeed=150;
private int ballSpeed=90;
private int ballX=150;
private int ballY=200;
Color c=Color.BLACK;
JLabel statusbar = new JLabel("This game is developed by Asuskobay");
Startthegame panelstart= new Startthegame();//this is start JPanel
chooselevel panellevel= new chooselevel();//this is difficulties JPanel
thegameover gameover=new thegameover();//End of page
private int mouseclicks;//mouseclicks score
private int mouse;
public myshapestry() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.add(panel);
frame.add(panellevel);
frame.add(gameover);
frame.add(panelstart);
frame.add(statusbar, BorderLayout.SOUTH);
frame.setVisible(true);
frame.setSize(getPreferredSize());
frame.setTitle("Game of Shapes");
HandlerClass handler=new HandlerClass();
panel.addMouseListener(handler);
panel.addMouseMotionListener(handler);
Timer timer=new Timer(100,panel) ;
timer.start();
}
public Dimension getPreferredSize() {
return new Dimension(900,730);
}
private class HandlerClass implements MouseMotionListener, MouseListener {
public void mouseClicked(MouseEvent e){
mouseclicks++;
statusbar.setText(String.format("MouseLoc ( %d, %d ) \t \t Mouse Click \t", e.getX(), e.getY()) + mouseclicks);
mouseclicks=mouse;
}
@Override
public void mousePressed(MouseEvent event) {
if(event.getX() <= (ballX+90) && event.getX() >= (ballX) && event.getY() <= (ballY+90) && event.getY() >= (ballY))
c=Color.RED;
} }
public class MyPanel extends JPanel implements ActionListener {
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(c);
g.fillOval(ballX, ballY, 90 , 90);
}
public void actionPerformed(ActionEvent e) { //balls movement
ballX = ballX + ballXSpeed;
ballY = ballY + ballSpeed;
if(ballY>=730-185){
ballSpeed = -ballSpeed;
}
if(ballX>=900-180){
ballXSpeed = -ballXSpeed;
}
if(ballY<=0+60){
ballSpeed= -ballSpeed;
}
if (ballX<=0+60){
ballXSpeed= -ballXSpeed;
}
repaint();
if(c==Color.RED){
frame.remove(panel);
frame.add(gameover);
frame.validate();
}}}
public class chooselevel extends JPanel implements ActionListener {
private JButton easy;
private JButton normal;
private JButton hard;
public chooselevel(){
setLayout(null);
easy=new JButton("Easy");
normal=new JButton("Normal");
hard=new JButton("Hard");
easy.setBounds(380,330,90,20);
normal.setBounds(380,370,90,20);
hard.setBounds(380,410,90,20);
add(hard);
add(easy);
add(normal);
hard.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent l){
String level=l.getActionCommand();
if(level.equals("Hard")){
ballXSpeed=190;
ballSpeed=184;
frame.remove(panellevel);
frame.add(panel);
frame.validate();
}} });
normal.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent l){
String level=l.getActionCommand();
if(level.equals("Normal")){
ballXSpeed=157;
ballSpeed=123;
frame.remove(panellevel);
frame.add(panel);
frame.validate();
}}});
easy.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent l){
String level=l.getActionCommand();
if(level.equals("Easy")){
ballXSpeed=85;
ballSpeed=74;
frame.remove(panellevel);
frame.add(panel);
frame.validate();
}} });
}
public Dimension getPreferredSize() {
return new Dimension(900,730);
} }
public class Startthegame extends JPanel implements ActionListener {
private JButton Start;
private JButton Exit;
public Startthegame() {
setLayout(null);
Start = new JButton("Start");
Exit = new JButton("Exit");
Start.setBounds(380,330,70,20);
Exit.setBounds(380,370,70,20);
add(Start);
add(Exit);
Exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent i){
String action= i.getActionCommand();
if(action.equals("Exit")) {
System.exit(0);
}}
});
Start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent i){
String action= i.getActionCommand();
if(action.equals("Start")) {
frame.remove(panelstart);
frame.add(panellevel);
frame.validate();
repaint();
} }});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(900, 730);
} }
public class thegameover extends JPanel {
private JLabel gameisover;
private JLabel yourscore;
private JButton tryagain;
private JButton Exit;
thegameover(){
setLayout(null);
gameisover= new JLabel("GAME OVER");
yourscore=new JLabel();
add(gameisover);
add(yourscore);
gameisover.setBounds(170,200,600,70);
yourscore.setBounds(380,380,120,70);
gameisover.setFont(new Font(null, Font.PLAIN, 90));
yourscore.setFont(new Font(null, Font.PLAIN, 20));
yourscore.setText ("Your Score " + mouseclicks);
tryagain=new JButton("Try Again");
Exit=new JButton("Exit");
add(tryagain);
add(Exit);
tryagain.setBounds(280,550,100,20);
Exit.setBounds(490,550,100,20);
tryagain.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ac){
String tryit=ac.getActionCommand();
if(tryit.equals("Try Again")){
frame.remove(gameover);
frame.add(panelstart);
frame.validate();
repaint();
}
}
});
}
public Dimension getPreferredSize(){
return new Dimension(900,73);
}}
public static void main (String args[]){
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
myshapestry tr=new myshapestry();
}
});
} }
编辑后:
我创建了新的 Jpanel 来收集其中的所有 Jpanel,以便在 Frame 中添加状态栏,但我收到错误,出了点问题
public class myshapestry implements ActionListener {
collectionpanel collectpanel= new collectionpanel();
public myshapestry() {
frame.add(collectpanel);
public class collectionpanel extends JPanel {
collectionpanel(){
cardlayout= new CardLayout();
this.setLayout(cardlayout);
this.add(panel, "game");
this.add(panellevel,"level");
this.add(gameover, "over");
this.add(panelstart, "start");
cardlayout.show(collectpanel, "game");
cardlayout.show(collectpanel, "level");
cardlayout.show(collectpanel, "start");
cardlayout.show(collectpanel, "over");
} }
错误;
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: wrong parent for CardLayout
at java.awt.CardLayout.checkLayout(Unknown Source)
at java.awt.CardLayout.show(Unknown Source)
at example.myshapestry$collectionpanel.<init>(myshapestry.java:100)
at example.myshapestry.<init>(myshapestry.java:58)
at example.myshapestry.run(myshapestry.java:393)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access0(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
存在一连串的问题,所有问题共同作用导致混乱...
- 当游戏是 "over" 时,您永远不会停止
Timer
,这意味着当您尝试显示 "game over" 屏幕或尝试重新启动时,"game panel" 仍在尝试更新屏幕...
- 您对屏幕的管理使情况更加复杂。您一开始就添加了所有屏幕,但稍后又 remove/add 它们,这只会造成混乱。
而是...
- 在使 "game screen" 可见之前,启动
Timer
。当您检测到游戏为"over"时,在显示"over"屏幕之前,停止Timer
- 改用
CardLayout
。有关详细信息,请参阅 How to Use CardLayout
例如...
创建一个 CardLayout
实例字段并将 Timer
也设为实例字段
public class MyShapes {//implements ActionListener {
//...
private CardLayout cardLayout;
private Timer timer = new Timer(100, panel);
将 CardLayout
应用于 frame
并命名每个视图...
public MyShapes() {
//...
cardLayout = new CardLayout();
frame.setLayout(cardLayout);
frame.add(panel, "game");
frame.add(panellevel, "level");
frame.add(gameover, "over");
frame.add(panelstart, "start");
frame.add(statusbar, BorderLayout.SOUTH);
cardLayout.show(frame.getContentPane(), "start");
//...
}
当用户选择 "start" 时,使用 CardLayout
切换视图
Start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent i) {
String action = i.getActionCommand();
if (action.equals("Start")) {
//frame.remove(panelstart);
//frame.add(panellevel);
//frame.validate();
cardLayout.show(frame.getContentPane(), "level");
}
}
});
开始游戏时,启动Timer
并使用CardLayout
切换视图...
hard.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent l) {
String level = l.getActionCommand();
if (level.equals("Hard")) {
ballXSpeed = 190;
ballSpeed = 184;
//frame.remove(panellevel);
//frame.add(panel);
//frame.validate();
timer.start();
cardLayout.show(frame.getContentPane(), "game");
}
}
});
当您检测到 "game over" 条件时,停止 Timer
并使用 CardLayout
切换视图...
if (c == Color.RED) {
//frame.remove(panel);
//frame.add(gameover);
//frame.validate();
timer.stop();
cardLayout.show(frame.getContentPane(), "over");
}
现在,关于得分问题...
当您创建 thegameover
面板时,您使用 yourscore.setText("Your Score " + mouseclicks);
,但是当您创建视图时 mouseclicks
是 0
,您需要以某种方式更新此值。 ...
向 thegameover
添加方法 class,调用类似于 setScore
的方法并相应地更新标签...
public void setScore(int score) {
yourscore.setText("Your Score " + score);
}
当您检测到游戏结束时,更新比分...
timer.stop();
gameover.setScore(mouseclicks);
cardLayout.show(frame.getContentPane(), "over");
您可能希望通读 Code Conventions for the Java TM Programming Language,这将使人们更容易阅读您的代码,您也可以更轻松地阅读其他人
也是值得的
我已经完成了简单的形状游戏。代码有 3 个 JPanel,其中包含开始、游戏和游戏结束。在代码中,一切都是完美的,但游戏结束时我必须包括计算鼠标点击的游戏得分 score.I 不能包括最后一个面板 JPanel 中的 score.That 得分页面。并且我包含了 JButton,例如 {try again} 和 {exit}。当我按下重试按钮时,我无法完美地看到我的第一个 Jpanel,它包含开始按钮。我该如何解决? 这是沉重的代码,我希望它不是乱七八糟的
public class myshapestry implements ActionListener {
JFrame frame= new JFrame();
MyPanel panel=new MyPanel();
Container l ;
private int ballXSpeed=150;
private int ballSpeed=90;
private int ballX=150;
private int ballY=200;
Color c=Color.BLACK;
JLabel statusbar = new JLabel("This game is developed by Asuskobay");
Startthegame panelstart= new Startthegame();//this is start JPanel
chooselevel panellevel= new chooselevel();//this is difficulties JPanel
thegameover gameover=new thegameover();//End of page
private int mouseclicks;//mouseclicks score
private int mouse;
public myshapestry() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.add(panel);
frame.add(panellevel);
frame.add(gameover);
frame.add(panelstart);
frame.add(statusbar, BorderLayout.SOUTH);
frame.setVisible(true);
frame.setSize(getPreferredSize());
frame.setTitle("Game of Shapes");
HandlerClass handler=new HandlerClass();
panel.addMouseListener(handler);
panel.addMouseMotionListener(handler);
Timer timer=new Timer(100,panel) ;
timer.start();
}
public Dimension getPreferredSize() {
return new Dimension(900,730);
}
private class HandlerClass implements MouseMotionListener, MouseListener {
public void mouseClicked(MouseEvent e){
mouseclicks++;
statusbar.setText(String.format("MouseLoc ( %d, %d ) \t \t Mouse Click \t", e.getX(), e.getY()) + mouseclicks);
mouseclicks=mouse;
}
@Override
public void mousePressed(MouseEvent event) {
if(event.getX() <= (ballX+90) && event.getX() >= (ballX) && event.getY() <= (ballY+90) && event.getY() >= (ballY))
c=Color.RED;
} }
public class MyPanel extends JPanel implements ActionListener {
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(c);
g.fillOval(ballX, ballY, 90 , 90);
}
public void actionPerformed(ActionEvent e) { //balls movement
ballX = ballX + ballXSpeed;
ballY = ballY + ballSpeed;
if(ballY>=730-185){
ballSpeed = -ballSpeed;
}
if(ballX>=900-180){
ballXSpeed = -ballXSpeed;
}
if(ballY<=0+60){
ballSpeed= -ballSpeed;
}
if (ballX<=0+60){
ballXSpeed= -ballXSpeed;
}
repaint();
if(c==Color.RED){
frame.remove(panel);
frame.add(gameover);
frame.validate();
}}}
public class chooselevel extends JPanel implements ActionListener {
private JButton easy;
private JButton normal;
private JButton hard;
public chooselevel(){
setLayout(null);
easy=new JButton("Easy");
normal=new JButton("Normal");
hard=new JButton("Hard");
easy.setBounds(380,330,90,20);
normal.setBounds(380,370,90,20);
hard.setBounds(380,410,90,20);
add(hard);
add(easy);
add(normal);
hard.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent l){
String level=l.getActionCommand();
if(level.equals("Hard")){
ballXSpeed=190;
ballSpeed=184;
frame.remove(panellevel);
frame.add(panel);
frame.validate();
}} });
normal.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent l){
String level=l.getActionCommand();
if(level.equals("Normal")){
ballXSpeed=157;
ballSpeed=123;
frame.remove(panellevel);
frame.add(panel);
frame.validate();
}}});
easy.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent l){
String level=l.getActionCommand();
if(level.equals("Easy")){
ballXSpeed=85;
ballSpeed=74;
frame.remove(panellevel);
frame.add(panel);
frame.validate();
}} });
}
public Dimension getPreferredSize() {
return new Dimension(900,730);
} }
public class Startthegame extends JPanel implements ActionListener {
private JButton Start;
private JButton Exit;
public Startthegame() {
setLayout(null);
Start = new JButton("Start");
Exit = new JButton("Exit");
Start.setBounds(380,330,70,20);
Exit.setBounds(380,370,70,20);
add(Start);
add(Exit);
Exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent i){
String action= i.getActionCommand();
if(action.equals("Exit")) {
System.exit(0);
}}
});
Start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent i){
String action= i.getActionCommand();
if(action.equals("Start")) {
frame.remove(panelstart);
frame.add(panellevel);
frame.validate();
repaint();
} }});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(900, 730);
} }
public class thegameover extends JPanel {
private JLabel gameisover;
private JLabel yourscore;
private JButton tryagain;
private JButton Exit;
thegameover(){
setLayout(null);
gameisover= new JLabel("GAME OVER");
yourscore=new JLabel();
add(gameisover);
add(yourscore);
gameisover.setBounds(170,200,600,70);
yourscore.setBounds(380,380,120,70);
gameisover.setFont(new Font(null, Font.PLAIN, 90));
yourscore.setFont(new Font(null, Font.PLAIN, 20));
yourscore.setText ("Your Score " + mouseclicks);
tryagain=new JButton("Try Again");
Exit=new JButton("Exit");
add(tryagain);
add(Exit);
tryagain.setBounds(280,550,100,20);
Exit.setBounds(490,550,100,20);
tryagain.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ac){
String tryit=ac.getActionCommand();
if(tryit.equals("Try Again")){
frame.remove(gameover);
frame.add(panelstart);
frame.validate();
repaint();
}
}
});
}
public Dimension getPreferredSize(){
return new Dimension(900,73);
}}
public static void main (String args[]){
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
myshapestry tr=new myshapestry();
}
});
} }
编辑后:
我创建了新的 Jpanel 来收集其中的所有 Jpanel,以便在 Frame 中添加状态栏,但我收到错误,出了点问题
public class myshapestry implements ActionListener {
collectionpanel collectpanel= new collectionpanel();
public myshapestry() {
frame.add(collectpanel);
public class collectionpanel extends JPanel {
collectionpanel(){
cardlayout= new CardLayout();
this.setLayout(cardlayout);
this.add(panel, "game");
this.add(panellevel,"level");
this.add(gameover, "over");
this.add(panelstart, "start");
cardlayout.show(collectpanel, "game");
cardlayout.show(collectpanel, "level");
cardlayout.show(collectpanel, "start");
cardlayout.show(collectpanel, "over");
} }
错误;
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: wrong parent for CardLayout
at java.awt.CardLayout.checkLayout(Unknown Source)
at java.awt.CardLayout.show(Unknown Source)
at example.myshapestry$collectionpanel.<init>(myshapestry.java:100)
at example.myshapestry.<init>(myshapestry.java:58)
at example.myshapestry.run(myshapestry.java:393)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access0(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
存在一连串的问题,所有问题共同作用导致混乱...
- 当游戏是 "over" 时,您永远不会停止
Timer
,这意味着当您尝试显示 "game over" 屏幕或尝试重新启动时,"game panel" 仍在尝试更新屏幕... - 您对屏幕的管理使情况更加复杂。您一开始就添加了所有屏幕,但稍后又 remove/add 它们,这只会造成混乱。
而是...
- 在使 "game screen" 可见之前,启动
Timer
。当您检测到游戏为"over"时,在显示"over"屏幕之前,停止Timer
- 改用
CardLayout
。有关详细信息,请参阅 How to Use CardLayout
例如...
创建一个 CardLayout
实例字段并将 Timer
也设为实例字段
public class MyShapes {//implements ActionListener {
//...
private CardLayout cardLayout;
private Timer timer = new Timer(100, panel);
将 CardLayout
应用于 frame
并命名每个视图...
public MyShapes() {
//...
cardLayout = new CardLayout();
frame.setLayout(cardLayout);
frame.add(panel, "game");
frame.add(panellevel, "level");
frame.add(gameover, "over");
frame.add(panelstart, "start");
frame.add(statusbar, BorderLayout.SOUTH);
cardLayout.show(frame.getContentPane(), "start");
//...
}
当用户选择 "start" 时,使用 CardLayout
Start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent i) {
String action = i.getActionCommand();
if (action.equals("Start")) {
//frame.remove(panelstart);
//frame.add(panellevel);
//frame.validate();
cardLayout.show(frame.getContentPane(), "level");
}
}
});
开始游戏时,启动Timer
并使用CardLayout
切换视图...
hard.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent l) {
String level = l.getActionCommand();
if (level.equals("Hard")) {
ballXSpeed = 190;
ballSpeed = 184;
//frame.remove(panellevel);
//frame.add(panel);
//frame.validate();
timer.start();
cardLayout.show(frame.getContentPane(), "game");
}
}
});
当您检测到 "game over" 条件时,停止 Timer
并使用 CardLayout
切换视图...
if (c == Color.RED) {
//frame.remove(panel);
//frame.add(gameover);
//frame.validate();
timer.stop();
cardLayout.show(frame.getContentPane(), "over");
}
现在,关于得分问题...
当您创建 thegameover
面板时,您使用 yourscore.setText("Your Score " + mouseclicks);
,但是当您创建视图时 mouseclicks
是 0
,您需要以某种方式更新此值。 ...
向 thegameover
添加方法 class,调用类似于 setScore
的方法并相应地更新标签...
public void setScore(int score) {
yourscore.setText("Your Score " + score);
}
当您检测到游戏结束时,更新比分...
timer.stop();
gameover.setScore(mouseclicks);
cardLayout.show(frame.getContentPane(), "over");
您可能希望通读 Code Conventions for the Java TM Programming Language,这将使人们更容易阅读您的代码,您也可以更轻松地阅读其他人
也是值得的