2013-08-18 92 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爲什麼不起作用。非常感謝您的幫助,使其成爲更好的答案。 –