sunfruit[请访问http://www.fruitres.cn]

--我相信JAVA能走得更远 QQ:316228067

#

[原创]JAVA编写的使用手机串口发送短信的程序

    --sunfruit

    用JAVA编写的使用手机串口发送短信的程序

    功能简介:
        手机通过串口与电脑连接以后,就可以使用该程序发送短信
        如果是红外连接那么可以使用红外模拟串口的软件进行转换即可
        红外模拟串口的软件下载地址http://heart5.chinap4.com/moto388/connect/ircomm2k/download.html
    欢迎大家提意见,交流

   可以直接运行的程序下载地址,环境配置参考包中的txt
   http://www.blogjava.net/Files/sunfruit/comm.rar

    源代码下载地址
    http://www.blogjava.net/Files/sunfruit/comm_src.rar

posted @ 2006-02-19 18:08 sunfruit 阅读(5564) | 评论 (52)编辑 收藏

[经验]JAVA验证字符串转换为日期的合法性

    --sunfruit

    在处理日期的格式转换的时候总结些经验,和大家分享,如下:

       String  text  ="1996-2-1";
       Date  d  =  null; 
       SimpleDateFormat  df  =  new  SimpleDateFormat("yyyy-MM-dd"); 
       df.setLenient(false);//这个的功能是不把1996-13-3 转换为1997-1-3
        try
       { 
         d  =  df.parse(text); 
       }
       catch(Exception  e)
       { 
         d=new  Date();
         System.out.println("你输入的日期不合法,请重新输入"); 
       } 
       String sdata=df.format(d);
       System.out.println(sdata);
    
      这样输入1996-2-31这样的数据也会验证出来错误的,但是前提是要设置Lenient为false

posted @ 2006-02-19 18:07 sunfruit 阅读(2925) | 评论 (4)编辑 收藏

[原创]java的数据库基类--提供了灵活连接方式和多种的update语句

    --sunfruit

    用JAVA实现了数据库基类

    JDK版本
        JDK1.4.x
    功能
        实现了灵活的连接数据库或数据库连接池
        提供了update的多种方式
        现在提供的有DriverClass和DriverClassTomcat,分别是直接连接和tomcat连接池连接
        可以继续写出DriverClassWeblogic等其他的连接方式方到自己指定的地方,然后修改那个xml的class参数就可以了
        修改连接方式的时候无需修改代码
   
    欢迎大家提意见,交流

    代码下载
    http://sunfruit.blogchina.com/inc/database.rar

posted @ 2006-02-19 18:06 sunfruit 阅读(216) | 评论 (0)编辑 收藏

用Java事件处理机制实现录制回放功能

    --sunfruit

   

用Java事件处理机制实现录制回放功能

目前在一些java应用程序的GUI测试工具,可以提供捕获用户操作的能力并在代码被修改之后能够自动回放用户的操作。文章将分析Java的事件 处理模型及其原理,介绍了基于事件源识别的捕获/回放所需要了解的关键技术并给出了两种实现方式。

  1、 Java事件介绍

  1.1什么是事件

  首先我们来回答"什么是事件"这一基本问题。其实事件本身就是一个抽象的概念,他是表现另一对象状态变化的对象。在面向 对象的程序设计中,事件消息是对象间通信的基本方式。在图形用户界面程序中,GUI组件对象根据用户的交互产生各种类型的事件消息,这些 事件消息由应用程序的事件处理代码捕获,在进行相应的处理后驱动消息响应对象做出反应。我们在GUI上进行叫化操作的时候,在点击某个可 响应的对象时如,按钮,菜单,我们都会期待某个事件的发生。其实围绕GUI的所有活动都会发生事件,但Java事件处理机制却可以让您挑选出 您需要处理的事件。事件在Java中和其他对象基本是一样的,但有一点不同的是,事件是由系统自动生成自动传递到适当的事件处理程序。

  1.2Java事件处理的演变

  当java的开发者开始解决用java创建应用程序这一问题时,他们就认识到java事件模型的必要性。下面对java事件处理的发展做简要的概 括。

  在JDK1.0的版本采用用的事件模型,提供了基本的事件处理功能。这是一种包容模型,所有事件都封装在单一的类Event中,所有事件 对象都由单一的方法handleEvent来处理,这些定义都在Component类中。为此,只有Component类的子类才能充当事件处理程序,事件处理传递 到组件层次结构,如果目标组件不能完全处理事件,事件被传递到目标组件的容器。

  JDK1.1是编程界的一次革命,修正了前面版本的一些缺陷,同时增加了一些重要的新功能如,RMI、JNI、JDBC、JavaBean。在事件模型 上基本框架完全重写,并从Java1.0模型迁移到委托事件模型,在委托模型中事件源生成事件,然后事件处理委托给另一段代码。

  从JDK1.2开始,引入了Swing包事件处理模型功能更强大,更加可定制GUI组件与他们相关联的支持类。在后面的版本基本保持了整个事 件模型,但加入了一些附加事件类和接口。在1.3版本开始引入Rebot类,它能模拟鼠标和键盘事件,并用于自动化测试、自动运行演示、以及 其他要求鼠标和键盘控制的应用程序。

  我们把JDK1.0事件处理模型成为java 1.0事件模型,而从jdk1.1后的版本事件处理模型称为Java 2事件处理模型。

  2、 Java 2事件处理模型

  在Java1.0事件处理模型中事件处理是以如下方法执行的。deliverEvent()用于决定事件的目标,目标是处理事件的组件或容器,此过程 开始于GUI层的最外部而向内运作。当按一个button时,如果检测到是该按钮激发的事件,该按钮会访问它的deliverEvent()方法,这一操作由 系统完成。一旦识别目标组件,正确事件类型发往组件的postEvent()方法,该方法依次把事件送到handleEvent()方法并且等待方法的返回值 。"true"表明事件完全处理,"false"将使postEvent()方法联系目标容器,希望完成事件处理。

  下面给一个实例:

 
  import java.applet.*; 
  import java.awt.*; 
   
  public class Button1Applet extends Applet{ 
     public void init(){ 
   add(new Button("Red")); 
   add(new Button("Blue")); 
} 
public boolean action(Enent evt,Object whatAction){ 
    if( !( evt.target  instanceof  Button))return false; 
 String buttonlabel=(String)whatAction; 
 if(buttonlabel=="Red")setBackground(Color.red); 
 if(buttonlabel==" Blue")setBackground(Color.blue); 
 repaint(); 
return true; 
} 

} 

  在Java2处理事件时,没有采用dispatchEvent()-postEvent()-handleEvent()方式,采用了监听器类,每个事件类都有相关联的监听器 接口。事件从事件源到监听者的传递是通过对目标监听者对象的Java方法调用进行的。

  对每个明确的事件的发生,都相应地定义一个明确的Java方法。这些方法都集中定义在事件监听者(EventListener)接口中,这个接 口要继承java.util.EventListener。 实现了事件监听者接口中一些或全部方法的类就是事件监听者。 伴随着事件的发生,相应的状态通常都封装在事件状态对象中,该对象必须继承自java.util.EventObject。事件状态对象作为单参传递给应响 应该事件的监听者方法中。 发出某种特定事件的事件源的标识是:遵从规定的设计格式为事件监听者定义注册方法,并接受对指定事件监听者接口实例的引用。 有时,事件监听者不能直接实现事件监听者接口,或者还有其它的额外动作时,就要在一个源与其它一个或多个监听者之间插入一个事件适配 器类的实例,来建立它们之间的联系。

  我们来看下面一个简单的实例:

 
import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class SimpleExample extends JFrame { 
  JButton jButton1 = new JButton(); 

  public SimpleExample() { 
    try { 
      jbInit(); 
    } 
    catch(Exception e) { 
      e.printStackTrace(); 
    } 
  } 
  public static void main(String[] args) { 
    SimpleExample simpleExample = new SimpleExample(); 
  } 
  private void jbInit() throws Exception { 
    jButton1.setText("jButton1"); 
    jButton1.addActionListener(new SimpleExample_jButton1_actionAdapter(this)); 
    jButton1.addActionListener(new SimpleExample_jButton1_actionAdapter(this)); 
    this.getContentPane().add(jButton1, BorderLayout.CENTER); 
  this.setVisible(true);  
  } 

  void jButton1_actionPerformed(ActionEvent e) { 
    System.exit(0); 
  } 
} 

class SimpleExample_jButton1_actionAdapter implements java.awt.event.ActionListener { 
  SimpleExample adaptee; 

  SimpleExample_jButton1_actionAdapter(SimpleExample adaptee) { 
    this.adaptee = adaptee; 
  } 
  public void actionPerformed(ActionEvent e) { 
    adaptee.jButton1_actionPerformed(e); 
  } 
} 
 

3、 事件捕获与回放

 

  3.1 Java事件生命周期

  Java事件和万事一样有其生命周期,会出生也会消亡。下图3.1给出了Java事件生命周期的示意图,

  事件最初由事件源产生,事件源可以是GUI组件Java Bean或由生成事件能力的对象,在GUI组件情况下,事件源或者是组件的同位体( 对于Abstract Window Toolkit[awt]GUI组件来说)或组件本身(对于Swing组件来说)。事件生成后放在系统事件队列内部。现在事件处于事件分发线程的控 制下。事件在队列中等待处理,然后事件从事件队列中选出,送到dispatchEvent()方法,dispatchEvent()方法调用processEvent()方法并将 事件的一个引用传递给processEvent()方法。此刻,系统会查看是否有送出事件的位置,如果没有这种事件类型相应的已经注册的监听器,或 者如果没有任何组件受到激活来接收事件类型,事件就被抛弃。当然上图显示的是AWTEvent类的子类的生命周期。dispatchEvent()方法和proc essEvent()方法把AWTEvent作为一个参数。但对,javax.swing.event并不是AWTEvent子类,而是从EventObject直接继承过来,生成这些事件 的对象也会定义fireEvent()方法,此方法将事件送到包含在对象监听器列表内的那种类型的任何监听器。

  3.2 Java事件捕获

  从上面的分析我们知道,任何事件产生到dispatchEvent()方法分发方法前,所有的事件都是存放在系统事件的队列中,而且所有的事件都 由dispatchEvent()方法来分派。所以只要能重载dispatchEvent()方法就可以获取系统的所有事件,包括用户输入事件。一般来说,系统事件 队列的操作对用户来说是可以控制。它在后台自动完成所要完成的事情,使用EventQueue类可以查看甚至操纵系统事件队列。

  Java提供了EventQueue类来访问甚至操纵系统事件队列。EventQueue类中封装了对系统事件队列的各种操作,除dispatchEvent()方法 外,其中最关键的是提供了push()方法,允许用特定的EventQueue来代替当前的EventQueue。只要从EventQueue类中派生一个新类,然后通过p ush()方法用派生类来代替当前的EventQueue类即可。这样,所有的系统事件都会转发到派生EventQueue类。然后,再在派生类中重载dispatch Event()方法就可以截获所有的系统事件,包括用户输入事件。下面一段代码给出一个操纵EventQueue的实例:

 
import java.awt.*; 
import java.awt.event.*; 

public class GenerateEventQueue extends Frame implements ActionListener{ 
  Button button1 = new Button(); 
  TextField textField1 = new TextField(); 

  public GenerateEventQueue() { 
    try { 
      jbInit(); 
    } 
    catch(Exception e) { 
      e.printStackTrace(); 
    } 
  } 
  public static void main(String[] args) { 
    GenerateEventQueue generateEventQueue = new GenerateEventQueue(); 
  } 
  private void jbInit() throws Exception { 
    button1.setLabel("button1"); 
    button1.addActionListener(this) ; 
    textField1.setText("textField1"); 

    this.add(button1, BorderLayout.SOUTH); 
    this.add(textField1, BorderLayout.CENTER); 
    EventQueue eq=getToolkit().getSystemEventQueue() ; 
    eq.postEvent(new ActionEvent(button1,ActionEvent.ACTION_PERFORMED,"test" )) ; 
    addWindowListener(new WinListener()); 
    setBounds(100,100,300,200); 
    setVisible(true); 
  } 

  public void actionPerformed(ActionEvent e) { 
    textField1.setText("event is :"+e.getActionCommand()) ; 
  } 

} 

class WinListener extends WindowAdapter{ 
  public void windowClosing(WindowEvent we){ 
    System.exit(0) ; 
  } 
} 

  运行结果如下图所示:

  在文本域中首先出现的是"event is :test",这是因为首先得到处理的是EventQueue对象发送到系统事件队列上的ActionEvent。

  下面的代码简单说明了如何捕获事件:

 
  import java.awt.EventQueue; 
import java.awt.*; 
import java.util.*; 
public class MyQueueEvent extends EventQueue {//定义EventQueue的子类 
  public MyQueueEvent() { 
  } 
  public static void main(String[] args) { 
    SimpleExample.main(new String[]{null}) ; 
    MyQueueEvent myQueueEvent1 = new MyQueueEvent(); 
    Toolkit.getDefaultToolkit().getSystemEventQueue().push(myQueueEvent1) ; 
  } 
//在这里重载事件分发的方法 
  public void dispatchEvent(AWTEvent ae){ 
     
    if(ae.getSource() instanceof javax.swing.JButton) 
    System.out.println("My apture:"+((javax.swing.JButton)ae.getSource()).getText()) ; 
    super.dispatchEvent(ae); 
  } 
  

  这个程序可以打印出当前应用的所有的事件,可以将这些事件中选出你需要的事件保存当然你还需要解析该控件的特征。在上面加黑部 分的代码,打印事件源控件的名称。

  除此之外,还可以通过实现java.awt.event. AWTEventListener接口实现对事件的捕获。这个侦听器接口可以接收Component or MenuComponent 以及它们的派生类在整个系统范围内所分发的事件,AWTEventListeners只是被动的监控这些事件。如果要监控系统事件,除了要实现接口,还 要用Toolkit的addAWTEventListener方法注册这个侦听器。

  下面我们来看一个实例:

 
import java.awt.AWTEvent; 
import java.awt.Frame; 
import java.awt.Toolkit; 
import java.awt.Window; 
import java.awt.event.AWTEventListener; 
import java.awt.event.WindowEvent; 

import java.util.ArrayList; 
import java.lang.ref.WeakReference; 
public class MyAWTEventListener implements AWTEventListener{ 
  private  static MyAWTEventListener s_singleton = null;//保证该类只被初始化一次 
  public static MyAWTEventListener getInstance(){ 
    if(s_singleton==null){ 
     s_singleton=new MyAWTEventListener(); 
    } 
    return s_singleton; 
  } 
  private MyAWTEventListener(){ 
    //注意下面这行代码,如果没有这行代码,将无法接收到系统分发的事件 
    // 下面代码在注册时,只请求了接收WINDOW_EVENT_MASK事件 
   //但实际上,你可以接收其他AWTEvent中定义的事件类型 
Toolkit.getDefaultToolkit().addAWTEventListener(this, 
        AWTEvent.COMPONENT_EVENT_MASK 
); 
  } 
  /* 
     这就是接口方法的实现 
*/ 
public void eventDispatched(final AWTEvent theEvent) { 
        processEvent(theEvent); 
  } 
  private static void processEvent(final AWTEvent theEvent) { 
        System.out.println(theEvent.getSource() ) ;//打印事件源 
    switch (theEvent.getID()) { 
        case WindowEvent.WINDOW_OPENED: 
          //System.out.println(((Frame)theEvent.getSource()).getTitle() ) ; 
        case WindowEvent.WINDOW_ACTIVATED: 
        case WindowEvent.WINDOW_DEACTIVATED: 
        case WindowEvent.WINDOW_CLOSING: 
        default: break; 
        } 
    } 
} 
3.3 Java事件回放

  事件的回放其实比较简单了,比如我们现在记录的是frame1下的jButton1点击事件回放。看下面一段简单的程序,只要点一下jButton1, 就在控制台打印一次"click me"的字符串。

 
import java.awt.*; 
import javax.swing.*; 
import java.awt.event.*; 

public class Frame1 extends JFrame { 
  private JButton jButton1 = new JButton(); 

  public Frame1() { 
    try { 
      jbInit(); 
    } 
    catch(Exception e) { 
      e.printStackTrace(); 
    } 
  } 
  public static void main(String[] args) { 
    Frame1 frame1 = new Frame1(); 
frame1.setVisible(true) ; 

  } 
  private void jbInit() throws Exception { 
    jButton1.setText("jButton1"); 
    jButton1.addActionListener(new java.awt.event.ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
        jButton1_actionPerformed(e); 
      } 
    }); 
    this.setTitle("Test"); 
    this.getContentPane().add(jButton1, BorderLayout.CENTER); 
  } 

  void jButton1_actionPerformed(ActionEvent e) { 
    System.out.println("click me") ; 
  } 
} 

  下面是回放的程序,在下面的程序中用到了java.awt.Robot类,这个类通常用来在自动化测试或程序演示中模拟系统事件,在某些需要 控制鼠标或键盘的应用程序中这个类也是很有用,这个类主要的目的就是为方便的实现java的GUI自动化测试平台。在事件回放时,我们同样需 要该类来模拟生成系统的事件,完成记录的操作的回放,在下面的代码中,给出了一个简单的例子。

 
