2015-04-23 47 views
1

经过多次尝试使JProgressBar按预期工作的尝试后,我终于成功实现了自己的目标。我曾使用@MadProgrammeradvice,并使用SwingWorker最终得到我想要的程序工作。将默认光标更改为忙光标不能正常工作

现在,当我的JProgressBar从0%变为100%时,我希望光标变为BUSY_CURSOR http://telcontar.net/Misc/screeniecursors/Cursor%20hourglass%20white.png。我GOOGLE了,发现,

setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 

是代码做它。我试过了,但它不能按预期工作。

相关的代码:

JProgressBar progress; 
JButton button;  
JDialog dialog;  //Fields of my GUI class 

progress=new JProgressBar(JProgressBar.HORIZONTAL,0,100); 
button=new JButton("Done"); 
dialog=new JDialog();    //Done from methods 

progress.setValue(0); 
progress.setStringPainted(true); 
progress.setBorderPainted(true); //Also done from methods 

button.addActionListener(this); //Also done from methods 

dialog.setLayout(new FlowLayout(FlowLayout.CENTER)); 
dialog.setTitle("Please wait..."); 
dialog.setBounds(475,150,250,100); 
dialog.setModal(true);   //Also done from methods 

dialog.add(new JLabel("Loading...")); 
dialog.add(progress);    //Also done from methods 

这里是actionPerformed方法:

public void actionPerformed(ActionEvent e) 
{ 
    setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 

    Task task=new Task(); 
    task.addPropertyChangeListener(this); 
    task.execute(); 
    dialog.setVisible(true); 
} 

propertyChange方法:

public void propertyChange(PropertyChangeEvent evt) { 
    if("progress" == evt.getPropertyName()){ 
     int progressnum = (Integer) evt.getNewValue(); 
     progress.setValue(progressnum); 
    } 
} 

和嵌套类Task

class Task extends SwingWorker<Void, Void> { 
     /* 
     * Main task. Executed in background thread. 
     */ 
     @Override 
     public Void doInBackground() { 
      int progressnum = 0; 
      setProgress(0); 

      while (progressnum < 100) { 
       try { 
        Thread.sleep(10); 
       } catch (InterruptedException ex) { 
        System.err.println("An error occured:"+ex); 
        ex.printStackTrace(); 
       } 

       progressnum ++; 
       setProgress(Math.min(progressnum, 100)); 
      } 
      return null; 
     } 

     /* 
     * Executed in event dispatching thread 
     */ 
     @Override 
     public void done() { 
      //setCursor(null); //turn off the wait cursor 
      setCursor(Cursor.getDefaultCursor()); //Is this one or the one above it right? 
      dialog.dispose(); 
      progress.setValue(progress.getMinimum()); 
     } 
    } 

当我按button时,带有JProgressBar的JDialog出现,JProgressBar从0%变为100%。在此期间,光标需要更改为BUSY_CURSOR http://telcontar.net/Misc/screeniecursors/Cursor%20hourglass%20white.png(忙光标),当JProgressBar达到100%时,需要恢复正常光标(NORMAL_CURSOR http://fc05.deviantart.net/fs70/i/2011/008/1/4/mouse_cursor_windows_by_mikima-d36oslj.png)。

问题是,当我按button时,光标变为繁忙的光标一瞬间,然后变回原来的光标。我希望光标很忙,直到JProgressBar达到100%。

我已经添加代码以将光标转换为忙碌光标在actionPerformed方法和恢复正常的光标在嵌套类Taskdone方法。请注意,我还包括必要的软件包。

  • 是什么导致了这个问题?
  • 我该如何解决?
  • 我应该使用

    setCursor(null); 
    

    setCursor(Cursor.getDefaultCursor()); 
    

    恢复光标?

回答

1

当您在JFrame上致电setCursor()时,它仅对框架有效,而不是对话框。同样,当您在JDialog上致电setCursor()时,它仅对对话框有效,而不是框架。有问题:你没有设置光标的对话框,对不对?

我不确定setCursor(null)是否比setCursor(Cursor.getDefaultCursor())安全。 :p

+0

现在我明白了。这正是我正在寻找的。我认为'setCursor'在整个程序中设置了给定的光标。为什么我的代码工作?因为GUI类,“扩展JFrame”。那么,这一次我将光标设置为JFrame? Arrgh!谢谢! –

1

用于创建无模式对话框和使用工作线程的权限,这将改善用户体验并减少感知延迟。考虑在工人启动时在对话框中添加MouseListener。在执行mouseEntered()时显示WAIT_CURSOR,并在您的实施mouseExited()中恢复默认设置。删除done()中的监听器。当用户的注意力转移到对话框而工作人员正在运行时,这将使进度和光标视觉线索一致。

+0

当我这样做时,光标需要在JDialog中才能变成忙碌光标,对吧?确切地说, –

+0

。优点是剩余的GUI保持响应,而用户得到视觉确认操作仍在进行中。 – trashgod

+0

好的。你的建议很有意义。谢谢 –