Need help with Flickering Images

hi,

I’m writing an application that needs to display images and I’m having some problems with my images flickering. The application is a kind of e-learning tool and will have questions and answers (both represented by images). The user will be required to drag the appropriate answer image to the corresponding question.

The questions and answers are stored in 2 seperate array Lists. I have a method which runs through the arrayLists and draws each question/answer. I also have a clear screen method which just paints a background coloured rectangle over the Canvas to clear the screen. This method is called only when and image is being moved and is determined by a boolean called screenRefresh.

The 2 paint methods are called from within a thread and for some reason, when the paintQuestions and clearScreen methods are called there is some flickering in the images and I just can’t seem to fix it.

Here’s my code. Maybe someone will be able to help

package pictureMatch;



import ImageHandler.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics2D;
import java.awt.geom.*;
import java.util.ArrayList;
import java.awt.image.BufferStrategy;
import java.util.Random;
import java.net.*;

public class PictureMatch extends Canvas implements MouseListener, MouseMotionListener{
    
    
    private BufferStrategy buffer;
    private int frameWidth, frameHeight;
    private int lastx, lasty, currentx, currenty;    
    private ArrayList<Question> questionList = new ArrayList();    
    private ArrayList<Question> answerList = new ArrayList();
    private ArrayList<Question> selectedQuestionList = new ArrayList();    
    private ArrayList<Question> selectedAnswerList = new ArrayList();
    private JPanel panel;
    private ImageHandler imageHandler;
    private String[] images = new String[20];
    private UpdateThread thread;
    private boolean screenRefresh = true;
    
    
    /** Creates a new instance of PictureMatch */
    public PictureMatch() 
    {
        super(); 
        
        this.frameWidth = this.getWidth();
        this.frameHeight = this.getHeight();
        
        initialise();      
               
        addMouseListener(this);
        addMouseMotionListener(this);
        setFocusable(true);        
        
        this.createBufferStrategy(2);
        buffer = getBufferStrategy();  
        
        thread = new UpdateThread();  
        
    }
    
