2015-03-03 3 views
0

Привет, я получаю случайное мерцание каждые две секунды при запуске моей программы, у него есть одно изображение, движущееся по экрану. Я использую метод Graphics paint() и repaint() в методе run() потока. Вот соответствующие части кода, я буду публиковать весь код, если это необходимо. Btw, пешки - это arraylist, загруженный предметами пешки, изначально у меня было 5 потоков для 5 изображений, перемещающихся, но я пробовал только с одним изображением, и он все еще мерцает, так что это не так.Java - мерцание при использовании repaint()

private BufferedImage helicopter; 

helicopter = ImageIO.read(new File("white.png")); 

public void paint(Graphics g) { 
     g.setColor(Color.WHITE); 
     g.fillRect(0, 0, this.getWidth(), this.getHeight()); 
     for(count=0; count<pawns.size(); count++){ 
     g.drawImage(helicopter, pawns.get(count).getX(), pawns.get(count).getY(), null); 
     } 
     g.setColor(Color.BLACK); 
     g.drawLine(350, 0, 350, 600); 
    } 

public void run() { 
     while(true) { 
      randSleep = (int)(Math.random()*100); 
      randMove = (int)(Math.random()*2); 
      pawn.setX(pawn.getX()+randMove); 
      try{ 
       Thread.sleep(40); 
      } 
      catch(Exception e) { 
       e.printStackTrace(); 
      } 

      repaint(); 

     } 
     } 
+2

Вы должны называть 'super.paint (g)' перед тем, как делать что-либо еще в методе 'paint'. Если ваш класс является подклассом 'JComponent', используйте его метод' paintComponent' вместо 'paint' и сделайте вызов' super.paintComponent (g) '. Кроме того, поскольку 'java.awt.Component' и его подклассы реализуют« ImageObserver », почему бы вам не заменить« null »ссылкой в ​​вызове' drawImage'? – TNT

+0

Возможно, вам понадобится двойная буферизация. –

+0

Я не могу использовать paintComponent, потому что я использую jFrame, я мог бы создать jpanel, а затем использовать paintcomponent, и я мог бы попробовать это позже. С другой стороны, я реализовал doublebuffering, но он не работает, мерцание все еще существует. – user2627736

ответ

1

компонентов со сложной продукции, перекрасить() должна вызываться с аргументами, которые определяют только прямоугольник, который нуждается в обновлении, а , чем не-Arg версии, которая заставляет весь компонент быть перекрасили. Реализация

Свинг краски() факторы вызов в 3 отдельных обратных вызовов: paintComponent() paintBorder() paintChildren() Расширения компонентов Swing, которые хотят реализовать свой собственный код краски должны поместить этот код в пределах метод paintComponent() (не внутри краски()).

source: Painting in AWT and Swing: Good Painting Code Is the Key to App Performance

Вы должны заметить в источнике цитируемого и связаны, что перекрасить() (без аргументов) не будут вызывать обновление(), который по умолчанию очищает фон перед нанесением. Я подозреваю, что это источник мерцания, когда компонент очищается перед вызовом paint().

Если вы используете компоненты Swing, вы не должны использовать собственную двойную буферизацию, а вместо этого используйте функциональность, предоставляемую Swing.

Сначала попробуйте перерисовать с аргументами, чтобы избежать обновления, очищающего весь фон. Или напишите переопределение для метода обновления. Если это не решит проблему, попробуйте поместить свой код чертежа в метод paintComponent компонента Swing.

Смежные вопросы