简体   繁体   中英

Image Slideshow using JFrame

I have a problem with a task that seemed to be pretty easy. I have to create a program that will show images (.jpg,.png and .gif) consecutively. Images have to be the contents of some files, that is given as an argument to the program. When I have to load the images separately, it works, but the issue occurs when I load them one after another with a sleep between them.
Here is my code:

  import javax.swing.SwingUtilities;

    public class Main {

      public static void main(String[] args) 
      {
        SwingUtilities.invokeLater(new Runnable() 
        {
          @Override
          public void run()  
          {
            new MyFrame(args[0],Integer.parseInt(args[1])); 
    //First argument is path to file with images, second - amount of time (in seconds) which every image has to stay on the screen until the next one appears
          }
        });
      }
    }


import java.io.File;
import javax.swing.*;

public class MyFrame extends JFrame{

    public MyFrame(String path, int time){
        super("Obrazki");
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setVisible(true);
        MyPanel panel = new MyPanel();
        panel.setVisible(true);
        this.add(panel);
        pack();
        File file = new File(path);
        String[] tabs = file.list();
        for(int i=0; i<tabs.length; i++)
        {
            panel.loadImage(path+"\\"+tabs[i]);
            this.repaint();
            try {
                Thread.sleep(time*1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}


import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import javax.swing.JPanel;

public class MyPanel extends JPanel 
{
  Image img;

  public void loadImage(String s)
  {
     img = Toolkit.getDefaultToolkit().getImage(s);
     MediaTracker tracker = new MediaTracker(this);
     tracker.addImage(img, 1);
     while(!tracker.checkID(1)) {
         try {
            tracker.waitForID(1);
         } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
         }
     }
     this.repaint();
  }

  @Override
  public void paintComponent(Graphics g) 
  {
     super.paintComponent(g);
     Graphics2D g2 = (Graphics2D)g;
     g2.drawImage(this.img, 0, 0, this.getSize().width, this.getSize().height, this);
  }
}

but the issue is when i load them one after another with sleep time between them.

You are causing the Event Dispatch Thread (EDT) to sleep, which means the GUI can't respond to events or repaint itself. Read the section from the Swing tutorial on Concurrency for more information.

Don't use Thread.sleep() when code is executing on the EDT .

For animation you can:

  1. use a SwingWorker (with Thread.sleep())and publish the Icon you want to paint, or
  2. use a Swing Timer. The tutorial also has a section on How to Use Swing Timers .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM