将默认光标更改为忙碌光标无法按预期方式工作

经过多次尝试使JProgressBar按预期工作,我终于成功实现了我的目标。 我曾经使用@MadProgrammer的建议并使用SwingWorker来最终使程序正常工作。

现在,当我的JProgressBar从0%变为100%时,我希望光标变为BUSY_CURSOR http://sofzh.miximages.com/java/Cursor hourglass white.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 { /* * 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://sofzh.miximages.com/java/Cursor hourglass white.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()); 

    恢复光标?

JFrame上调用setCursor()时,它只对框架有效,而不是对话框。 类似地,当你在JDialog上调用setCursor()时,它只对对话框有效,而不是帧。 有问题:你没有为对话框设置光标,对吧?

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

用于创建无模式对话框和使用工作线程的荣誉,这将改善用户体验,减少感知延迟。 考虑在工作程序启动时向对话框添加MouseListener 。 在mouseEntered()实现中显示WAIT_CURSOR ,并恢复mouseExited()实现中的默认值。 删除done()的监听器。 当工作人员正在运行时,当用户的注意力转移到对话框 ,这将使进度和光标视觉提示重合。