Search code examples
javarepaintjapplet

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

Solution

  • 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.