免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3293 | 回复: 11
打印 上一主题 下一主题

事件触发不了 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-10-14 16:39 |只看该作者 |正序浏览
做了一个界面,包括确定和取消两个按钮,确定触发的事件是:
SSLServerSocket listen = new SSLServerSocket(ctx, port);
        while (true) {
          SSLSocket s = (SSLSocket) listen.accept();
         }
希望取消可以触发中断上述连接,现在出现了这样一个问题:
一旦按下按钮”确定“,可以正确执行上述代码,但是按下”取消“或者右上角那个关闭”X“,都没有用,无法中断程序,除非使用任务管理器来结束程序。请赐教,不胜感激

论坛徽章:
0
12 [报告]
发表于 2004-10-15 04:26 |只看该作者

事件触发不了

典型的阻塞问题。

一般来说,普通的程序都会从头执行到尾,但是有些程序使用了“阻塞”模式,如果阻塞事件不被触发,后面的程序不会被执行。

  1. public class MyClass extends Thread{
  2.     public boolean keepRunning;
  3.    
  4.     /** Creates a new instance of MyClass */
  5.     public MyClass() {
  6.         keepRunning = true;
  7.     }
  8.    
  9.     public void run()
  10.     {
  11.         Socket s;
  12.         while(keepRunning)
  13.         {
  14.             s = serversocket.accept();
  15.             //如果没有连接,这里的代码无法被执行
  16.             ....
  17.             ....
  18.         }
  19.     }

  20.     public void stopThread()
  21.     {
  22.         this.keepRunning = false;
  23.     }
  24. }
复制代码


即使你用 myclass.stopThread() , 也不会跳过 serversocket.accept();
正确的方法是彻底破坏阻塞,但是要注意清理资源
应该把serversocket声明成全局变量,然后在stopThread里面调用serversocket.close(),这时会在serversocket.accept()产生一个Exception,然后在finally里面清理掉这个socket。注意,清理不使用的资源非常重要,如果你不能正常清理,有些资源可能会一直被占用,这样你的内存很快就用光,产生OutOfMemory Error而导致程序崩溃的。

  1. public class MyClass extends Thread{
  2.     public boolean keepRunning;
  3.     public Socket serversocket;
  4.    
  5.     /** Creates a new instance of MyClass */
  6.     public MyClass(ServerSocket ssocket) {
  7.         keepRunning = true;
  8.         serversocket = ssocket;
  9.     }
  10.    
  11.     public void run()
  12.     {
  13.         Socket s;
  14.         while(keepRunning)
  15.         {
  16.             try{
  17.                 s = serversocket.accept();
  18.                 //....
  19.                 //.....
  20.             }catch(...){
  21.                 //...
  22.             }finally{
  23.                 //清理资源
  24.             }
  25.         }
  26.     }
  27.    
  28.     public void stopThread()
  29.     {
  30.         try{
  31.             keepRunning = false;
  32.             serversocket.stop();
  33.         }catch(){
  34.             
  35.         }finally{
  36.             
  37.         }
  38.     }
  39. }
复制代码


这个class必须以独立的线程来运行,这样你才可能在这个class运行的时候对其进行干预。

论坛徽章:
0
11 [报告]
发表于 2004-10-14 20:34 |只看该作者

事件触发不了

刚才的代码有错误
落了.start()
应为
new Thread(){...}.start();

论坛徽章:
0
10 [报告]
发表于 2004-10-14 19:51 |只看该作者

事件触发不了

谢谢大家。

论坛徽章:
0
9 [报告]
发表于 2004-10-14 19:28 |只看该作者

事件触发不了

好像默认jvm不会重开一个线程来处理事件响应

论坛徽章:
0
8 [报告]
发表于 2004-10-14 19:26 |只看该作者

事件触发不了

我写了一个例子
罗嗦了点
对付看吧

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JButton;
import javax.swing.JFrame;

/**
* @author Administrator
*
* 更改所生成类型注释的模板为
* 窗口 >; 首选项 >; Java >; 代码生成 >; 代码和注释
*/
public class TestKill {
        private JFrame f;
        public static void main(String[] args) {
                TestKill t=new TestKill();
               
               
        }
        public TestKill(){
                JButton bt1;
                JButton bt2;
                bt1=new JButton("bt1";
                bt2=new JButton("bt2";
                bt1.addActionListener(new ActionListener(){                       
                        public void actionPerformed(ActionEvent e) {
                                // TODO 自动生成方法存根
                                new Thread(){
                                        public void run(){
                                                while(true){
                                                        try {
                                                                Thread.sleep(1000);
                                                        } catch (InterruptedException e1) {
                                                                // TODO 自动生成 catch 块
                                                                e1.printStackTrace();
                                                        }
                                                }
                                        }
                               
                                }.start();
                               
                        }
                });
                f =new JFrame();
                f.addWindowListener(new WindowListener(){

                        public void windowOpened(WindowEvent e) {
                                // TODO 自动生成方法存根
                               
                        }

                        public void windowClosing(WindowEvent e) {
                                // TODO 自动生成方法存根
                                System.exit(0);
                        }

                        public void windowClosed(WindowEvent e) {
                                // TODO 自动生成方法存根
                               
                        }

                        public void windowIconified(WindowEvent e) {
                                // TODO 自动生成方法存根
                               
                        }

                        public void windowDeiconified(WindowEvent e) {
                                // TODO 自动生成方法存根
                               
                        }

                        public void windowActivated(WindowEvent e) {
                                // TODO 自动生成方法存根
                               
                        }

                        public void windowDeactivated(WindowEvent e) {
                                // TODO 自动生成方法存根
                               
                        }
                       
                });
                f.getContentPane().setLayout(new FlowLayout());
                f.getContentPane().add(bt1);
                f.getContentPane().add(bt2);
                f.pack();
                f.setVisible(true);
               
        }
}

论坛徽章:
0
7 [报告]
发表于 2004-10-14 19:21 |只看该作者

事件触发不了

这时是关不了窗口的
必须先把那个线程kill掉
要不这样吧
你试试把你的监听代码放到另外一个进程中
使用多线程可以解决这个问题

论坛徽章:
0
6 [报告]
发表于 2004-10-14 19:17 |只看该作者

事件触发不了

[quote]原帖由 "gazania"]SSLSocket的accept方法以及while循环应该放在线程中,否则UI会被挂起,关闭程序的按钮不起作用。[/quote 发表:
是吗,这是什么原理,如果单独放在一个现成中,那么主程序结束,那个现成也不会结束吧.除非是守护现成.

论坛徽章:
0
5 [报告]
发表于 2004-10-14 19:02 |只看该作者

事件触发不了

首先你得定义关闭程序的事件,以及该事件的Handler。其次,SSLSocket的accept方法以及while循环应该放在线程中,否则UI会被挂起,关闭程序的按钮不起作用。

论坛徽章:
0
4 [报告]
发表于 2004-10-14 18:53 |只看该作者

事件触发不了

设置窗口关闭的事件了吗?
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP