JApplet repaint()不起作用

时间:2013-10-20 22:33:30

标签: java repaint japplet

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

以下是该计划到目前为止的展望方式link

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

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

    LevelScreen有一个Main调用的paint方法。

  2. 我试图避免使用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();
    }
    

2 个答案:

答案 0 :(得分:1)

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

public Main getInstance() {
    return instance;
}

并将此行添加到init方法:

instance = this;

顺便说一句,你不应该覆盖paint所在的Swing组件中的JApplet。您应该覆盖paintComponent,并将super.paintComponent(g)作为第一行。这应该可以解决问题。

答案 1 :(得分:1)

Main.getInstance().repaint();  //this doesnt work!!

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

当你打电话给这个......

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

你实际上正在创建applet的第二个实例,它不是屏幕上的实例,所以当你调用repaint时,Swing会说,“没有意义,你甚至不能显示”,什么都不做。

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

您还应该考虑查看Performing Custom Painting

JAppelt这样的顶级容器不是双缓冲的,这需要更多的工作来直接绘制它们。相反,请将您的应用程序移至JPanel之类的内容,并改为覆盖paintComponent方法。

绘画也是一种复杂的多层方案。您必须调用super.paintXxx以保留油漆链并防止出现任何可能的问题。