2015-01-31 3 views
0

У меня есть Java-программа, которая должна делать что-то очень простое. Он содержит JPanel, на котором repaint() вызывается 30 раз в секунду. Этот JPanel переопределяет метод paintComponent(), и в этом перезаписанном методе я беру BufferedImage и рисую его в JPanel.Графика JPanel мерцает на левой стороне

Этот BufferedImage состоит из черного изображения с несколько меньшим синим прямоугольником внутри него. Это отображает, но проблема в том, что левая сторона, 50-80 пикселей или около того, мерцает на экране. В самой левой части того, что должно быть синим прямоугольником, некоторые пиксели иногда будут казаться черными вместо этого, как будто есть черный оверлей, простирающийся от левой стороны экрана, покрывающего его, что немного мерцает каждый кадр.

Я бы не подумал, что просто рисование прямоугольника будет настолько поглощающим, что это вызовет графические ошибки с чем-то подобным; это? Я не могу понять, почему это будет происходить, поэтому у любого из вас есть идея, что может вызвать черное «мерцание» слева от BufferedImage или Graphics2D?

«Runnable пример (пожалуйста, добавьте импорт)»:

public class Panel extends JPanel{ 
public int width, height; 
public long lastTime; 
public BufferedImage canvas; 
public Panel(int a, int b){ 
width = a; 
height = b; 
canvas = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
lastTime = System.currentTimeMillis(); 
} 
public void paintComponent(Graphics g){ 
super.paintComponent(g); 
Graphics2D g2 = (Graphics2D) g; 
g.drawImage(canvas, 0, 0, this); 
} 
public void drawRect(int startX, int startY, int w, int h, int color){ 
for(int i=0; i<w; i++){ 
for(int j=0; j<h; j++){ 
canvas.setRGB(i + startX, j + startY, color); 
} 
} 
} 
public void render(){ 
drawRect(0, 0, width, height, 0x000000); 
drawRect(10, 10, width - 20, height - 20, 0x0000ff); 
} 
public void update(){ 
int delta = (int)(System.currentTimeMillis() - lastTime); 
if(delta >= 1000/30){ 
render(); 
lastTime = System.currentTimeMillis(); 
} 
} 

//in a different class, contains main() 

public class Main{ 
public static Panel pan; 
public static void main(String[] args){ 
JFrame frame = new JFrame(); 
Container c = frame.getContentPane(); 
c.setPreferredSize(500, 500); 
pan = new Panel(500, 500); 
frame.add(pan); 
frame.pack(); 
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
frame.setVisible(true); 
new runThread().run(); 
} 
class runThread extends Thread{ 
public void run(){ 
while(true){ 
pan.update(); 
} 

} 
} 
} 
+3

Если это была моя проблема, и я искал помощь здесь, я бы потратил немного времени на создание и публикацию [минимальной примерной программы] (http://stackoverflow.com/help/mcve), поскольку я знал бы что это будет лучшим и быстрым способом заставить людей полностью понять мою проблему, а затем помочь мне. Пожалуйста, рассмотрите это; вы не пожалеете, поверьте мне! –

+0

Один из способов получить образы для примера - это горячая ссылка на изображения, которые можно увидеть в [этом Q & A] (http://stackoverflow.com/q/19209650/418556). –

+1

'Графика # drawImage' должна использовать' this' как 'ImageObserver' – MadProgrammer

ответ

2

Поскольку ваша программа неправильно синхронизировано несколькими способами, результат неопределен. Качели GUI-объекты должны быть сконструированы и обработаны только на event dispatch thread; это требуется на всех поддерживаемых платформах. Как обсуждалось в How to Use Swing Timers, этот example работает при 50 Гц без мерцания.

У меня есть программа 15 класса ...

В больших программах, вы можете искать нарушения EDT, используя один из подходов привел here. Также рассмотрите предложенные методы анимации here.

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