这是我遇到问题的代码部分。
我应该每 5 秒显示一次图片,但它不起作用。
我希望你能帮忙。谢谢
编辑:5秒后所有图片一起显示
JButton btnGenerateNumber = new JButton("Generate Number");
btnGenerateNumber.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent arg0) {
ImageIcon apple = new ImageIcon("Resources/apple.png");
try{
for(int i=0; i<labelApp.length; i++){
remove(labelApp[i]);
}
}catch(Exception e){
}
Random rand = new Random();
int number = rand.nextInt(10)+1;
labelApp = new JLabel[number];
for(i=0; i<number; i++){
labelApp[i] = new JLabel(apple);
labelApp[i].setBounds(500, 100 + 10 * i, 40, 39);
add(labelApp[i]);
Timer t = new Timer(5000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
revalidate();
repaint();
}
});
t.start();
}
labelNum.setText(number + " ");
}
});
您的问题是,通过 for 循环,您一次创建所有图像,一次创建所有标签,并创建一堆不执行任何有用操作的 Swing 计时器。您不应该使用 for 循环来浏览图像,而是创建一个 JLabel 和最重要的是一个 Swing Timer,并且计时器将替代 for 循环。将重复调用 Timer 的 actionPerformed 方法,而不是循环。
建议:
- 不要尝试使用 for 循环来交换图像——这是执行此操作的控制台方式,并且不适用于 Swing GUI。
- 创建一个图像查看器 JLabel 来查看图像,并将其保留在 GUI 上。不要添加和删除它,也不要为每个图像创建新的 JLabel。
- 一次读取所有图像,也许在构造函数中(如果图像不是太大)。
- 将图像转换为 ImageIcons 并将其保存在
ArrayList<Icon>
.
- 在你的 Swing Timer 中,做的不仅仅是
repaint()
and revalidate()
。相反,将索引提前到 ArrayList,确保它不等于或大于列表的大小,然后从列表中获取图像并将其放置在图像查看器 JLabel 中。
- Done.
例如:
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<Icon> iconList = new ArrayList<>();
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.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
上面代码的关键是Timer的ActionListener:
private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent arg0) {
iconIndex++;
iconIndex %= iconList.size();
label.setIcon(iconList.get(iconIndex));
}
}
它的作用是增加一个 int 变量,该变量充当保存图像(实际上是 ImageIcons)的 ArrayList 的索引。因此,首先我增加索引,然后如果它与 iconList ArrayList 的大小匹配,则将其更改为 0,然后获取图标并将其设置到 JLabel 中。简单的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)