因此,我已经对这个小UI进行了一段时间的编码,由于某种原因,repaint()方法似乎导致屏幕上生成的图像闪烁和闪烁。有办法防止这种情况吗?

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.Timer;

public class userInterfaceSimple extends JFrame implements ActionListener
{
    static ArrayList<Creature> list = new ArrayList<Creature>();
    static JButton next = new JButton("Begin");
    static Timer timer = new Timer();
    static JFrame frame = new JFrame();
    final static JPanel pane = new JPanel();

    public static void main(String[] args)
    {
        new userInterfaceSimple();
    }

    public userInterfaceSimple()
    {
        super("Toy Planet: Life, a Simulation");

        setSize(1000,1000);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        setLayout(new BorderLayout());
        add(pane, BorderLayout.CENTER);

        next.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                 if(next.getText().equals("Begin"))
                 {
                    next.setText("Stop");
                    timer.scheduleAtFixedRate(new TimerTask()
                    {
                        @Override
                        public void run()
                        {
                            checkRules();
                            repaint();
                        }
                    }, 250, 250);
                 }
                 else
                 {
                    next.setText("Begin");
                    timer.cancel();
                    timer = new Timer();
                 }
            }
        });

        add(next, BorderLayout.SOUTH);

        for(int j = 0; j < 3; j ++)
        {
            Creature orgArc = new Creature();
            for(int i = 0; i < 20; i++)
            {
                 list.add(new Creature(orgArc.gene));
            }
        }
        sortList();
    }

    public void paint(Graphics g)
    {
        super.paint(g);
        for(int i = 0; i < list.size(); i++)
        {
            g.setColor(list.get(i).getColor());
            int size = list.get(i).getSize();
            g.fillOval(list.get(i).getX() - size/2, list.get(i).getY() - size/2,size,size);
        }

    }

    public static void checkRules()
    {
        int size = list.size();

        for(int i = 0; i < size; i++)
        {
            try
            {
                for(int j = 0; j < size; j++)
                {
                    boolean alreadyMoved = false;
                    if(!(list.get(i)).equals(list.get(j)))
                    {

                        int x = list.get(j).getX() - (list.get(i)).getX();
                        int y = list.get(j).getY() - (list.get(i)).getY();
                        double z = Math.sqrt(x*x + y*y);

                        //Passive Interaction Rules
                        //Sight Check
                        if(list.get(j).getSense() > z)
                        {
                            list.get(j).moveTo(list.get(i));
                            alreadyMoved = true;
                        }

                        if(z <= 1.5)
                        {
                            //Active Interaction Rules
                            //Breeding Check
                            if(list.get(j).isCompatible(list.get(i)))
                            {
                                list.add(list.get(j).breed(list.get(i)));
                                sortList();
                            }
                            //Eating Check
                            else if(list.get(j).getAggro() > 15 || list.get(j).getDiet() > 3)
                            {
                                list.get(j).eat(list.get(i));
                            }
                        }
                    }
                    //If no checks fire then move randomly
                    if(alreadyMoved == false)
                    {
                        Organism temp = new Organism();
                        list.get(j).moveTo(temp);
                    }
                }
                //Hunger Check
                list.get(i).hungerCheck();
            }
            catch(Exception e)
            {

            }

            list.get(i).validate();
            size = size - validateList();
        }
        /*for(int i = 0; i < list.size(); i ++) //for debugging.
        {
            System.out.println(list.get(i).getInfo());
        }
        System.out.println("----");*/
    }

    public static int getClosestCreature(Organism org)
    {
        int x,y;
        double z;
        double tempZ = 100000;
        int closest = 0;
        for(int i = 0; i < list.size(); i++)
        {
            if(!(list.get(i)).equals(org))
            {
                x = org.getX() - (list.get(i)).getX();
                y = org.getY() - (list.get(i)).getY();
                z = Math.sqrt(x*x + y*y);
                if(z < tempZ)
                {
                    closest = i;
                    tempZ = z;
                }
            }
        }
        return (closest);
    }

    public static int validateList()
    {
        int netLoss = 0;
        for(int i = 0; i < list.size(); i++)
        {
            if((list.get(i)).getAlive() == false)
            {
                list.remove(i);
                netLoss = netLoss + 1;
            }
        }
        return netLoss;
    }

    public static void sortList()
    {
        Creature temp;
        for(int i = 0; i < list.size(); i ++)
        {
            for(int j = 1; j < list.size() - i; j++)
            {
                if(list.get(j - 1).getSpeed() > list.get(j).getSpeed())
                {
                    temp = list.get(j - 1);
                    list.set(j - 1, list.get(j));
                    list.set(j, temp);
                }
            }
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub

    }
}


感谢您的帮助!

最佳答案

是的,这很简单:Double Buffering应该修复它。有关更多参考,请访问http://docs.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html

首先,您应该创建private BufferedImage bufferImage;
在您的public void paint(Graphics g)中,您应该将内容绘制到此bufferImage中,然后,在填充bufferImage时,将其绘制为g.drawImage(bufferImage, 0, 0, null);

public void paint(Graphics g) {
   Graphics2D gr = bufferImage.createGraphics();
   for(int i = 0; i < list.size(); i++)
       {
           gr.setColor(list.get(i).getColor());
           int size = list.get(i).getSize();
           gr.fillOval(list.get(i).getX() - size/2, list.get(i).getY() - size/2,size,size);
       }
    super(g);
    g.drawImage(bufferImage, 0, 0, null);
}


未编译,但类似的东西应该起作用。

08-17 02:00