0

问题: Main.repaint() 对我不起作用。repaint() 不会在 Main 中调用我的绘制方法。我尝试在重绘之前调用 validate 但没有成功。Main 最初或在调整大小时完美绘制,但是当我在代码中调用 repaint() 时没有发生任何事情。

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

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

  1. 我的 Main 类扩展了 JApplet 并包含 LevelScreen 类的对象

    LevelScreen 有一个 Main 调用的绘制方法。

我试图避免使用 Swing,因为布局管理器给我的设计带来了麻烦。所以我试图制作一个更简单、更适合我需要的结构。

Main.java 中的paint()

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(Graphics g)

这里我调用 repaint():

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();
}
4

2 回答 2

1

这是您实现单例设计模式的方式的问题。您执行此操作的方式不适用于 applet,其中的实例是由 applet 容器为您创建的。getInstance您可以通过如下更改来修复它:

public Main getInstance() {
    return instance;
}

并将这一行添加到init方法中:

instance = this;

顺便说一句,您不应该paint在 Swing 组件中覆盖,它JApplet是。您应该改写paintComponent,并super.paintComponent(g)作为第一行调用。这应该可以解决问题。

于 2013-10-20T22:36:47.680 回答
1
Main.getInstance().repaint();  //this doesnt work!!

我不惊讶。您不是创建实例的人JApplet,浏览器是。

当你调用这个...

public static Main getInstance() {
    if (instance == null)
        instance = new Main();
    return instance;
}

您实际上是在创建小程序的第二个实例,它不是屏幕上的那个,所以当您调用 时repaint,Swing 会出现“没意义,您甚至无法显示”并且什么都不做。

如果没有更多代码上下文,您甚至可能不需要getInstance,而是使用引用当前实例Main.this

您还应该考虑查看Performing Custom Painting

像这样的顶级容器JAppelt不是双缓冲的,这需要更多的工作来直接绘制它们。相反,将您的应用程序移动到基于 a 之类的东西JPanel并覆盖它的paintComponent方法。

绘画也是一个复杂的、多层次的方案。您必须致电super.paintXxx以保护油漆链并防止任何可能的问题。

于 2013-10-20T22:40:58.810 回答