import java.awt.*; 
import javax.swing.*; 
import java.awt.event.*; 
public class TestReplay extends Thread{ 
  public static void main(String[] args) { 
    try{ 
      //启动要回放的应用程序 
      Frame1.main(new String[]{null}) ; 
   //等应用程序启动后延迟3秒再进行回放 
      Thread.currentThread().sleep(3000) ; 
      Robot robottest=new Robot(); 
      robottest.waitForIdle(); 
      //根据标题名获取当前应用的主窗体,在本例中为"test" 
      Frame jframe=getFrame("test");; 
     //根据给定的窗体和窗体中要find的控件的名称来获取控件的引用    
JButton jbtn=getButton(jframe,"jButton1"); 
//将鼠标移到控件所在的位置 
      robottest.mouseMove(jbtn.getLocationOnScreen().x+jbtn.getWidth()/2 
   ,jbtn.getLocationOnScreen().y+jbtn.getHeight()/2) ; 
  //在控件所在位置,生成鼠标点击事件 
      robottest.mousePress(InputEvent.BUTTON1_MASK ) ; 
      robottest.mouseRelease(InputEvent.BUTTON1_MASK ) ; 
    }catch(Exception ee){ 
      ee.printStackTrace() ; 
    } 
  } 
  //获得标题为title的frame 
  private static Frame getFrame(String title){ 
    Frame[] jframes=(Frame[])JFrame.getFrames(); 
    for(int i=0;i<jframes.length ;i++){ 
      if(jframes[i].getTitle().equalsIgnoreCase(title))return jframes[i]; 
    } 
    return null; 

  } 
  //获取某一个frame下的某个名为jButton1的控件 
  private static JButton getButton(Frame jf,String text){ 
/*注意下面这行代码,因为实例比较简单只有ContentPane一个Container类型的控件, 
如果在JFrame中有多个Container控件//的话,必须进行递归处理,搜索出所有的控件 
*/ 
    Component[] coms=((JFrame)jf).getContentPane().getComponents(); 
    for(int i=0;i<coms.length ;i++){ 
      if(!(coms[i] instanceof JButton))continue; 
      if(((JButton)coms[i]).getText().equalsIgnoreCase(text))return (JButton)coms[i]; 
    } 
    return null; 
  } 
  public void run(){ 

  } 
} 

  该程序运行完,你会发现在控制台同样打印出了:

  "click me"的字符串说明事件被正确回放了。

  当然还可以通过直接操纵系统事件队列实现输入事件的回放。先通过记录下的窗口/组件名获得对应窗口引用,然后重构鼠标/键盘事件 ,最后将重构的事件直接放入系统事件队列,由分派线程执行后续的事件分派工作。还需要解决关键问题如何能根据窗口名称获得其引用。这 里还是可以通过系统事件队列来实现的,因为Java程序在新建/删除一个容器时都会向系统事件队列发出一个Containerevent事件,其中包含了 对该容器的引用。所以,事件回放器在载入被测测试程序后便监视系统队列,截获所有的Containerevent事件。如果新建容器,便获得新建Con tainer的引用。因为所有的Container都实现了getComponets(),可以返回所有该容器所包含的组件或容器,只需要保存到一个HashMap结构中 ,需要时检索出来就可以了。该过程所用到的知识,其实在上面都有提到而且在实际引用中,既然Robot已经帮我们完成许多事情,也没有必要 自己再去重构一个鼠标或键盘事件了,不过有兴趣的朋友也可以去试试。

  4、 结束语

  随着我国软件业的发展,软件测试技术作为软件质量保证的重要环节越来越受到重视,而在基于GUI的应用中采用自动化测试工具可以提高 软件测试的有效性和效率,特别在回归测试中可以大大减少人力投入,还可以提高测试脚本的复用。因此,软件自动测试平台开发已经成为软 件测试的一个重要领域。本文介绍了基于Java的GUI应用的自动测试平台开发需要的基本但关键的捕获、回放功能,所有相关系统开发其实都离 不开本文说的方法。

