Swing 従業員はパッシブ リペイント エンジンを使用します。つまり、必要な場合にのみ更新されます。は、RepaintManager
複数の再描画を、必要と思われる数の再描画イベントに統合するようにも最適化されています。
これは、 のリクエストを作成できることを意味しますが、repaint
その再描画がいつ行われるか、または行われるかどうかについての保証はありません。
これは主にパフォーマンスの最適化のために行われます。
詳細については、AWT と Swingでのペイントを参照してください。
その性質上、repaint
スレッドセーフです。 は、ペイント イベントをイベント キューにポストするrepaint
ように要求します。このキューは、イベント ディスパッチ スレッドによって処理されます。つまり、自分で EDTRepaintManager
と同期する必要はありません。repaint
次の例は、その考え方を示しています。ペイント カウンターをリセットし、リクエスト間の遅延を設定するシンプルなスライダーを提供しrepaint
ます。
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();
}
}
}