简体   繁体   English

JApplet repaint()不起作用

[英]JApplet repaint() doesn't work

Problem: Main.repaint() doesn't work for me. 问题: Main.repaint()对我不起作用。 repaint() doesnt invoke my paint method in Main. repaint()不会在Main中调用我的paint方法。 I've tried calling validate before repainting but with no succes. 我曾尝试在重新绘制之前调用validate但没有成功。 Main paints perfectly initially or when resized but when i call repaint() in my code nothing is happening. 主要绘制完美或最初调整大小,但当我在我的代码中调用repaint()时,没有任何事情发生。

Here is how the program looks so far link 以下是该程序到目前为止的链接方式

So im trying to create a level selection screen for a game in java. 所以我试图在java中为游戏创建一个关卡选择屏幕。 My game is a JApplet. 我的游戏是JApplet。 I have a structure as follows: 我的结构如下:

  1. my Main class which extends JApplet and contains an object of LevelScreen class 我的Main类,它扩展了JApplet并包含一个LevelScreen类的对象

    LevelScreen has a paint method which Main invokes. LevelScreen有一个Main调用的paint方法。

I tried to avoid using Swing since the layout managers gave me trouble with the design. 我试图避免使用Swing,因为布局管理器给我带来了设计上的麻烦。 So I've tried to make a structure which were simpler and more suited for my need. 所以我试图制作一个更简单,更适合我需要的结构。

paint() in Main.java 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;
    }
}

In the code of my Buttons i try to repaint Main because i want to make a fade out animation when mouse leaves the button. 在我的按钮的代码中,我尝试重新绘制Main,因为我想在鼠标离开按钮时制作淡出动画。 my problem is that i cant invoke the paint(Graphics g) in main with repaint() 我的问题是我无法使用repaint()调用main中的paint(Graphics g)

Here i call repaint(): 在这里我称之为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();
}

This is a problem with the way that you implement the singleton design pattern. 这是实现单例设计模式的方法的问题。 The way you do it doesn't work for an applet, where the instance is created for you by the applet container. 您执行此操作的方式不适用于applet,applet容器会为您创建实例。 You can fix it by changing getInstance as follows: 您可以通过更改getInstance来修复它,如下所示:

public Main getInstance() {
    return instance;
}

And add this line to the init method: 并将此行添加到init方法:

instance = this;

By the way, you should not override paint in a Swing component, which a JApplet is. 顺便说一句,你不应该覆盖JApplet所在的Swing组件中的paint You should override paintComponent instead, and call super.paintComponent(g) as the first line. 您应该重写paintComponent ,并调用super.paintComponent(g)作为第一行。 This should fix the problem. 这应该可以解决问题。

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

I'm not surprised. 我不惊讶。 You're not the one creating the instance of the JApplet , the browser is. 您不是创建JApplet实例的人,浏览器是。

When you call this... 当你打电话给这个......

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

You are actually creating a second instance of the applet, which is NOT the one that is on the screen, so when you call repaint , Swing goes, "no point, you're not even displayable" and does nothing. 你实际上是在创建applet的第二个实例,它不是屏幕上的那个,所以当你调用repaint ,Swing会说,“没有意义,你甚至不能显示”并且什么都不做。

Without any more context of you code, you may not even need getInstance , instead reference the current instance using Main.this instead. 在没有任何代码上下文的情况下,您甚至可能不需要getInstance ,而是使用Main.this来引用当前实例。

You should also consider taking a look at Performing Custom Painting . 您还应该考虑一下“ 执行自定义绘画”

Top level containers like JAppelt are not double buffered, which involves more work to paint directly to them. JAppelt这样的顶级容器不是双缓冲的,它需要更多的工作来直接绘制它们。 Instead, move your application to be based on something like a JPanel and override it's paintComponent method instead. 相反,将您的应用程序移动到基于类似JPanel东西并改写它的paintComponent方法。

Painting is also a complex, multi-layered scheme. 绘画也是一个复杂的多层计划。 You MUST call super.paintXxx in order to preserve the paint chain and prevent any possible issues. 您必须调用super.paintXxx以保留油漆链并防止任何可能的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM