事件触发不了

时间:2008-01-16 12:57:52  来源:  作者:

做了一个界面,包括确定和取消两个按钮,确定触发的事件是:
SSLServerSocket listen = new SSLServerSocket(ctx, port);
        while (true) {
          SSLSocket s = (SSLSocket) listen.accept();
         }
希望取消可以触发中断上述连接,现在出现了这样一个问题:
一旦按下按钮”确定“,可以正确执行上述代码,但是按下”取消“或者右上角那个关闭”X“,都没有用,无法中断程序,除非使用任务管理器来结束程序。请赐教,不胜感激



 demon-duke 回复于:2004-10-14 16:51:00

这个不是事件触发不了的问题
而是那个事件处理线程没法被kill的问题


 jerryzhu863 回复于:2004-10-14 18:48:14

那我应该怎样kill


 镖师甲 回复于:2004-10-14 18:53:09

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


 gazania 回复于:2004-10-14 19:02:33

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


 镖师甲 回复于:2004-10-14 19:17:11

引用:原帖由 "gazania"]SSLSocket的accept方法以及while循环应该放在线程中,否则UI会被挂起,关闭程序的按钮不起作用。
 发表:

 是吗,这是什么原理,如果单独放在一个现成中,那么主程序结束,那个现成也不会结束吧.除非是守护现成.


 demon-duke 回复于:2004-10-14 19:21:24

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


 demon-duke 回复于:2004-10-14 19:26:06

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

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);

}
}


 demon-duke 回复于:2004-10-14 19:28:18

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


 jerryzhu863 回复于:2004-10-14 19:51:20

谢谢大家。 :oops:


 demon-duke 回复于:2004-10-14 20:34:27

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


 perryhg 回复于:2004-10-15 04:26:38

典型的阻塞问题。

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

public class MyClass extends Thread{

    public boolean keepRunning;
    
    /** Creates a new instance of MyClass */
    public MyClass() {
        keepRunning = true;
    }
    
    public void run()
    {
        Socket s;
        while(keepRunning)
        {
            s = serversocket.accept();
            //如果没有连接,这里的代码无法被执行
            ....
            ....
        }
    }

    public void stopThread()
    {
        this.keepRunning = false;
    }
}


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

public class MyClass extends Thread{

    public boolean keepRunning;
    public Socket serversocket;
    
    /** Creates a new instance of MyClass */
    public MyClass(ServerSocket ssocket) {
        keepRunning = true;
        serversocket = ssocket;
    }
    
    public void run()
    {
        Socket s;
        while(keepRunning)
        {
            try{
                s = serversocket.accept();
                //....
                //.....
            }catch(...){
                //...
            }finally{
                //清理资源
            }
        }
    }
    
    public void stopThread()
    {
        try{
            keepRunning = false;
            serversocket.stop();
        }catch(){
            
        }finally{
            
        }
    }
}


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




原文链接:http://bbs.chinaunix.net/viewthread.php?tid=425026
转载请注明作者名及原文出处


文章评论

共有 位网友发表了评论 查看完整内容