posted @ 2006-02-19 18:06 sunfruit 阅读(319) | 评论 (0)编辑 收藏

[原创]JAVA数据加密解密的实例

    --sunfruit

    关于加密解密的理论知识已经不少了,这里只给出一个加密解密以及生成key的源代码,给大家参考

    源代码下载地址:
        http://sunfruit.blogchina.com/inc/des.rar

posted @ 2006-02-19 18:05 sunfruit 阅读(2557) | 评论 (4)编辑 收藏

[原创]JAVA读取文件或是数据流的源代码--涵盖了多种形式

    --sunfruit

    java读取文件或是文件流的代码,涵盖了读取jar文件中的文件流,网络文件流等,有些读取方式为了防止编码转换带来的问题,采取了动态byte[]的方式读取,源码如下

import java.io.BufferedInputStream;
import java.io.File;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Util {

  public Util() {
  }
  /**
   * 读取源文件内容
   * @param filename String 文件路径
   * @throws IOException
   * @return byte[] 文件内容
   */
  public static byte[] readFile(String filename) throws IOException {

    File file =new File(filename);
    if(filename==null || filename.equals(""))
    {
      throw new NullPointerException("无效的文件路径");
    }
    long len = file.length();
    byte[] bytes = new byte[(int)len];

    BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream(file));
    int r = bufferedInputStream.read( bytes );
    if (r != len)
      throw new IOException("读取文件不正确");
    bufferedInputStream.close();

    return bytes;

  }

  /**
   * 将数据写入文件
   * @param data byte[]
   * @throws IOException
   */
  public static void writeFile(byte[] data,String filename) throws IOException {
    File file =new File(filename);
    file.getParentFile().mkdirs();
    BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(new FileOutputStream(file));
    bufferedOutputStream.write(data);
    bufferedOutputStream.close();

  }

  /**
   * 从jar文件里读取class
   * @param filename String
   * @throws IOException
   * @return byte[]
   */
  public byte[] readFileJar(String filename) throws IOException {
    BufferedInputStream bufferedInputStream=new BufferedInputStream(getClass().getResource(filename).openStream());
    int len=bufferedInputStream.available();
    byte[] bytes=new byte[len];
    int r=bufferedInputStream.read(bytes);
    if(len!=r)
    {
      bytes=null;
      throw new IOException("读取文件不正确");
    }
    bufferedInputStream.close();
    return bytes;
  }
 
  /**
   * 读取网络流,为了防止中文的问题,在读取过程中没有进行编码转换,而且采取了动态的byte[]的方式获得所有的byte返回
   * @param bufferedInputStream BufferedInputStream
   * @throws IOException
   * @return byte[]
   */
  public byte[] readUrlStream(BufferedInputStream bufferedInputStream) throws IOException {
    byte[] bytes = new byte[100];
    byte[] bytecount=null;
    int n=0;
    int ilength=0;
    while((n=bufferedInputStream.read(bytes))>=0)
    {
      if(bytecount!=null)
        ilength=bytecount.length;
      byte[] tempbyte=new byte[ilength+n];
      if(bytecount!=null)
      {
        System.arraycopy(bytecount,0,tempbyte,0,ilength);
      }

      System.arraycopy(bytes,0,tempbyte,ilength,n);
      bytecount=tempbyte;

      if(n<bytes.length)
        break;
    }
    return bytecount;
  }

}

posted @ 2006-02-19 18:04 sunfruit 阅读(6058) | 评论 (1)编辑 收藏

[原创]用JAVAMAIL发送邮件的一个简单例子

    --sunfruit

    写了一个收发邮件的应用程序[在列表里面可以看到]但是毕竟有些复杂,关键部分其实也就是几行代码,为了大家使用方便,我把发送邮件的代码单独拿了出来,并且分为发送附件/不发送附件两个方法,便于大家查看,只是什么设计啦,编程思想啦,等等就谈不到了,呵呵,大家将就吧

    JDK版本
        1.4.x
    其   他
        JAVAMAIL相关包
    功能简介:
        简单的邮件发送功能,可以发送附件

    源代码如下

import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
import java.util.*;
import java.util.*;
import java.text.*;
import java.io.*;
public class SendMail
{
    //传入的参数有密码、姓名、谁发、发给谁、主题、正文内容、smtp地址、附件文件路径、附件的新文件名、发送类型(text/html)
    //发送邮件主函数
    public String sendmail(int myport,String password,String username,String myfrom,String myto,String mysubject,String mytext,String mysmtp,String[] filepath,String[] newfilename,String htmlandtext)
    {
            try{
                int indexstr=0;
                if (filepath[0]!=null && !filepath[0].equals(""))
                    indexstr=1;
                    //替换字符串
               //     jbemail myjbemail=new jbemail();
               //     filepath=myjbemail.myreplace(filepath,"\\","\\\\");
               //     System.out.println("附件地址"+filepath+"服务器地址"+mysmtp+mysmtp.length());
                    //Properties props = new Properties();
                Properties props = System.getProperties();
                Session sendMailSession;
                Store store;  //收邮件时使用
                Transport transport;//发邮件时使用
                props.put("mail.smtp.host",mysmtp);
                props.put("mail.smtp.auth","true");
                SmtpAuthenticator sa=new SmtpAuthenticator(username,password);
                sendMailSession = Session.getInstance(props,sa);
                //sendMailSession = Session.getInstance(props,null);
                sendMailSession.setDebug(true);

                MimeMessage newMessage = new MimeMessage(sendMailSession);
                newMessage.setFrom(new InternetAddress(myfrom));
                newMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(myto));
                //设定邮件格式
                newMessage.setSentDate(new Date());
                System.out.println(htmlandtext+"邮件正文格式");
                Multipart multipart = new MimeMultipart();
                if (htmlandtext.equals("text"))
                {
                    //获得文本格式的邮件

                    newMessage.setSubject(mysubject);
                    BodyPart messageBodyPart = new MimeBodyPart();
                    messageBodyPart.setText(mytext);
                    multipart.addBodyPart(messageBodyPart);
                }
                else if(htmlandtext.equals("html"))
                {
                    //设置邮件内容,将邮件body部分转化为HTML格式
                    newMessage.setSubject(mysubject,"gb2312");
                    BodyPart messageBodyPart = new MimeBodyPart();
                    messageBodyPart.setDataHandler(new DataHandler(mytext,"text/html;charset=gb2312"));
                    multipart.addBodyPart(messageBodyPart);
                }
                if (indexstr>0)
                {

                    for(int i=0;i                    {
                        if (newfilename[i]!=null)
                        {
                            //创建BodyPart对象以便获得附件
                            BodyPart messageBodyPart = new MimeBodyPart();
                            System.out.println("附件地址"+filepath[i]);
                            DataSource source = new FileDataSource(filepath[i]);
                            messageBodyPart.setDataHandler(new DataHandler(source));
                            messageBodyPart.setFileName(newfilename[i]);
                            multipart.addBodyPart(messageBodyPart);
                        }
                    }
                }
                //将正文和附件添加到邮件中
                newMessage.setContent(multipart);
                newMessage.saveChanges();
                //transport = sendMailSession.getStore("pop3");
                transport = sendMailSession.getTransport("smtp");
                transport.connect(mysmtp,myport,username,password);
                //transport.connect();
                transport.send(newMessage,newMessage.getAllRecipients());
                System.out.println("成功发送到"+myto);
                return "ok";
        }
        catch(MessagingException m)
        {
                System.out.println(m.toString()+"失败");
                return myto;
        }
    }
    //不含发送附件的函数
    //传入的参数有port地址、密码、姓名、谁发、发给谁、主题、正文内容、smtp地址、发送类型(text/html)
    public String sendmail(String mailPathlog,int myport,String password,String username,String myfrom,String myto,String mysubject,String mytext,String mysmtp,String htmlandtext)
    {
            try{
                //解码
                mysubject=java.net.URLDecoder.decode(mysubject);
                    //Properties props = new Properties();
                Properties props = System.getProperties();
                Session sendMailSession;
                Store store;  //收邮件时使用
                Transport transport;//发邮件时使用
                props.put("mail.smtp.host",mysmtp);
                props.put("mail.smtp.auth","true");
                SmtpAuthenticator sa=new SmtpAuthenticator(username,password);
                //身份验证
                sendMailSession = Session.getInstance(props,sa);
                //sendMailSession = Session.getInstance(props,null);
                sendMailSession.setDebug(true);
                MimeMessage newMessage = new MimeMessage(sendMailSession);
                try
                {
                  newMessage.setFrom(new InternetAddress(myfrom,"法律之星"));
                  newMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(myto));
                }
                catch(java.io.UnsupportedEncodingException ex)
                {
                   System.out.println(ex.toString());
                }
                //设定邮件格式
                newMessage.setSentDate(new Date());
                System.out.println(htmlandtext+"邮件正文格式");
                Multipart multipart = new MimeMultipart();
                if (htmlandtext.equals("text"))
                {
                    //获得文本格式的邮件

                    newMessage.setSubject(mysubject);
                    BodyPart messageBodyPart = new MimeBodyPart();
                    messageBodyPart.setText(mytext);
                    multipart.addBodyPart(messageBodyPart);
                }
                else if(htmlandtext.equals("html"))
                {
                    //设置邮件内容,将邮件body部分转化为HTML格式
                    newMessage.setSubject(mysubject,"gb2312");
                    BodyPart messageBodyPart = new MimeBodyPart();
                    messageBodyPart.setDataHandler(new DataHandler(mytext,"text/html;charset=gb2312"));
                    multipart.addBodyPart(messageBodyPart);
                }
                //将正文添加到邮件中
                newMessage.setContent(multipart);
                newMessage.saveChanges();
                //transport = sendMailSession.getStore("pop3");
                transport = sendMailSession.getTransport("smtp");
                transport.connect(mysmtp,myport,username,password);
                //transport.connect();
                transport.send(newMessage,newMessage.getAllRecipients());
                System.out.println("成功发送到"+myto+mytext);
                return "ok";
        }
        catch(MessagingException m)
        {
                System.out.println(m.toString()+"失败");
                //生成当前日期
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                Date dateTime= new Date();
                String sDateTime=dateFormat.format(dateTime);
                //生成日志文件
                try
                {
                    File filelog=new File(mailPathlog+"\\"+"mainlog.txt");
                    BufferedWriter out2=new BufferedWriter(new FileWriter(filelog.getPath(),true));
                    String newline = System.getProperty("line.separator");
                    out2.write(sDateTime+"/"+mysmtp+"/"+myfrom+"/"+myto+"/"+m.toString()+"/"+newline);
                    out2.close();
                }
                catch (IOException ex)
                {
                    System.out.println(ex.toString());
                }
                return myto;
        }
    }
    class SmtpAuthenticator extends Authenticator
    {
        //SMTP身份验证
        public SmtpAuthenticator(String username,String password)
        {
            this.username=username;
            this.password=password;
        }
        public PasswordAuthentication getPasswordAuthentication()
        {
            return new  PasswordAuthentication(this.username,this.password);
        }
        String username=null;
        String password=null;
    }
}

posted @ 2006-02-19 18:03 sunfruit 阅读(1788) | 评论 (4)编辑 收藏

[原创]JAVA用户自定义事件监听完整例子

    --sunfruit

    很多介绍用户自定义事件都没有例子,或是例子不全,下面写了一个完整的例子,并写入了注释以便参考,完整的实例源代码如下:

package demo;

import java.util.EventObject;

/**
 * Title: 事件处理类,继承了事件基类
 * Description: 
 * Copyright: Copyright (c) 2005
 * Company: cuijiang
 * @author not attributable
 * @version 1.0
 */
public class DemoEvent extends EventObject
{
  private Object obj;
  private String sName;
  public DemoEvent(Object source,String sName)  {
    super(source);
    obj = source;
    this.sName=sName;
  }
  public Object getSource()
  {
    return obj;
  }
  public void say()
  {
    System.out.println("这个是 say 方法...");
  }

  public String getName()
  {
    return sName;
  }
}

package demo;

import java.util.EventListener;

/**
 * Title: 监听器接口
 * Description: 
 * Copyright: Copyright (c) 2005
 * Company: cuijiang
 * @author not attributable
 * @version 1.0
 */
public interface DemoListener extends EventListener{
  public void demoEvent(DemoEvent dm);
}

package demo;