    public void initialise()
    {
        imageHandler = new ImageHandler(this);   
        loadImages();        
        
        createQuestions();
        createAnswers();  
        selectQuestions();
        
        
        JFrame window = new JFrame("Differentiation Test");
        panel = (JPanel)window.getContentPane();
        setBounds(0, 0, 850, 550);
        panel.setLayout(new BorderLayout());
       
        
        panel.add(this);
        window.setBounds(0, 0, 850, 550);
        window.setVisible(true);  
        window.setResizable(false);
        
        window.addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });
    }
    
    
    public void loadImages()
    {
        
        images[0]="diffPics/q0.png";
        images[1]="diffPics/q1.png";
        images[2]="diffPics/q2.png";
        images[3]="diffPics/q3.png";
        images[4]="diffPics/q4.png";
        images[5]="diffPics/q5.png";
        images[6]="diffPics/q6.png";
        images[7]="diffPics/q7.png";
        images[8]="diffPics/q8.png";
        images[9]="diffPics/q9.png";
        images[10]="diffPics/a0.png";
        images[11]="diffPics/a1.png";
        images[12]="diffPics/a2.png";
        images[13]="diffPics/a3.png";
        images[14]="diffPics/a4.png";
        images[15]="diffPics/a5.png";
        images[16]="diffPics/a6.png";
        images[17]="diffPics/a7.png";
        images[18]="diffPics/a8.png";
        images[19]="diffPics/a9.png";
                   
        imageHandler.images(images);
        
    }
    
    //--------------------create questions------------------
    
    public void createQuestions()
    {                
        for(int i = 0; i<(int)images.length/2; i++)
        {
            Question question = new Question(imageHandler.getImages(i),0,0,false,0);
            questionList.add(question);
        }
    }
    
    public void createAnswers()
    {        
        for(int i = (int)images.length/2; i<images.length; i++)
        {
            Question answer = new Question(imageHandler.getImages(i),0,0,true,0);
            answerList.add(answer);
        }
    }
    
    public void selectQuestions()
    {
        Random random = new Random();
        
        for(int i=0;i<5;i++)
        {
            int ran = random.nextInt(questionList.size());
            
            //select random question from array list
            Question selectedQuestion = questionList.get(ran);
            selectedQuestion.setY(85*i+100);
            selectedQuestionList.add(selectedQuestion);
            questionList.remove(ran);
            
            Question selectedAnswer = answerList.get(ran);
            selectedAnswer.setX(600);
            selectedAnswer.setY(400 - 75*i);
            selectedAnswerList.add(selectedAnswer);
            answerList.remove(ran);             
        }
        
        
    }
    
    
    //--------------------paint methods-----------------------
    
    public void clearScreen()
    {        
        Graphics2D g = (Graphics2D)buffer.getDrawGraphics();
        try {    
                Rectangle2D clear = new Rectangle2D.Double(0,0,this.getWidth(), this.getHeight());
                g.setColor(this.getBackground());
                g.fill(clear);
            
            } 
        finally 
        {
            g.dispose();
        }
        buffer.show();        
    }
    
    
    public void paintQuestions()
    {
        Graphics2D g = (Graphics2D)buffer.getDrawGraphics();
        
        try{
            for(int i = 0; i<selectedQuestionList.size(); i++)
            {
                selectedQuestionList.get(i).draw(g);
            
            }
        
            for(int i = 0; i<selectedAnswerList.size(); i++)
            {
                selectedAnswerList.get(i).draw(g);      
                System.out.println(selectedAnswerList.get(i).getHeight());
            }
        }
        finally
        {
            g.dispose();
            
        }
        
        buffer.show();
    }
    
        
    //-----------------------Mouse Listener and motion Methods------------
    
    public void mouseExited(MouseEvent e){}
    public void mouseEntered(MouseEvent e){}
    public void mouseClicked(MouseEvent e){}    
    public void mousePressed(MouseEvent e) {}     
    public void mouseReleased(MouseEvent e){screenRefresh = false;}  
    
    public void mouseMoved(MouseEvent e){}
    public void mouseDragged(MouseEvent e)
    {
        int xPos = e.getX();
        int yPos = e.getY();
        
        for(int i = 0; i<answerList.size(); i++)
        {                        
            if(selectedAnswerList.get(i).bounds().contains(xPos, yPos)
               && selectedAnswerList.get(i).isMoveable())
            {                
                selectedAnswerList.get(i).setX(xPos - 0.5*selectedAnswerList.get(i).getWidth());
                selectedAnswerList.get(i).setY(yPos - 0.5*selectedAnswerList.get(i).getHeight());                
            }
        }      
        screenRefresh = true;
    }

    
    
    //-------------------thread----------------------------------
    
    class UpdateThread extends Thread
    {
        
        public void run()
        {
            while(true)
            {   
                if(screenRefresh)
                {
                    clearScreen();
                    paintQuestions();
                }            
                
                try
                {
                    sleep(50);
                }
                catch(InterruptedException e){}
            }
            
            
        }
    }
    
     public void run()
    {
        PictureMatch pm = new PictureMatch();
        pm.thread.start();
    }
    
    public static void main(String[] args)
    {
        PictureMatch pm = new PictureMatch();
        //pm.run();
        pm.thread.start();
    }
        
}

Thanks

I’ve only had a quick look at the code, but your problem could well be the call to buffer.show() in clearScreen().

The way it looks to me, when screenRefresh is true, you’re clearing the back buffer, then displaying it, then drawing your images to the new back buffer, and displaying it again. So the cleared canvas is briefly visible on each refresh, hence flicker.

It may be better to move the buffer.show() call into run() immediately after clearScreen() and paintQuestions() (removing it from both of those). In other words, call whichever functions you need to draw to the back buffer, then at the end of that display the back buffer.

Fingers crossed that’s some help,
Simon