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

Changing the default cursor to busy cursor does not work as expected

经过多次尝试使 JProgressBar 按预期工作,我终于成功地实现了我的目标。我使用了 @MadProgrammer's 并使用了 SwingWorker 最终让程序按我想要的方式工作。

现在,我想让光标变成 当我的 JProgressBar 从 0% 变为 100% 时。我用谷歌搜索并发现

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);
    }
}

和嵌套的 class 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%。这段时间需要将光标变为(忙光标),当JProgressBar达到100%时,变为正常光标( ) 需要恢复。

问题是,当我按下 button 时,光标瞬间变为忙碌光标,然后又变回原来的光标。我希望光标在 JProgressBar 达到 100% 之前一直处于忙碌状态。

我在 actionPerformed 方法中添加了将光标转换为忙碌光标的代码,并在嵌套 class 的 done 方法中添加了恢复正常光标的代码 Task。请注意,我还包含了必要的包。

创建无模式对话框和使用工作线程的荣誉,这将通过减少感知延迟来改善用户体验。考虑在 worker 启动时向对话框添加 MouseListener。在 mouseEntered() 的实现中显示 WAIT_CURSOR,并在 mouseExited() 的实现中恢复默认值。删除 done() 中的侦听器。当用户的注意力转移到对话框 工作人员 运行.

时,这将使进度和光标视觉提示重合

当您在 JFrame 上调用 setCursor() 时,它只对框架有效,对对话框无效。同样,当您在 JDialog 上调用 setCursor() 时,它只对对话框有效,对框架无效。问题来了:你没有为对话框设置光标,对吧?

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