Swing ProgressMonitor无法正常工作

时间:2013-10-07 16:55:15

标签: java swing progressmonitor

我正在尝试在Java Swing中学习ProgressMonitor。 我创建了这个简单的测试代码 -

public class ProgressMonitorTest extends JFrame 
{
private JPanel contentPane;
private ProgressMonitor progressMonitor;
private JButton button;
private static ProgressMonitorTest frame;
private static boolean isFrameReady;

public JButton getButton()
{
    return button;
}

public ProgressMonitor getProgressMonitor()
{
    return progressMonitor;
}

/**
 * Launch the application.
 */
public static void main(String[] args) 
{
    EventQueue.invokeLater(new Runnable() 
    {
        public void run() 
        {
            try 
            {
                frame = new ProgressMonitorTest();
                frame.setVisible(true);
                isFrameReady = true;
            } 
            catch (Exception e) 
            {
                e.printStackTrace();
            }
        }
    });

    while(!isFrameReady)
    {
        //
    }

    frame.getButton().addActionListener(new ActionListener() 
    {   
        @Override
        public void actionPerformed(ActionEvent e) 
        {
            try
            {
                for(int i=0;i<=10;i++)
                {
                    final int percent = i;
                    SwingUtilities.invokeAndWait(new Runnable() 
                    {   
                        @Override
                        public void run()
                        {
                            frame.getProgressMonitor().setProgress(percent * 10);
                            frame.getProgressMonitor().setNote("Completed " + percent*10 + "%.");
                        }
                    });
                    try
                    {
                        Thread.sleep(1000);
                    }
                    catch(Exception ee)
                    {
                        //
                    }                           
                }
            }
            catch(Exception es)
            {
                //
            }
        }           
    });
}

/**
 * Create the frame.
 */
public ProgressMonitorTest() 
{
    isFrameReady = false;

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    setTitle("Progress Monitor");

    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));

    progressMonitor = new ProgressMonitor(frame, "Update in progress...", "", 0, 10);
    button = new JButton("Click Here");
    contentPane.add(button);

    setContentPane(contentPane);
}

}

有关此问题的一些问题 -

  1. 如果我删除了isFrameReady支票,程序会在我指定按钮动作监听器的行上显示NullPointerException

  2. 如果我保留上述检查,则点击该按钮不会做任何事情。

  3. 保持上面的检查然后调试它,我让它等待一段时间才能到达动作监听器的行。在这种情况下,它可以工作,但会立即退出,说它无法从事件处理线程调用invokeAndWait

  4. 我在这一切中缺少什么?有人可以解释如何使其发挥作用。

1 个答案:

答案 0 :(得分:2)

  

如果我删除isFrameReady检查,程序会说a   在我指定按钮操作的行的NullPointerException   监听器。

您使用isFrameReady可确保您已成功创建frame。在您的main内,您使用调用EventQueue.invokeLater(new Runnable(){})向事件发送线程(EDT)发布的请求:删除支票isFrameReady,您将在主线程中调用frame.getButton()但是{1}}尚未在EDT中创建frame因此发生了frame = new ProgressMonitorTest();

  

如果我保留上述检查,则点击该按钮不会做任何事情。

你现在应该明白,上面的检查与按钮点击无关。该按钮没有做任何事情,因为GUI因违反swing的单线程规则而被冻结。将NullPointerException方法的递增for循环放在另一个线程中,如下面的代码片段所示,并从那里执行它。你会发现它运作良好。

actionPerformed
  

保持上述检查然后再调试,我让它等待   在它到达动作监听器的行之前的某个时间。在   这种情况下,它可以工作,但立即退出说它无法调用   来自事件处理线程的invokeAndWait。

new Thread(){ public void run() { for(int i=0; i<10; i++) { //whatever you were doing. } } }.start(); 阻止当前线程并等待EDT完成执行给它的任务。由于SwingUtitlies.invokeAndWait()函数已在EDT内运行,因此从当前线程调用actionPerformed():EDT将阻止当前线程:不应允许的EDT。在这种情况下,请勿使用SwingUtitlies.invokeAndWait()。你应该打电话给invokeAndWait

但是,在您了解Swing线程模型之前,我认为您不会得到任何东西。阅读javadoc和一些互联网资源。有没有“Filthy Rich Clients”这本书并试试这本书所提供的例子:你将对图形效果有更多的了解,然后就可以提供任何其他资源。