import java.util.*;

/**
 *Title: 使用事件的类
 * Description: 该类实现了监听器的添加和监听器方法的执行,并且实现了由于属性的改变而执行事件
 * Description: 在添加、删除、执行监听器的时候都要注意同步问题
 * Copyright: Copyright (c) 2005
 * Company: cuijiang
 * @author not attributable
 * @version 1.0
 */
public class DemoSource{
  private Vector repository = new Vector();
  private DemoListener dl;
  private String sName="";

  public DemoSource()
  {
  }

  //注册监听器,如果这里没有使用Vector而是使用ArrayList那么要注意同步问题
  public void addDemoListener(DemoListener dl)
  {
    repository.addElement(dl);//这步要注意同步问题
  }

  //如果这里没有使用Vector而是使用ArrayList那么要注意同步问题
  public void notifyDemoEvent(DemoEvent event) {
    Enumeration enum = repository.elements();//这步要注意同步问题
    while(enum.hasMoreElements())
    {
      dl = (DemoListener)enum.nextElement();
      dl.demoEvent(event);
    }
  }

  //删除监听器,如果这里没有使用Vector而是使用ArrayList那么要注意同步问题
  public void removeDemoListener(DemoListener dl)
  {
    repository.remove(dl);//这步要注意同步问题
  }

  /**
   * 设置属性
   * @param str1 String
   */
  public void setName(String str1)
  {
    boolean bool=false;
    if(str1==null && sName!=null) bool=true;
    else if(str1!=null && sName==null) bool=true;
    else if(!sName.equals(str1)) bool=true;

    this.sName=str1;

    //如果改变则执行事件
    if(bool) notifyDemoEvent(new DemoEvent(this,sName));
  }

  public String getName()
  {
    return sName;
  }
}

package demo;

import java.lang.Thread;

/**
 * Title: 测试类
 * Description: 测试了由于改变属性而引起的事件发生
 * Copyright: Copyright (c) 2005
 * Company: cuijiang
 * @author not attributable
 * @version 1.0
 */
public class TestDemo
    implements DemoListener {
  private DemoSource ds;

  public TestDemo()
  {
    ds=new DemoSource();
    ds.addDemoListener(this);
    System.out.println("添加监听器完毕");
    try {
      Thread.sleep(3000);
      //改变属性,触发事件
      ds.setName("改变属性,触发事件");
    }
    catch (InterruptedException ex) {
      ex.printStackTrace();
    }

    ds.addDemoListener(this);
    System.out.println("添加监听器完毕2");
    try {
      Thread.sleep(3000);
      //改变属性,触发事件
      ds.setName("改变属性,触发事件2");
    }
    catch (InterruptedException ex) {
      ex.printStackTrace();
    }

    ds.removeDemoListener(this);
    System.out.println("添加监听器完毕3");
    try {
      Thread.sleep(3000);
      //改变属性,触发事件
      ds.setName("改变属性,触发事件3");
    }
    catch (InterruptedException ex) {
      ex.printStackTrace();
    }


  }

  public static void main(String args[])
  {

    new TestDemo();
  }

  /**
   * demoEvent
   * @param dm DemoEvent
   * @todo Implement this test.DemoListener method
   */
  public void demoEvent(DemoEvent dm) {
    System.out.println("事件处理方法");
    System.out.println(dm.getName());
    dm.say();
  }
}

posted @ 2006-02-19 17:59 sunfruit 阅读(855) | 评论 (0)编辑 收藏

[原创]JAVA编写的带有复选框的资源管理器树目录

    --sunfruit

    用JAVA实现了带有复选框的树目录


    JDK版本
        JDK1.4.x
    功能
        实现了带有复选框的资源管理器树目录,还有需要改进的地方,我在以后更新,如果那位朋友有好的建议欢迎提出
   
    欢迎大家提意见,交流
   
    代码如下
   
import javax.swing.tree.*;
import javax.swing.filechooser.*;
import javax.swing.event.*;
import java.awt.Cursor;
import java.awt.Component;
import java.awt.Font;
import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;

