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

时间:2015-04-23 08:02:05

标签: java swing cursor swingworker jprogressbar

经过多次努力尝试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方法中的忙游标,并在嵌套类done的{​​{1}}方法中恢复正常游标。请注意,我还包括必要的包。

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

    Task

    setCursor(null);
    

    恢复光标?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

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