2011-03-03 56 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