简体   繁体   中英

JApplet repaint() doesn't work

Problem: Main.repaint() doesn't work for me. repaint() doesnt invoke my paint method in Main. I've tried calling validate before repainting but with no succes. Main paints perfectly initially or when resized but when i call repaint() in my code nothing is happening.

Here is how the program looks so far link

So im trying to create a level selection screen for a game in java. My game is a JApplet. I have a structure as follows:

  1. my Main class which extends JApplet and contains an object of LevelScreen class

    LevelScreen has a paint method which Main invokes.

I tried to avoid using Swing since the layout managers gave me trouble with the design. So I've tried to make a structure which were simpler and more suited for my need.

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;
    }
}

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. my problem is that i cant invoke the paint(Graphics g) in main with repaint()

Here i call 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. You can fix it by changing getInstance as follows:

public Main getInstance() {
    return instance;
}

And add this line to the init method:

instance = this;

By the way, you should not override paint in a Swing component, which a JApplet is. You should override paintComponent instead, and call super.paintComponent(g) as the first line. 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.

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.

Without any more context of you code, you may not even need getInstance , instead reference the current instance using Main.this instead.

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. Instead, move your application to be based on something like a JPanel and override it's paintComponent method instead.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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