我正在使用多个BufferedImages。我正在使用的JPanel的绘制功能在JPanel上绘制currentImg:
@Override
public void paint(Graphics g) {
g.drawImage(currentImg, 0, 0, null);
}
使用currentImg以便我可以轻松切换图像,它在开头等于normalImg。 redImg是一个看起来与normalImg不同的BufferedImage。 现在我想画redImg半秒,然后再画一次normalImg。
currentImg = redImg;
repaint();
Thread.sleep(1000);
currentImg = normalImg;
repaint();
但是这段代码什么也没做,JPanel没有重新粉刷。这段代码有效:
currentImg = redImg;
repaint();
JOptionPane.showMessageDialog(this,"test");
Thread.sleep(1000);
JOptionPane.showMessageDialog(this,"test");
currentImg = normalImg;
repaint();
但是我不想显示消息对话框只是为了正确地重新绘制它。 感谢您的帮助:)
答案 0 :(得分:5)
paint
,尤其是顶级容器,使用基于JComponent
的组件并覆盖其paintComponent
方法。请查看Painting in AWT and Swing和Performing Custom Painting,了解有关在Swing气喘吁吁的更多详情super.paintXxx
Thread.sleep
,这将阻止它处理来自EventQueue
的新事件,包括重绘事件。请查看Concurrency in Swing以获取更多详细信息,并How to use Swing Timers查看可能的解决方案
答案 1 :(得分:4)
您可以通过在paint方法和Swing事件线程中调用Thread.sleep(...)
来冻结整个应用程序。不要这样做。而是使用Swing Timer并在Timer中交换JLabel的图标。
例如:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.*;
public class SwapImages extends JPanel {
private static final int TIMER_DELAY = 200;
private static final String SPRITE_PATH = "http://th02.deviantart.net/"
+ "fs70/PRE/i/2011/169/0/8/blue_player_sprite_sheet_by_resetado-d3j7zba.png";
public static final int SPRITE_ROWS = 6;
public static final int SPRITE_COLS = 6;
public static final int SPRITE_CELLS = 35;
private JLabel label = new JLabel();
private List<ImageIcon> iconList = new ArrayList<ImageIcon>();
private int iconIndex = 0;
public SwapImages() throws IOException {
URL imgUrl = new URL(SPRITE_PATH);
BufferedImage mainImage = ImageIO.read(imgUrl);
for (int i = 0; i < SPRITE_CELLS; i++) {
int row = i / SPRITE_COLS;
int col = i % SPRITE_COLS;
int x = (int) (((double) mainImage.getWidth() * col) / SPRITE_COLS);
int y = (int) ((double) (mainImage.getHeight() * row) / SPRITE_ROWS);
int w = (int) ((double) mainImage.getWidth() / SPRITE_COLS);
int h = (int) ((double) mainImage.getHeight() / SPRITE_ROWS);
BufferedImage img = mainImage.getSubimage(x, y, w, h);
ImageIcon icon = new ImageIcon(img);
iconList.add(icon);
}
add(label);
label.setIcon(iconList.get(iconIndex));
new Timer(TIMER_DELAY, new TimerListener()).start();
}
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
iconIndex++;
iconIndex %= iconList.size();
label.setIcon(iconList.get(iconIndex));
}
}
private static void createAndShowGui() {
SwapImages mainPanel = null;
try {
mainPanel = new SwapImages();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
JFrame frame = new JFrame("SwapImages");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}