Search code examples
javaappletjapplet

How to stop moving image in a JApplet from flickering


I managed to create a (basic) animated JApplet for the first time in 3 years, but I am annoyed with the image flickering when it moves. The Timer object is what is making the image move, and my private inner class "TimerListener" is responsible for the animated motion of the moving image.

Here is the code of my TimerListener class, where I think this problem may be able to be solved:

@Override
    public void paint(Graphics g) {
        super.paint(g);
        g.drawImage(smileyFace.getImage(), xCoord, yCoord, this);
    }

    private class TimerListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {

            //Following if-else manipulates Y coordinate
            if (goingUp) {
                if (yCoord > minY) {
                    yCoord -= move;
                } 
                else {
                    goingUp = false;
                }
            } else {
                if (yCoord < (getContentPane().getHeight() - (smileyFace.getIconHeight()+ Y_OFFSET))) {
                    yCoord += move;
                } 
                else {
                    goingUp = true;
                }
            }

            //Following if-else manipulates X coordinate
            if (goingSideways) {
                if (xCoord > 0) {
                    xCoord -= move;
                } 
                else {
                    goingSideways = false;
                }
            } else {
                if (xCoord < (getContentPane().getWidth() - (smileyFace.getIconWidth() + X_OFFSET))) {
                    xCoord += move;
                } 
                else {
                    goingSideways = true;
                }
            }

            repaint();
        }
    }

If it helps, here is a screenshot of my JApplet - in this case, the troll face should be moving in the black area, and bouncing off the sides as it hits them:

enter image description here

For those of you who want to run and test the JApplet, you can get the Netbeans project from https://github.com/rattfieldnz/Java_Projects/tree/master/JAppletAnimation.


Solution

  • Thanks to the user 'arynaq', I have fixed my problem. I put the following paint method:

    @Override
        public void paint(Graphics g) {
            super.paint(g);
            g.drawImage(smileyFace.getImage(), xCoord, yCoord, this);
        }
    

    ...into an inner class which extends JPanel (notice how I changed 'paint' to 'paintComponent'):

    class ImagePanel extends JPanel
        {
    
            public ImagePanel()
            {
                setBackground(Color.BLACK);
            }
    
            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(smileyFace.getImage(), xCoord, yCoord, this);
            }
    
            @Override
            public void setBackground(Color bg) {
                super.setBackground(bg); //To change body of generated methods, choose Tools | Templates.
            }
    
    
        }
    

    ... then added it to my JApplet via it's init() method (I'm not sure if I'd be correct by calling this the JApplet's constructor...):

    @Override
    public void init() {
    
        smileyFace = new ImageIcon("images/happyFace.png");
        **add(new ImagePanel());**
        timerDelay = 10;
        timer = new Timer(timerDelay, new TimerListener());
        timer.start();
    
        //getContentPane().setBounds(0, 0, CONTENTPANE_WIDTH, CONTENTPANE_HEIGHT);
        getContentPane().setBackground(Color.BLACK);
    
        //maxY = getContentPane().getHeight();
        minY = 0;
    
        xCoord = 0;
        yCoord = 0;
        move = 2;
    
    }
    

    You can see it running by cloning my GitHub JApplet project and running it in NetBeans :).