/**
 * Title: 系统级树目录
 * Description: 
 * Copyright: Copyright (c) 2004
 * Company: 
 * @author cuijiang contact cj0063@sina.com or cuij7718@yahoo.com.cn
 * @version 1.0
 */
public class AgileSuperJTreeBasic
    extends JTree
    implements TreeExpansionListener, TreeSelectionListener, MouseListener {
  protected DefaultTreeModel treeModel;
  protected FileSystemView fileSystemView; //建立文件系统视类对象
  protected FileNode root;

  public AgileSuperJTreeBasic() {
    Font myFont = new Font("宋体", 11, 12);
    fileSystemView = FileSystemView.getFileSystemView();
    root = new FileNode(fileSystemView.getRoots()[0]);
    root.explore();
    treeModel = new DefaultTreeModel(root);
    this.setModel(treeModel); //设定树形菜单
    this.addTreeExpansionListener(this); //打开/关闭节点事件
    this.addTreeSelectionListener(this); //选择的事件
    this.setCellRenderer(new MyTreeCellRenderer()); //生成图标
    this.setFont(myFont);
    this.setRootVisible(true);
    this.setRowHeight(18);
    this.addMouseListener(this);
  }

  //图标生成类
  protected class MyTreeCellRenderer
      extends JPanel
      implements TreeCellRenderer {
    JCheckBox check = new JCheckBox();
    BorderLayout borderLayout1 = new BorderLayout();
    JLabel label = new JLabel();
    public MyTreeCellRenderer() {
      this.setLayout(null);

      this.add(check);
      this.add(label);
      check.setBackground(UIManager.getColor("Tree.textBackground"));
      label.setBackground(UIManager.getColor("Tree.textBackground"));
      this.setBackground(UIManager.getColor("Tree.textBackground"));

    }

    public Dimension getPreferredSize() {
      Dimension checkDimension = check.getPreferredSize();
      Dimension labelDimension = label.getPreferredSize();
      return new Dimension(checkDimension.width + labelDimension.width,
                           (checkDimension.height < labelDimension.height ?
                            labelDimension.height : checkDimension.height));
    }

    public Component getTreeCellRendererComponent(JTree tree, Object value,
                                                  boolean sel, boolean expanded,
                                                  boolean leaf, int row,
                                                  boolean hasFocus) {
      String stringValue = tree.convertValueToText(value, sel, expanded, leaf,
          row, hasFocus);
      setEnabled(tree.isEnabled());
      label.setFont(tree.getFont());
      check.setSelected( ( (FileNode) value).isSelected());
      //设置图标为系统的文件类型图标
      FileSystemView fileSystemView = FileSystemView.getFileSystemView();
      label.setIcon(fileSystemView.getSystemIcon( ( (FileNode) value).getFile()));
      label.setText(stringValue);
      return this;
    }

    public void doLayout() {
      Dimension checkDimension = check.getPreferredSize();
      Dimension labelDimension = label.getPreferredSize();
      int checkY = 0;
      int labelY = 0;
      if (checkDimension.height > labelDimension.height) {
        labelY = (checkDimension.height - labelDimension.height) / 2;
      }
      else {
        checkY = (labelDimension.height - checkDimension.height) / 2;
      }
      check.setLocation(0, checkY);
      check.setBounds(0, checkY, checkDimension.width, checkDimension.height);
      label.setLocation(checkDimension.width, labelY);
      label.setBounds(checkDimension.width, labelY, labelDimension.width,
                      labelDimension.height);
    }

  }

  //节点张开事件
  public void treeExpanded(TreeExpansionEvent event) {
    //判断是否是叶节点
    //if (this.getLastSelectedPathComponent() == null) {
      //System.out.println("ok");
      //return;
    //}
    setCursor(new Cursor(Cursor.WAIT_CURSOR));
    TreePath path = event.getPath();
    //System.out.println(path.toString());
    FileNode node = (FileNode) path.getLastPathComponent();
    node.explore();
    treeModel.nodeStructureChanged(node);
    this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));

  }

  //节点闭合事件
  public void treeCollapsed(TreeExpansionEvent event) {

  }

  //文件节点类
  protected class FileNode
      extends DefaultMutableTreeNode {

    private boolean isSelected = false;
    private boolean explored = false;

    public FileNode(File file) {
      this(file, false);
    }

    public FileNode(File file, boolean bool) {
      super(file);
      this.isSelected = bool;
    }

    //
    public boolean isSelected() {
      return isSelected;
    }

    public void setSelected(boolean isSelected) {
      this.isSelected = isSelected;
      if (children != null) {
        Enumeration enum = children.elements();
        while (enum.hasMoreElements()) {
          FileNode node = (FileNode) enum.nextElement();
          node.setSelected(isSelected);
        }
      }
    }

    //
    public boolean getAllowsChildren() {
      return isDirectory();
    }

    public boolean isLeaf() {
      return!isDirectory();
    }

    public File getFile() {
      return (File) getUserObject();
    }

    public boolean isExplored() {
      return explored;
    }

    public void setExplored(boolean b) {
      explored = b;
    }

    public boolean isDirectory() {
      return getFile().isDirectory();
    }

    public String toString() {
      File file = (File) getUserObject();
      String filename = file.toString();
      int index = filename.lastIndexOf(File.separator);
      return (index != -1 && index != filename.length() - 1)
          ? filename.substring(index + 1) : filename;
    }

    public void explore() {
      if (!isExplored()) {
        File file = getFile();
        File[] children = file.listFiles();
        if (children == null || children.length == 0)
          return;
        for (int i = 0; i < children.length; ++i) {
          File f = children[i];
          if (f.isDirectory())
            add(new FileNode(children[i], isSelected));
        }
        explored = true;
      }
    }

  }

  /**
   * 选择节点触发的事件
   * 继承或是直接引用需要重新写此方法
   * @param e
   */
  public void valueChanged(TreeSelectionEvent e) {
    //文件路径
    String sFilePath = "";
    Object myobj = this.getLastSelectedPathComponent();
    if (myobj != null) {
      sFilePath = ( (File) ( ( (DefaultMutableTreeNode) (myobj)).getUserObject())).
          getPath();
    }
    //System.out.println(sFilePath);
  }

  /**
   * Invoked when the mouse button has been clicked (pressed and released) on a
   * component.
   * @param e MouseEvent
   * @todo Implement this java.awt.event.MouseListener method
   */
  public void mouseClicked(MouseEvent e) {
    int count = e.getClickCount();

    if (count != 1) {
      //System.out.println(count);

    }
    else {
      int x = e.getX();
      int y = e.getY();
      int row = this.getRowForLocation(x, y);
      TreePath path = this.getPathForRow(row);
      if (path != null) {
        FileNode node = (FileNode) path.getLastPathComponent();
        boolean isSelected = ! (node.isSelected());
        node.setSelected(isSelected);
        ( (DefaultTreeModel)this.getModel()).nodeChanged(node);
      }
    }

  }

  /**
   * Invoked when a mouse button has been pressed on a component.
   * @param e MouseEvent
   * @todo Implement this java.awt.event.MouseListener method
   */
  public void mousePressed(MouseEvent e) {
  }

  /**
   * Invoked when a mouse button has been released on a component.
   * @param e MouseEvent
   * @todo Implement this java.awt.event.MouseListener method
   */
  public void mouseReleased(MouseEvent e) {
  }

  /**
   * Invoked when the mouse enters a component.
   * @param e MouseEvent
   * @todo Implement this java.awt.event.MouseListener method
   */
  public void mouseEntered(MouseEvent e) {
  }

  /**
   * Invoked when the mouse exits a component.
   * @param e MouseEvent
   * @todo Implement this java.awt.event.MouseListener method
   */
  public void mouseExited(MouseEvent e) {
  }
}

