2011-03-03 31 views
1

問題,我試圖讓一個SwingWorker的工作。 我有下面的代碼的那一刻:用的SwingWorker

public class ImageWorker extends SwingWorker<Void, Void> implements KeyListener 
{ 
private JLabel imageLabel; 
private ImageIcon basicImage; 
private ImageIcon whiteImage; 
public static void main(String[] args) 
{ 
    new ImageWorker();  
} 

public ImageWorker() 
{ 
    final JFrame frame = new JFrame(); 
    imageLabel = new JLabel(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setSize(400, 400); 
    frame.getContentPane().add(imageLabel); 
    frame.setVisible(true); 
    try 
    { 
     basicImage = new ImageIcon(ImageIO.read(new File("src\\img\\basis1.jpg")).getScaledInstance(1024, 768, Image.SCALE_SMOOTH)); 
     whiteImage = new ImageIcon(ImageIO.read(new File("src\\img\\wit.jpg")).getScaledInstance(1024, 768, Image.SCALE_SMOOTH));  
    } 
    catch(IOException ex) 
    { 
     ex.getMessage(); 
    } 
    this.execute(); 

} 

@Override 
protected Void doInBackground() 
{ 
    try 
    { 
     while (true) 
     { 
      displayImage(basicImage); 
      Thread.sleep(1000L); 
      if(isCancelled()) 
       return null; 
     } 
    } 
    catch(InterruptedException e) 
    { 
     e.getMessage(); 
    } 
    return null; 
} 

private void displayImage(final Icon image) 
{ 
    SwingUtilities.invokeLater(new Runnable() 
    { 
     public void run() 
     { 
      imageLabel.setIcon(image); 
     } 
    });  
} 

我期待的圖像出現在的JLabel,但我只看到JFrame中彈出。文件正確加載我已經在另一個設置中測試過。 任何指針?

+1

你究竟在做什麼,需要一個'SwingWorker'?它意味着用於在後臺執行某些密集操作但希望結果顯示在UI中的情況,因此需要在「Event Dispatch Thread」中執行某些操作,例如通過網絡加載映像。在這裏,它看起來像你只是不斷地顯示圖像。也許如果你解釋你想達到什麼,你會得到一個很好的答案。 – 2011-03-03 15:13:25

+0

我沒有做任何事情,我只是試圖在JLabel上替換一些圖像,直到用戶按下一個鍵。但由於我不是程序員,我不知道從哪裏開始。我被告知SwingWorker將是一個容易開始的地方,因爲效率和代碼都不重要。這是我一次性使用某個課程的演示文稿(顯然不是CS相關的)。我在尋找快速ñ髒嘿嘿http://stackoverflow.com/questions/5179569/alternating-images-with-a-timer-using-java – Oxymoron 2011-03-03 15:17:57

+0

好了,沒有什麼幫助。讓我再說一遍。 – 2011-03-03 15:25:37

回答

2

下面是一個使用Timer而不是使用SwingWorker的例子,它確實不適合您的情況。請注意,它與現有代碼沒有太大差別。

import java.awt.Image; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.io.File; 
import java.io.IOException; 

import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.Timer; 

public class ImageWorker implements KeyListener 
{ 
    private JLabel imageLabel; 
    private ImageIcon basicImage; 
    private ImageIcon whiteImage; 
    private boolean isBasic = true; 
    private int delay = 1000; //milliseconds 
    private Timer timer; 

    public static void main(String[] args) 
    { 
     new ImageWorker(); 
    } 

    public ImageWorker() 
    { 
     final JFrame frame = new JFrame(); 
     imageLabel = new JLabel(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(400, 400); 
     frame.getContentPane().add(imageLabel); 
     frame.setVisible(true); 

     try 
     { 
      basicImage = new ImageIcon(ImageIO.read(new File("src\\img\\basis1.jpg")).getScaledInstance(1024, 768, Image.SCALE_SMOOTH)); 
      whiteImage = new ImageIcon(ImageIO.read(new File("src\\img\\wit.jpg")).getScaledInstance(1024, 768, Image.SCALE_SMOOTH));  
     } 
     catch (IOException ex) 
     { 
      ex.getMessage(); 
      ex.printStackTrace(); 
     } 

     frame.addKeyListener(this); 
     ActionListener taskPerformer = new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
       if(isBasic) { 
        //display basic image 
        imageLabel.setIcon(basicImage); 
       } 
       else { 
        //display white image 
        imageLabel.setIcon(whiteImage); 
       } 

       //toggle the flag 
       isBasic = !isBasic; 
      } 
     }; 
     //use a timer instead of SwingWorker 
     timer = new Timer(delay, taskPerformer); 
     timer.start(); 

    } 



    @Override 
    public void keyPressed(KeyEvent e) 
    { 
     //key pressed, we want to stop toggling so stop the timer 
     timer.stop(); 
     //do whatever else you were doing to set the value for isCancelled(); 
    } 

    @Override 
    public void keyReleased(KeyEvent e) 
    { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void keyTyped(KeyEvent e) 
    { 
     // TODO Auto-generated method stub 

    } 
} 
+0

您可能遇到的最棘手問題之一是,您應該在'Event Dispatch Thread'中執行任何GUI相關操作(更改大小,顏色等)。如果使用普通定時器(java.util.Timer),則超時事件不會觸發GUI線程中的回調,這對於Swing應用程序來說是有問題的。這就是爲什麼,如果你注意到了,我們希望使用'javax.swing.Timer',它將在GUI線程中回調,以便你可以安全地執行GUI操作。 – 2011-03-03 15:43:18

+0

另外請注意,您的原始代碼確實對我有用 - 至少可以看到圖像。因此,如果您仍然遇到問題,則可能是您爲圖片提供的路徑存在問題。更好,更便攜的方式是[將圖像作爲資源加載](http://download.oracle.com/javase/tutorial/uiswing/components/icon.html)。 – 2011-03-03 15:49:00

+0

哇,這正是我正在尋找的:)我可以很容易地做出一些改變,以滿足我的需求。非常非常感謝你!!! – Oxymoron 2011-03-03 15:50:09

1

A SwingWorker不適合您的情況在swing包中查看Timer。這裏是一個鏈接到API:http://download.oracle.com/javase/6/docs/api/javax/swing/Timer.html

你有定時器的運行,改變每一秒,因爲圖像被你所需要的。

而且,只要你有例外,至少打印出堆棧跟蹤或消息。否則,您將不知道是否發生異常並被捕獲。

+0

@jzd是否setIcon觸發重繪或他需要明確調用它嗎?我不是肯定了我的頭頂。 – gcooney 2011-03-03 15:33:42

+0

我還需要能夠取消按一個鍵,我知道該怎麼做運行,但我沒有時間(也不希望)學習堅果和Java的螺栓,所以我一直在使用這個SwingWorker的幾個小時,但沒有很多的運氣。作爲矯枉過正與否,我想追求這個,所以這個問題。 – Oxymoron 2011-03-03 15:34:03

+0

@ZedLep,你是在浪費你的時間的SwingWorker搞亂,使用定時器,請保留一個引用,並在需要時取消它。 – jzd 2011-03-03 15:36:48