我在使用JFrame
时遇到了问题,它在连续运行代码时会被冻结。下面是我的代码:
btnRun
时,我调用了函数MainLoop()
:
ActionListener btnRun_Click =新的ActionListener() {@覆盖公共无效actionPerformed(ActionEvent e) { MainLoop();};MainLoop()
的实现:
{ Hopper =新CHopper(this);System.out.println(Hopper);btnRun.setEnabled(false);textBox1.setText("");Hopper.getM_cmd().ComPort = helpers.Global.ComPort;Hopper.getM_cmd().SSPAddress = helpers.Global.SSPAddress;Hopper.getM_cmd().Timeout = 2000;Hopper.getM_cmd(.RetryLevel)= 3;System.out.println("In MainLoop:“+ Hopper);//首先连接到验证器if (ConnectToValidator(10,3)) {btnHalt.setEnabled(真);r= true;textBox1.append("\r\nPoll循环\r\n“+”*} //此循环将在验证器连接之前不会运行,而(运行){ //轮询验证器if (!Hopper.DoPoll(textBox1)) { //如果轮询失败,请尝试重新连接textBox1.append(“试图重新连接.\r\n”);如果(!ConnectToValidator(10,3)) { //如果5次尝试失败,退出运行的循环= false;} //勾选计时器// timer1.start();// UpdateUI()更新表单;//设置win form的动态元素一次if (! bFormSetup ) { SetupFormLayout();bFormSetup= true;}//关闭com端口Hopper.getM_eSSP().CloseComPort();btnRun.setEnabled(真);btnHalt.setEnabled(False)};MainLoop()
函数中,while循环一直在持续运行,直到运行成为真为止,问题是如果我想停止那个which循环,我必须将运行设置为false,这是在另一个btnHalt
按钮上完成的:
ActionListener btnHalt_Click =新的ActionListener() {@ActionListener(@ActionEvent e) { textBox1.append("Poll循环停止\r\n“);System.out.println("Hoper”);ActionEvent= false;};但是btnHalt
没有响应,整个帧被冻结,也没有在textarea
中显示任何日志。
发布于 2013-03-21 05:47:19
Swing是一个单线程框架。也就是说,只有一个线程负责将所有事件分配给所有组件,包括重绘请求。
任何停止/阻止此线程的操作都会导致您的UI“挂起”。
Swing的第一条规则是,从不在事件调度线程上运行任何阻塞或耗时的任务,而是应该使用后台线程。
这会让你碰到第二条挥杆规则。不要在EDT之外创建、修改或与任何UI组件交互。
有很多方法可以解决这个问题。您可以使用SwingUtilities.invokeLater
或SwingWorker
。
SwingWorker
通常更容易使用,因为它提供了许多简单易用的方法,这些方法可以自动地重新同步对EDT的调用。
读一遍在Swing中并发
更新的
只是为了让你明白;)
您的MainLoop
方法不应该在EDT上下文中执行,这是非常糟糕的。
此外,您不应该与任何线程(当时的EDT )的任何UI组件进行交互。
https://stackoverflow.com/questions/15540319
复制相似问题