我正在制作一个简单的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) {
}
}
}
}
答案 0 :(得分:2)
基本上,你违反了Swing的单线程规则,ClikerGame
正在运行while-loop
,它阻止事件调度线程,阻止它处理新事件,包括绘制事件
从main
起作用的原因是,main
在美国东部时间内没有被调用,基本上,这是一个侥幸。但是,当您从new Clicker()
的{{1}}内拨打ActionListener
时,您正在EDT的上下文中运行,因此就是您的问题。
请查看Initial Threads和Concurrency in Swing了解详情。
"立即"解决方案可能看起来像使用JButton
,但这也违反了Swing的单一规则,因为Swing不是线程安全的,你永远不应该从EDT的上下文之外更新UI。
更好的解决方案可能是使用Swing Thread
来充当伪循环。这会定期通知EDT的背景
也许,就像......
Timer