如何在jpanel上延迟显示图片?

2024-05-02

这是我遇到问题的代码部分。 我应该每 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 方法,而不是循环。

建议:

  1. 不要尝试使用 for 循环来交换图像——这是执行此操作的控制台方式,并且不适用于 Swing GUI。
  2. 创建一个图像查看器 JLabel 来查看图像,并将其保留在 GUI 上。不要添加和删除它,也不要为每个图像创建新的 JLabel。
  3. 一次读取所有图像,也许在构造函数中(如果图像不是太大)。
  4. 将图像转换为 ImageIcons 并将其保存在ArrayList<Icon>.
  5. 在你的 Swing Timer 中,做的不仅仅是repaint() and revalidate()。相反,将索引提前到 ArrayList,确保它不等于或大于列表的大小,然后从列表中获取图像并将其放置在图像查看器 JLabel 中。
  6. 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(使用前将#替换为@)

如何在jpanel上延迟显示图片? 的相关文章

随机推荐