posted @ 2006-02-19 17:59 sunfruit 阅读(2745) | 评论 (10)编辑 收藏

[JAVA]用户自定义事件监听

    --sunfruit

    用户自定义事件

   

User defined Event listeners java

All of us who have used java.awt.event package in either applets
or in Frames or in swing JFrame, shall agree to the fact that event
propagation and listener concept is very very useful for capturing
any action initiated either by user or by system, should be caught
at the right place and without unneccessarily wasting time traversing
through all the way from begining to end of source code just to know
any takers for this event.



This concept is implemented in form of MouseEvent, KeyEvent, WindowEvent so on so forth.

JDK has given us a handle for creating our own event object and as well
as event handling framework using java.util.EventObject and java.util.EventListener.

You can imagine a scenario whereby you have to write an application, in
which a email notification feature in a forum.

Whenever a special event takes place , then your have to notify all the users
who have registered themselves for this program.

One solution is to use a Database and query all the users from the table
and send notification to each and every user.
But this is more of Database centric approach like old days thick client
and server model.

Think about the overhead on database and instead another solution is
to create an event notification framework, whereby you have to create
your own version of Event Object and Event Listeners.

Event object represents the special event and all the users who register
themselves for the event implements this Event listener.

Let us take a more deeper plunge into this:

1. Create a Demo event by creating a DemoEvent.java file that
extends to java.util.EventObject.

This class has a constructor that takes the event originator object (DemoSource).
and a method getSource(), that gives the reference to the object that originated
this event.

DemoEvent.java

package demo.listener;

import java.util.EventObject;

public class DemoEvent extends EventObject
{
	Object obj;
	public DemoEvent(Object source)
	{
		super(source);
		obj = source;

	}
	public Object getSource()
	{
		return obj;
	}
	public void say()
	{
		System.out.println("This is say method...");
	}

}



2. Create the source of event notification file DemoSource.java
It has a java.util.Vector that acts like a repository for storing all the
listeners to the events this source provides.

It has two other common method such as addListener(..) is to add any
new user to this event.

And notifyDemoEvent(..) is to alert all the users about this perticular event
occurance.

DemoEvent.java

package demo.listener;
import java.util.*;

public class DemoSource
{
	private Vector repository = new Vector();
	DemoListener dl;
	public DemoSource()
	{

	}
	public void addDemoListener(DemoListener dl)
	{
		repository.addElement(dl);
	}
	public void notifyDemoEvent()
	{
		Enumeration enum = repository.elements();
		while(enum.hasMoreElements())
		{
			dl = (DemoListener)enum.nextElement();
			dl.demoEvent(new DemoEvent(this));
		}
	}
}



3. Define a listener interface that extends to java.util.EventListener
and contains the method for invoking the Event, here it is demoEvent(DemoEvent de).

DemoListener.java

package demo.listener;

import java.util.EventListener;

public interface DemoListener extends EventListener
{
	public void demoEvent(DemoEvent dm);

}




4. Define all the users, who want to listen to this events.
These objects should implement DemoListener, to be able to
capture the event propagated from DemoSource.java.

Listener1.java

package demo.listener;

public class Listener1 implements DemoListener
{
	public void demoEvent(DemoEvent de)
	{
		System.out.println("Inside listener1...");
	}
}



Listener2.java

package demo.listener;

public class Listener2 implements DemoListener
{
	public void demoEvent(DemoEvent de)
	{
		System.out.println("Inside listener2...");
	}
}


Listener3.java

package demo.listener;

public class Listener3 implements DemoListener
{
	public void demoEvent(DemoEvent de)
	{
		System.out.println("Inside listener3...");
	}
}



5. Now it time to write the client for testing this Framework.
Create a client such as TestDemo.java and create a DemoSource
object and all the users such as Listener1, Listener2, Listener3.
And add all these listeners to the demo source by using the addDemoListener(..).
When the notifyDemoEvent(..) is called on the demo source object,
the event gets notified to all the users (listener1, listener2, listener3)
and  the  output comes out to be

Inside listener1...
Inside listener2...
Inside listener3...


TestDemo.java

package demo.listener;

public class TestDemo
{
	DemoSource ds;

	public TestDemo()
	{
		try{
			ds = new DemoSource();
			Listener1 l1 = new Listener1();
			Listener2 l2 = new Listener2();
			Listener3 l3 = new Listener3();

			ds.addDemoListener(l1);
			ds.addDemoListener(l2);
			ds.addDemoListener(l3);

			ds.notifyDemoEvent();

		}catch(Exception ex){ex.printStackTrace();}
	}

	public static void main(String args[])
	{
		new TestDemo();
	}
}

posted @ 2006-02-19 17:58 sunfruit 阅读(3529) | 评论 (0)编辑 收藏

仅列出标题
共11页: First 上一页 3 4 5 6 7 8 9 10 11 下一页