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

时间:2016-03-13 15:32:59

标签: java swing

这是我遇到问题的代码的一部分。 我应该在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 + " ");
        }
    });

2 个答案:

答案 0 :(得分:1)

你的问题是你的for循环你一次创建图像,一次创建标签,并创建一堆没有做任何有用的Swing Timers。您不应该使用for循环来遍历您的图像,而是创建一个JLabel,最重要的是创建一个Swing Timer,并且计时器将替换for循环。而不是循环,将重复调用Timer的actionPerformed方法。

建议:

  1. 不要尝试使用for循环来交换图像 - 这是执行此操作的控制台方式,并且不适用于Swing GUI。
  2. 创建单个图像查看器JLabel以查看图像,并将其保留在GUI上。不要添加和删除它,也不要为每个图像创建新的JLabel。
  3. 一次读取所有图像,可能在构造函数中(如果图像不是太大)。
  4. 将图像转换为ImageIcons并将其保存在ArrayList<Icon>
  5. 在您的Swing Timer中,执行的操作远不止repaint()revalidate()。而是将索引前进到ArrayList,确保它不等于或大于列表的大小,并从列表中获取图像并将其放在图像查看器JLabel中。
  6. 完成。
  7. 例如:

    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变量,该变量充当保存图像的ArrayList的索引(实际上是ImageIcons)。所以首先我增加索引,然后如果它匹配iconList ArrayList的大小我将其更改为0,然后我得到图标并将其设置为JLabel。简单。

答案 1 :(得分:0)

问题是在for循环中将计时器设置为5秒。 for循环将非常快,就像在几毫秒内完成一样。你可以在几毫秒内启动计时器,这样它们就可以同时完成(5秒+几毫米)。

即使这不是一个好方法,如果你在5秒后触发第一个计时器,在10点之后触发第二个计时器等等,你的问题就会解决(再说一遍,这个编码不是很好)。 / p>