问题:Main.repaint() 对我不起作用。repaint() 不会在 Main 中调用我的 paint 方法。我尝试在重新绘制之前调用验证,但没有成功。Main paint最初或调整大小时完美无缺,但是当我在我的代码中调用 repaint() 时,什么都没有发生。
这是到目前为止程序的外观链接
所以我试图在java中为游戏创建一个关卡选择屏幕。我的游戏是JApplet。我有一个结构如下:
-
我的主类,它扩展了 JApplet 并包含一个对象水平屏幕类
LevelScreen 有一个 Main 调用的绘制方法。
我尽量避免使用Swing,因为布局管理器在设计上给我带来了麻烦。所以我试图制作一个更简单、更适合我需求的结构。
paint() in Main.java
public class Main extends JApplet {
public static final int WIDTH = 700, HEIGHT = 500;
private static Main instance;
private LevelScreen levelScreen = new LevelScreen();
private View view = View.LEVELSCREEN;
public static Main getInstance() {
if (instance == null)
instance = new Main();
return instance;
}
@Override
public void init() {
setSize(WIDTH, HEIGHT);
addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
Point p = e.getPoint();
if (view == View.LEVELSCREEN) {
levelScreen.mouseMoved(p);
}
}
});
}
@Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if (view == View.LEVELSCREEN)
levelScreen.paint(g2);
}
public enum View {
GAME, LEVELSCREEN;
}
}
在我的按钮代码中,我尝试重新绘制 Main,因为我想在鼠标离开按钮时制作淡出动画。 我的问题是我无法使用 repaint() 在 main 中调用 paint(图形 g)
这里我调用重绘():
public void mouseExited() {
//start new thread to make fade out animation when mouse leave
mouseOver = false;
TimerTask task = new TimerTask() {
@Override
public void run() {
while (!mouseOver && opacity > 0.6) {
opacity -= 0.02;
//set level to 999 so i can see if the game repaints()
level = 999;
Main.getInstance().repaint(); //this doesnt work!!
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
new Thread(task).start();
}
这是实现单一实例设计模式的方式存在的问题。执行此操作的方式不适用于小程序,其中实例由小程序容器为您创建。您可以通过更改getInstance
来修复它,如下所示:
public Main getInstance() {
return instance;
}
并将此行添加到init
方法中:
instance = this;
顺便说一下,您不应该覆盖 Swing 组件中的paint
,而 JApplet
就是。您应该改用paintComponent
,并将super.paintComponent(g)
作为第一行调用。这应该可以解决问题。
Main.getInstance().repaint(); //this doesnt work!!
我并不感到惊讶。 您不是创建JApplet
实例的人,浏览器是。
当你称之为...
public static Main getInstance() {
if (instance == null)
instance = new Main();
return instance;
}
您实际上是在创建小程序的第二个实例,该实例不是屏幕上的小程序,因此当您调用repaint
时,Swing 会说,"没有意义,您甚至无法显示"并且什么也不做。
如果没有更多的代码上下文,您甚至可能不需要getInstance
,而是使用 Main.this
引用当前实例。
您还应该考虑查看执行自定义绘画。
像JAppelt
这样的顶级容器不是双缓冲的,这需要更多的工作来直接绘制它们。 相反,请将应用程序移动到基于类似JPanel
的内容,并改为重写其paintComponent
方法。
绘画也是一个复杂的、多层次的方案。 您必须致电super.paintXxx
以保留油漆链并防止任何可能的问题。