2013-08-18 49 views
1

我已经创建ImagePanel它能够显示指定目录中的图像 - >它休眠1秒,并从Java项目的目录加载下一个图像。 它实际上加载下一个图像,但它不显示(它不刷新面板),当它完成目录中的所有文件时,它只显示目录中的最后一张图像。我想在加载完所有图像后刷新它。刷新JPanel后下载图像

import java.awt.Color; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.File; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.border.LineBorder; 

public class Okno extends JFrame { 
    JPanel jp; 
    ImagePanel ImagePanel; 
    JButton buttonExit; 
    JButton buttonWyjscie; 

    public Okno() { 

    } 

    public void createGUI() { 
     setSize(400, 400); 
     setLayout(new GridLayout()); 
     buttonExit = new JButton("Exit"); 
     buttonWyjscie = new JButton("Wyjscie"); 
     // Sluchacz sluchacz = new Sluchacz(); 

     // buttonExit.addActionListener(sluchacz); 
     buttonExit.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.exit(0); 

      } 
     }); 

     jp = new JPanel(); 
     jp.setBorder(new LineBorder(new Color(40, 120, 80), 4)); 

     ImagePanel = new ImagePanel(); 
     ImagePanel.setBorder(new LineBorder(Color.blue, 4)); 
     jp.add(buttonExit); 
     add(jp); 
     add(ImagePanel); 

     setVisible(true); 
     slajd(); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

    } 

    public void slajd() { 
     try { 
      File f = new File("."); 
      File[] tablicaPlikow = f.listFiles(); 
      for (File el : tablicaPlikow) { 

       String rozszerzenie = el.getName().substring(
         el.getName().length() - 3); 

       if (rozszerzenie.equals("jpg") || rozszerzenie.equals("peg")) { 
        System.out.println(rozszerzenie); 
        ImagePanel.setImage(el); 
       } 
       repaint(); 
      } 
      setVisible(true); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Okno().createGUI(); 
      } 
     }); 

    } 

} 

import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.image.BufferedImage; 
import java.io.File; 

import javax.imageio.ImageIO; 
import javax.swing.JPanel; 

public class ImagePanel extends JPanel { 
    private BufferedImage image; 

    public ImagePanel() { 
    } 

    public ImagePanel(String sciezka) { 
     setImage(new File(sciezka)); 
    } 

    public void setImage(File plik) { 
     try { 
      image = ImageIO.read(plik); 
      System.out.println("tutaj"); 
      repaint(); 
      Thread.sleep(1000); 
     } catch (Exception e) { 

      e.printStackTrace(); 
     } 
    } 

    public void paint(Graphics g) { 
     if (image != null) { 
      Image b = image.getScaledInstance(getWidth(), getHeight(), 
        Image.SCALE_FAST); 
      g.drawImage(image, 0, 0, getWidth(), getHeight(), null); 
     } 

    } 

} 
+0

你的尝试是什么?为什么他们没有工作?他们没有达到你期望他们做什么的方式?任何错误消息,异常或不良行为? –

回答

3

睡在EDT防止画面摆动,所以只能看到最后一张图片。相反,在事件分派线程睡觉,用摇摆Timer做重复的工作:如果加载图像是需要长时间

private final ActionListener timerTask = new ActionListener() { 
    @Override 
    public void actionPerformed(final ActionEvent e) { 
     // Whatever you need to to that 
     showNextImage(); 
    } 
}; 

Timer timer = new Timer(1000, timerTask); 
timer.start(); 

,可以考虑使用background task预加载在内存中的下一个,不阻塞EDT 。

2

答案很可能是:在方法slajd,调用repaint();后,加入

Thread.sleep(1000); 

然而,这完全违背了挥杆的基于事件的性质,在这种情况下甚至不起作用,因为出于效率原因,Swing不会立即执行repaint()呼叫。它在所有事件处理结束后才“收集”并执行它们。如果您在事件处理程序(直接或间接)中包含休眠期(或任何其他长时间运行的操作),则重新绘制将被延迟,并且应用程序对该点极其反应迟钝,因为在这种情况下,它并不真正起作用。

你需要做的是在createGUI实例化一个Swing定时器(javax.swing.Timer;不java.util.Timer,或Timer班其他几个包混淆)一个触发间隔为1秒,而不是调用slajd()。第一次射击应该是立即的,或者你可以包含代码来显示第一个文件。相关的侦听器将取代slajd()应该跟踪要显示的下一个文件。您将最有可能想使这个监听一个完整的类字段以支持此跟踪,一个指向ImagePanel哪里显示文件等

欲了解更多信息,请阅读Java's Tutorial on How to Use Swing Timers

+0

1)因为它会起作用(并且我可能会使用它)如果问题都是问题。 2)因为我家里有太多的停电事故,想救我的回应。之后我也做了一些其他的部分保存,并且3)因为我的回答(请检查他们是否需要)通常很长,并且(希望)完成,而一些求助者只需要快速回复。 –

+0

不是。为了与上述第3点相一致,我将解释Thread.sleep为什么不起作用。非常感谢您的帮助,使其成为更好的答案。 –