创建游戏启动器时出错

时间:2015-06-19 03:06:29

标签: java swing

我正在制作一个简单的Java游戏并试图在游戏开始时实现一个启动器。

例如,一个JFrame,其中有一个按钮,可以在按下时启动我的应用程序。

我要做的是让main方法调用一个单独的类来打开JFrame,并为调用ActionListener的{​​{1}}调用JButton它被称为。

但是,如果在new Cliker();方法之外调用new Cliker();,则会打开游戏main,而不是JFrame

为什么会发生此错误,我该如何解决?我对编程比较陌生,所以我提前为这个问题或我的程序提出任何不明确的观点而道歉。

非常感谢你的帮助。如果您需要更多课程来帮助回答我的问题,请询问,或者如果您有任何其他问题,请随时告诉我。

JPanel

下一课

package com.Cliker;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import com.Cliker.Accessories.Music;

public class Cliker extends JFrame {

private static final long serialVersionUID = 1L;

int score = 0;

JButton ball = new JButton(new ImageIcon("res/textures/ball/ball.PNG"));
JFrame gameFrame = new JFrame("Cliker v1.0");

public static void main(String[] args){
    new Cliker();
}


public Cliker() {

    gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    gameFrame.add(new MyPanel());
    gameFrame.pack();
    gameFrame.setVisible(true);
    gameFrame.setResizable(false);
    gameFrame.setLocationRelativeTo(null);

    ClikerGame play = new ClikerGame();
    play.run(this);

}

class MyPanel extends JPanel implements MouseListener {

    private static final long serialVersionUID = 1L;

    public MyPanel() {

        setBackground(Color.CYAN);

        ball.addMouseListener(new MouseListener() {

            @Override
            public void mousePressed(MouseEvent e) {
                if (e.getSource() == ball) {
                    score++;
                    Music.music(4);
                    repaint();

                }

            }

            @Override
            public void mouseClicked(MouseEvent e) {

            }

            @Override
            public void mouseEntered(MouseEvent e) {

            }

            @Override
            public void mouseExited(MouseEvent e) {

            }

            @Override
            public void mouseReleased(MouseEvent e) {

            }
        });
        ball.setBorder(null);

        add(ball);
        addMouseListener(this);

    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setFont(new Font("Fixedsys", Font.BOLD, 30));
        g.setColor(Color.BLACK);
        g.drawString(String.valueOf(score), getWidth() / 2, 40);

    }

    public Dimension getPreferredSize() {
        return new Dimension(700, 500);
    }

    @Override
    public void mousePressed(MouseEvent e) {
        if (e.getSource() == this) {

            this.setBackground(Color.RED);

            gameFrame.setVisible(false);

            ClikerEndGame sendData = new ClikerEndGame();

            try {

                sendData.finish(score);

            } catch (Exception e1) {
                JOptionPane.showInputDialog(null,"The game has encountered an error. Error code: 001");
                e1.printStackTrace();
            }




        }

    }

    @Override
    public void mouseClicked(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    @Override
    public void mouseReleased(MouseEvent arg0) {

    }
}

}

}

1 个答案:

答案 0 :(得分:2)

基本上,你违反了Swing的单线程规则,ClikerGame正在运行while-loop,它阻止事件调度线程,阻止它处理新事件,包括绘制事件

main起作用的原因是,main在美国东部时间内没有被调用,基本上,这是一个侥幸。但是,当您从new Clicker()的{​​{1}}内拨打ActionListener时,您正在EDT的上下文中运行,因此就是您的问题。

请查看Initial ThreadsConcurrency in Swing了解详情。

"立即"解决方案可能看起来像使用JButton,但这也违反了Swing的单一规则,因为Swing不是线程安全的,你永远不应该从EDT的上下文之外更新UI。

更好的解决方案可能是使用Swing Thread来充当伪循环。这会定期通知EDT的背景

也许,就像......

Timer