我正在努力学习Java中的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);
}}
有几个问题-
isFrameReady检查,程序将在指定按钮操作侦听器的行中显示一个NullPointerException。invokeAndWait。我在这一切中遗漏了什么?有人能解释一下怎么让这件事起作用吗。
发布于 2013-10-07 17:58:38
如果删除isFrameReady检查,程序将在指定按钮操作侦听器的行中显示一个NullPointerException。
使用isFrameReady可以确保您成功地创建了frame。在您的main中,您发布的使用调用EventQueue.invokeLater(new Runnable(){}):删除check isFrameReady的事件分派线程( EDT )的请求将在主线程中调用frame.getButton(),但frame尚未由EDT中的frame = new ProgressMonitorTest();创建,因此出现NullPointerException。
如果我保留上面的检查,然后点击按钮什么也不做。
你现在应该明白了,上面的检查与点击按钮无关。该按钮没有做任何事情,因为GUI因为违反swing的单一线程规则而被冻结。如下面的代码片段所示,将actionPerformed方法的增量actionPerformed循环放在另一个线程中,并从那里执行它。你会发现它运转得很好。
new Thread(){
public void run()
{
for(int i=0; i<10; i++)
{
//whatever you were doing.
}
}
}.start(); 保持上面的检查,然后调试它,我让它等待一段时间才到达动作侦听器所在的行。在这种情况下,它可以工作,但立即退出,说它不能从事件处理线程调用invokeAndWait。
SwingUtitlies.invokeAndWait()阻塞当前线程并等待EDT完成,执行交给它的任务。由于actionPerformed()函数已经在EDT中运行,因此从当前线程:EDT调用SwingUtitlies.invokeAndWait()将阻塞不应该允许的当前线程:EDT。不要在这种情况下使用invokeAndWait。你应该打电话给SwingUtilities.invokeLater()。
但是,我认为在您了解Swing线程模型之前,您不会得到任何东西。阅读javadoc和一些互联网资源。一定要有这本书“肮脏的富客户端”,并尝试一下这本书提供的例子:您将在图形效果方面有更多的知识,而其他任何资源都可以提供。
https://stackoverflow.com/questions/19230449
复制相似问题