给员工一个被动的重新喷漆引擎。也就是说,它只会在需要时更新
RepaintManager
还进行了优化,以将多个重新绘制合并为其认为需要的尽可能少的重新绘制事件。
这意味着您可以请求
repaint
,但无法保证何时或是否会重新喷漆。
这样做主要是为了优化性能。
退房
Painting in AWT and Swing
了解更多详细信息。
因为它是自然的,
重新喷漆
是线程安全的。
重新喷漆
询问
重新喷漆管理器
将绘制事件发布到事件队列中。此队列由事件调度线程处理,这意味着您不必同步
重新喷漆
使用EDT。
下面的例子说明了这一观点。它提供了一个简单的滑块,可以重置绘制计数器并设置之间的延迟
重新喷漆
请求。
线程延迟0毫秒。。。
线程延迟2秒
正如你所看到的。在0毫秒时(这实际上是你在循环中所做的),实际绘制的数量与重新绘制请求的数量不匹配,但在延迟2秒时,实际绘制和绘制请求几乎相等(我认为额外的一个来自滑块进行的重新绘制)。
事实上,在我的测试中,在大约100毫秒的时间里,我能够使它大致相等。我甚至尝试了5毫秒,并使其达到平衡。
实际油漆的作用和EDT上的负载也会影响这些结果。。。
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class RepaintTest {
public static void main(String[] args) {
new RepaintTest();
}
public RepaintTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private int paintRequests;
private int paints;
private int delay = 0;
public TestPane() {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
paintRequests++;
try {
Thread.sleep(delay);
} catch (InterruptedException exp) {
}
System.out.println("tick");
repaint();
}
}
});
t.setDaemon(true);
setLayout(new BorderLayout());
final JSlider slider = new JSlider();
slider.setMinimum(0);
slider.setMaximum(2000);
slider.setPaintTicks(true);
slider.setMajorTickSpacing(100);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
delay = slider.getValue();
paintRequests = 0;
paints = 0;
}
});
slider.setValue(0);
add(slider, BorderLayout.SOUTH);
t.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paints++;
String text = "Paints = " + paints + "; Paint Requests = " + paintRequests;
Graphics2D g2d = (Graphics2D) g.create();
FontMetrics fm = g2d.getFontMetrics();
int x = (getWidth() - fm.stringWidth(text)) / 2;
int y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
g2d.drawString(text, x, y);
g2d.dispose();
}
}
}