Swing のすべてのアニメーションは、 Event Dispatching Threadを考慮する必要があります。
EDT をブロックする可能性のあるアクション (ループや I/O など) を EDT のコンテンツ内で実行しないでください。これにより、EDT が (特に) ペイント要求を処理できなくなります。
JPanel
ちらつきをなくすのに役立つなど、常にダブル バッファをサポートできる表面を使用する必要があります。
以下は、 aを使用しjavax.swing.Timer
て 2 つの画像を切り替えます...


public class TestPacMan {
public static void main(String[] args) {
new TestPacMan();
}
public TestPacMan() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new PacManPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PacManPane extends JPanel {
private BufferedImage pacOpened;
private BufferedImage pacClosed;
private BufferedImage frame;
private boolean opened = true;
public PacManPane() {
try {
pacOpened = ImageIO.read(new File("PC-Closed.png"));
pacClosed = ImageIO.read(new File("PC-Opened.png"));
frame = pacOpened;
} catch (IOException exp) {
exp.printStackTrace();
}
Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
opened = !opened;
frame = opened ? pacOpened : pacClosed;
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (frame != null) {
int x = (getWidth() - frame.getWidth()) / 2;
int y = (getHeight() - frame.getHeight()) / 2;
g2d.drawImage(frame, x, y, this);
}
g2d.dispose();
}
}
}