これは、実際にはダブル バッファリングが機能する方法ではなく、ペイント プロセスが機能する方法でもありません。
- オーバーライドしないでください
update
。
paint
可能な限りトップ レベルのコンテナー (Applet/JApplet/Frame/JFrame など) をオーバーライドしないでください。
- レンダリングできる「ペイント」パネル、できれば のようなものを使用します
JPanel
。Swing コンポーネントは、ダブル バッファリングのサポートを提供します
- ダブル バッファは、ペイント サイクルの外でペイントし、必要な場合にのみ更新する必要があります。これにより、不必要にコンテンツを再レンダリングする必要がないため、ペイント プロセス全体が高速になります。
- バッファを更新するときが来たら、最初に一時バッファにレンダリングします。これにより、更新中に発生する可能性のある再描画が時期尚早に画面に反映されなくなります...
public class TestPaintGeometry {
public static void main(String[] args) {
new TestPaintGeometry();
}
public TestPaintGeometry() {
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("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ShowPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ShowPane extends JPanel {
private GeometryPane geoPane;
public ShowPane() {
setLayout(new BorderLayout());
geoPane = new GeometryPane();
JButton redrew = new JButton("Redraw");
add(geoPane);
add(redrew, BorderLayout.SOUTH);
redrew.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
geoPane.redrew();
}
});
}
}
public class GeometryPane extends JPanel {
private BufferedImage buffer;
public void redrew() {
Path2D.Float path = new Path2D.Float();
int width = getWidth();
int height = getHeight();
int points = Math.max(10, (int) Math.round(Math.random() * 100));
for (int index = 0; index < points; index++) {
int x = (int) Math.round(Math.random() * width);
int y = (int) Math.round(Math.random() * height);
if (index > 0) {
path.lineTo(x, y);
} else {
path.moveTo(x, y);
}
}
BufferedImage tmp = createCompatibleImage(width, height);
Graphics2D g2d = tmp.createGraphics();
g2d.setColor(Color.BLACK);
g2d.draw(path);
g2d.dispose();
buffer = tmp;
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (buffer != null) {
int x = (getWidth() - buffer.getWidth()) / 2;
int y = (getHeight() - buffer.getHeight()) / 2;
g.drawImage(buffer, x, y, this);
}
}
}
public static GraphicsConfiguration getGraphicsConfiguration() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
}
public static BufferedImage createCompatibleImage(int width, int height) {
return createCompatibleImage(width, height, Transparency.TRANSLUCENT);
}
public static BufferedImage createCompatibleImage(int width, int height, int transparency) {
BufferedImage image = getGraphicsConfiguration().createCompatibleImage(width, height, transparency);
image.coerceData(true);
return image;
}
}
これにより、継承のレガシーによって制約されないGeometryPane
ため、JFrame
またはに展開できます...JAppelt