我正在尝试开发一个我需要绘制网格的游戏。为此,我使用的是由paintComponent(Graphics g)
方法调用的repaint()
方法。
问题是重绘方法在无限的While循环内部,除非我最小化并最大化屏幕,否则它永远不会调用paintComponent()
方法。之后它工作正常并在while循环中完美地调用paintComponent()
。
简而言之,我需要通过最小化 - 最大化屏幕来触发它。
有人可以帮帮我吗?
在代码中你可以看到3个类,即Frame.java,MenuHandler.java& Screen.java。代码从Frame类中的main方法开始,并在Screen扩展JPanel时将Screen类添加到自身。但是,仅当用户在菜单上选择“创建地图”时,控件才会进入Screen类。然后MenuHandler类将控件传递给Screen类,其中在createMap方法中调用run方法,并在此run方法中调用repaint方法。 包所以;
public class Screen extends JPanel implements Runnable {
Frame frame;
public Screen(Frame frame) {
this.frame = frame;
}
public void createMap() {
thread.start();
}
public void paintComponent(Graphics g) {
g.setColor(Color.BLUE);
}
@Override
public void run() {
System.out.println("Success******");
long lastFrame = System.currentTimeMillis();
int frames = 0;
running = true;
scene = 0;
// the map grid would be refreshed every 2 ms so that we don't get the
// flickering effect
while (running) {
frames++;
if (System.currentTimeMillis() - 1000 >= lastFrame) {
fps = frames;
frames = 0;
lastFrame = System.currentTimeMillis();
}
// to draw stuff all the time on the screen : goes around 2 millions
// frames per second. Which is of no use.
repaint();
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.exit(0);
}
}
run方法中的计时器代码:
public void run() {
System.out.println("Success");
long lastFrame = System.currentTimeMillis();
int frames = 0;
running = true;
scene = 0;
// the map grid would be refreshed every 2 ms so that we don't get the
// flickering effect
while (running) {
frames++;
if (System.currentTimeMillis() - 1000 >= lastFrame) {
fps = frames;
frames = 0;
lastFrame = System.currentTimeMillis();
}
System.out.println("before repaint");
// to draw stuff all the time on the screen : goes around 2 millions
// frames per second. Which is of no use.
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
repaint();
}
};
new Timer(200, taskPerformer).start();
System.out.println("after repaint");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.exit(0);
}
答案 0 :(得分:2)
我想出了这个问题。我只需要添加一行来触发paintComponent方法,而不是通过最小化窗口来实现它。
Frame是我的顶级容器,我正在向框架中添加Screen组件(将JPanel扩展并具有paintComponent的实现)。所以在添加时,我早些时候正在做
frame.add(screen);
我将其更改为:
frame.getContentPane().add(screen);
frame.getContentPane().validate();
添加后调用validate方法为我做了。我不知道它是否有意义,但是这是唯一对我有用的线。
希望它有所帮助。