【问题标题】:Changing the default cursor to busy cursor does not work as expected将默认光标更改为忙光标无法按预期工作
【发布时间】:2015-04-23 08:02:05
【问题描述】:

经过多次尝试使JProgressBar 按预期工作,我终于成功地实现了我的目标。我曾使用@MadProgrammeradvice 并使用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);
    }
}

还有嵌套类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 方法中添加了将光标转换为忙碌光标的代码,并在嵌套类Taskdone 方法中添加了恢复正常光标的代码。请注意,我还包括了必要的软件包。

  • 导致问题的原因是什么?
  • 如何解决?
  • 我应该使用

    setCursor(null);
    

    setCursor(Cursor.getDefaultCursor());
    

    恢复光标?

【问题讨论】:

    标签: java swing cursor swingworker jprogressbar


    【解决方案1】:

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

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

    【讨论】:

    • 现在我明白了。这正是我想要的。我认为setCursor 在整个程序中设置了给定的光标。为什么我的代码有效?因为 GUI 类,extends JFrame。那么,一直以来我都将光标设置为 JFrame?啊!谢谢!
    【解决方案2】:

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

    【讨论】:

    • 当我这样做时,光标需要在 JDialog 中才能变成忙碌光标,对吧?
    • 没错。优点是您剩余的 GUI 保持响应,而用户可以直观地确认操作仍在等待中。
    • 好的。你的建议很有道理。谢谢
    猜你喜欢
    • 2011-05-02
    • 1970-01-01
    • 1970-01-01
    • 2012-11-09
    • 2023-01-14
    • 2017-02-11
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    相关资源
    最近更新 更多