JApplet repaint() 不起作用



问题:Main.repaint() 对我不起作用。repaint() 不会在 Main 中调用我的 paint 方法。我尝试在重新绘制之前调用验证,但没有成功。Main paint最初或调整大小时完美无缺,但是当我在我的代码中调用 repaint() 时,什么都没有发生。

这是到目前为止程序的外观链接

所以我试图在java中为游戏创建一个关卡选择屏幕。我的游戏是JApplet。我有一个结构如下:

  1. 我的主类,它扩展了 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以保留油漆链并防止任何可能的问题。

最新更新