qiyadeng

专注于Java示例及教程
posts - 84, comments - 152, trackbacks - 0, articles - 34

IBM推荐的的开发组合.

http://www-128.ibm.com/developerworks/cn/kickstart/index.html

posted @ 2006-04-04 09:16 qiyadeng 阅读(801) | 评论 (1)编辑 收藏

网上主要流传有两种方式实现系统托盘:
1.Windows Tray Icon (http://jeans.studentenweb.org/java/trayicon/trayicon.html)
shot-balloon.gif

2.SysTray for Java (http://systray.sourceforge.net/)
shot.png

这两个都是开源的...可以根据上面的下载.

相对来说,我更喜欢SysTray for Java,原因很简单,SysTray for Java实现了我所要的功能而且相对来说比Windows Tray Icon 要简单.

使用SysTray是很简单的.下载下来的文件有个例子Example.java,照着这个实现你所需要的功能应该不算困难.

主要是菜单和按钮的操作,和操作一般的JFrame一样.

下面是一个例子程序:

package qiya.systray;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import snoozesoft.systray4j.SysTrayMenu;
import snoozesoft.systray4j.SysTrayMenuEvent;
import snoozesoft.systray4j.SysTrayMenuIcon;
import snoozesoft.systray4j.SysTrayMenuItem;
import snoozesoft.systray4j.SysTrayMenuListener;

public class MainFrame extends JFrame implements ActionListener,
  SysTrayMenuListener {

 static final int INIT_WIDTH = 400;// 默认窗口宽度

 static final int INIT_HEIGHT = 244;// 默认窗口高度

 private static final String toolTip = "宽带计费接口";// 提示文字

 static final SysTrayMenuIcon icon = new SysTrayMenuIcon("rocket.gif");// 图片信息

 SysTrayMenu menu;// 菜单

 private JButton launchButton = new JButton();// 启动按钮

 private JButton exitButton = new JButton();// 退出按钮

 private JLabel statusLabel = new JLabel();// 运行状态

 public static void main(String[] args) {
  try {
   UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  } catch (InstantiationException e) {
   e.printStackTrace();
  } catch (IllegalAccessException e) {
   e.printStackTrace();
  } catch (UnsupportedLookAndFeelException e) {
   e.printStackTrace();
  }

  new MainFrame();
 }

 public MainFrame() {
  super("宽带计费接口");// 标题
  setIconImage(new ImageIcon(getClass().getResource("rocket.gif"))
    .getImage());// 图标
  this.setLayout(null);
  this.setSize(new Dimension(INIT_WIDTH, INIT_HEIGHT));
  Dimension dimScreen = Toolkit.getDefaultToolkit().getScreenSize();
  int xPos = (dimScreen.width - INIT_WIDTH) / 2;
  int yPos = (dimScreen.height - INIT_HEIGHT) / 2;

  statusLabel.setText("系统状态监视");
  statusLabel.setBounds(new Rectangle(45, 35, 280, 40));
  statusLabel.setToolTipText("当前系统的运行状态");
  statusLabel.setFont(new Font("宋体", 0, 14));

  launchButton.setText("启动");
  launchButton.setBounds(new Rectangle(80, 180, 80, 23));

  exitButton.setText("退出");
  exitButton.setBounds(new Rectangle(230, 180, 80, 23));

  this.getContentPane().add(statusLabel, null);
  this.getContentPane().add(launchButton, null);
  this.getContentPane().add(exitButton, null);

  launchButton.addActionListener(this);
  exitButton.addActionListener(this);

  this.setBounds(xPos, yPos, INIT_WIDTH, INIT_HEIGHT);

  icon.addSysTrayMenuListener(this);
  this.createMenu();
  this.setVisible(true);
 }

 /**
  * 创建菜单
  *
  */
 private void createMenu() {
  SysTrayMenuItem subItem1 = new SysTrayMenuItem("退出", "退出");
  subItem1.addSysTrayMenuListener(this);

  SysTrayMenuItem subItem2 = new SysTrayMenuItem("关于", "关于");
  subItem2.addSysTrayMenuListener(this);

  SysTrayMenuItem subItem3 = new SysTrayMenuItem("帮助", "帮助");
  subItem3.addSysTrayMenuListener(this);

  menu = new SysTrayMenu(icon, toolTip);// 生成菜单
  menu.addItem(subItem1);
  menu.addSeparator();
  menu.addItem(subItem2);
  menu.addItem(subItem3);
 }

 /**
  * 点击按钮事件
  */
 public void actionPerformed(ActionEvent e) {
  if (e.getActionCommand().equalsIgnoreCase("退出")) {
   System.exit(0);
  } else if (e.getActionCommand().equalsIgnoreCase("启动")) {
   // 启动计费程序

  }
 }

 /**
  * 菜单选择事件
  */
 public void menuItemSelected(SysTrayMenuEvent e) {
  if (e.getActionCommand().equalsIgnoreCase("退出")) {
   System.exit(0);
  } else if (e.getActionCommand().equalsIgnoreCase("关于")) {
   JOptionPane.showMessageDialog(this, "宽带计费接口" + "完成于2005-3-27");
  } else if (e.getActionCommand().equalsIgnoreCase("帮助")) {
   JOptionPane.showMessageDialog(this, "宽带计费接口" + "帮助文件待写...");
  }
 }

 /**
  * 左键单击事件
  */
 public void iconLeftClicked(SysTrayMenuEvent e) {
  if (this.isVisible()) {// 如果可见,最小化
   this.setVisible(false);
  } else {// 如果不可见显示出来
   this.setVisible(true);
  }
 }

 /**
  * 左键双击事件
  */
 public void iconLeftDoubleClicked(SysTrayMenuEvent e) {
  if (this.isVisible()) {// 如果可见,最小化
   this.setVisible(false);
  } else {// 如果不可见显示出来
   this.setVisible(true);
  }
 }
}


tray.gif

posted @ 2006-03-27 17:34 qiyadeng 阅读(2956) | 评论 (2)编辑 收藏

(Generic algorithms for Java)jga is a functors library: the intent is to explore and exploit functors as a design and implementation tool to reduce boilerplate coding. A functor is an object that encapsulates a function or expression: it can take arguments and produce results, as can any method, expression, or function (in other languages that support functions). Unlike an expression, as an object it can be passed as an argument without being executed; it can be persisted to a database or file; it can be serialized and passed from client to server (and back); and it can be instantiated at runtime based on information unavailable at compile-time.

posted @ 2006-03-24 09:16 qiyadeng 阅读(444) | 评论 (0)编辑 收藏

美国联邦法律规定:
 
  1)不得与豪猪发生性关系。(靠,谁敢呀) 
  2)每周四晚6:00以后不得放P。(以后还真要小心了,别一不留神坐牢了还不知为啥) 
  3)任何人不得销售其子女。(好象中国也不许吧?) 


阿拉巴马州:
 
  无论任何时候,将冰激淋卷放在口袋里是违法的。(有病啊~~) 

  
阿肯色州:
 
  男性可以合法殴打其配偶,但每月最多一次。 
  (估计很多暴力倾向的兄弟知道了一定想移民阿肯色了, 
  可也有例外呀,克林顿就是阿肯色的前州长,咋老被希拉里扁呀) 

  
亚利桑纳州:
 
  任何房间中不得有两根以上的假阳具。 
  (估计那州的最高法官是个变态狂!) 

  
夏威夷州:
 
  不得将谷物放在耳朵里。(神经病,以为偷太空种子呀) 

  
印弟安纳州:
 
  1)任何年满18岁的男性,若与17岁以下的女性发生性关系,而且当时她又没穿鞋袜,那将课重罪. 
  (兄弟们千万注意了呀!别全了) 
  2)圆周率在该州法定为4。(活活气死咱祖聪之前辈呀!) 

  
爱荷华州:
 
  1)任何只有一只上臂的钢琴演奏者必须免费演奏。(严重歧视残疾艺术表演家) 
  2)任何有胃病的男性不得在公共场所与女性接吻。(接吻和胃有关系吗?男性胃癌晚期患者的福音 

  
纽约州:
 
  1)不得仅为娱乐而将球砸向他人脑袋。(谋杀可以不?真的脑子进水了) 
  2)10:00以后不得穿拖鞋。(光脚吧) 

  
新泽西州:
 
  凡谋杀时不得穿防弹背心。(管得着吗,警察这么没自信!) 

  
北卡州:
 
  任何一位未婚男性与一为未婚女性,如果在任何旅馆或汽车旅馆登记为已婚,那么他们即算合法夫妻了。(想带小蜜开房的兄弟们千万别去那州呀!) 

  
宾西法尼亚州:
 
  不得在浴室唱歌。(难怪在宾大商学院的同胞都不会K歌) 

  
南卡州:
 
  仅在每周六,男性被允许在法院的门前台阶上合法殴打其配偶。(这是啥规定,郁闷ING) 

  
犹他州:
 
  1)不喝牛奶违法。(喝不完援助非洲难民呀,干么为难自己! 
  难怪俺一只要喝牛奶就拉肚子的朋友从犹大转到纽约了,保命要紧呀。) 
  2)不得在正在执行急救任务的救护车后座上做爱。(这好理解,怕病人看见血管爆裂么!哈哈)

posted @ 2006-02-26 22:11 qiyadeng 阅读(171) | 评论 (0)编辑 收藏

一、穷
我想这已经是共识,没钱?那就别想谈女朋友了,别再幻想着什么纯洁无暇爱情了,都是扯淡。当你憋着小嘴愤愤不平的拿这个诅咒分手女友的无情的时候,那只能说明你无能懦夫懒惰加上小人,离开你是明智选择。给你个富婆说不定你绝情的嘴脸比谁都更丑陋。所以,男人,想讨老婆就赚钱吧不管你混B社会杀人放火贩毒contraband只要你能弄到票子女人就多得让你眼花了。
二、丑
经典语句,长得丑不是你的错,出来吓人就是你不对了,如果你敢说一句外表不是主要的,心灵美才是重要的,打住,那我就给你一头猪一样的恐龙做老婆我看你什么反映,己所不欲勿施与人,当你做着癞蛤蟆想吃天鹅肉的美梦时,女孩还在走着灰姑娘的神呢。
三、薄
这个薄是脸皮薄的意思,如果你文质彬彬,甚至会害羞,傻傻的,你如果不是内心真有点城府的话,那看来你跟异性也是绝缘了,别想着八十年代电影里女孩说傻的可爱了,时代不同了,并且进步太快了。如果你能达到不要脸的流氓地步,也是泡妞的最高境界了。
四、专
这里指的是在一棵树上吊死,如果你是个痴情专一的汉字,对一个MM渴望用坚持和痴情来感动,我想你离沉重打击不远了,现在的MM才不喜欢你用情专一呢,如果你能到处沾花惹草正说明你的本事,MM虽然会幽怨,其实底子里才更看得起你呢。保证你召之即来,挥之即去。
五、笨
这里的笨是指嘴笨,不需要你多厉害的口才,但是甜言蜜语是要会说的,哪怕你心里想着另一个MM,口里把对这个MM的感情换个名字说给那个听也行,爱的肉麻。
六、真
其实和五差不多,就是太真诚了,MM是要来骗和哄的,你傻傻的都说实话掏老底,嘿嘿,那你也等着MM和你拜拜吧!
七、小
此小非彼小,嘿嘿,是胆小,好像和三类似,但也不是,只要有机会,能拉手早拉手,拉了手了要赶快亲,亲完了赶快找地上床,不要觉得太快了,现在是个效率的社会,你不快有人比你快,也别担心MM会觉得你轻浮,她比你还急呢。不信?等上了床你就知道了。
八、跑
专指看贴不回贴就跑了的人,这类也是找不到女朋友的,自己掂量吧!

posted @ 2006-02-21 20:21 qiyadeng 阅读(304) | 评论 (0)编辑 收藏

目录

  前言
  一. Java 文档和 javadoc
  二. 文档注释的格式
    1. 文档注释的格式化
    2. 文档注释的三部分
  三. 使用 javadoc 标记
    1. @see 的使用
    2. 使用 @author、@version 说明类
    3. 使用 @param、@return 和 @exception 说明方法
  四. javadoc 命令


前言

  Java 的语法与 C++ 及为相似,那么,你知道 Java 的注释有几种吗?是两种?

  // 注释一行
  /* ...... */ 注释若干行

  不完全对,除了以上两种之外,还有第三种,文档注释:

  /** ...... */ 注释若干行,并写入 javadoc 文档

  通常这种注释的多行写法如下:

  /**
   * .........
   * .........
   */

  暂停,暂停!这第三种注释有什么用?javadoc 又是什么东西?

  好,那就让我告诉你——


一. Java 文档和 javadoc

  Java 程序员都应该知道使用 JDK 开发,最好的帮助信息就来自 SUN 发布的 Java 文档。它分包、分类详细的提供了各方法、属性的帮助信息,具有详细的类树信息、索引信息等,并提供了许多相关类之间的关系,如继承、实现接口、引用等。

  Java 文档全是由一些 html 文件组织起来的,在 SUM 的站点上可以下载它们的压缩包。但是你肯定想不到,这些文档我们可以自己生成。——就此打住,再吊一次胃口。

  安装了 JDK 之后,安装目录下有一个 src.jar 文件或者 src.zip 文件,它们都是以 ZIP 格式压缩的,可以使用 WinZip 解压。解压之后,我们就可以看到分目录放的全是 .java 文件。是了,这些就是 Java 运行类的源码了,非常完整,连注释都写得一清二楚……不过,怎么看这些注释都有点似曾相识的感觉?

  这就不奇怪了,我们的迷底也快要揭开了。如果你仔细对比一下 .java 源文件中的文档注释 (/** ... */) 和 Java 文档的内容,你会发现它们就是一样的。Java 文档只是还在格式和排版上下了些功夫。再仔细一点,你会发现 .java 源文件中的注释还带有 HTML 标识,如 <B>、<BR>、<Code> 等,在 Java 文档中,该出现这些标识的地方,已经按标识的的定义进行了排版。

  终于真像大白了,原来 Java 文档是来自这些注释。难怪这些注释叫做文档注释呢!不过,是什么工具把这些注释变成文档的呢?

  是该请出 javadoc 的时候了。在 JDK 的 bin 目录下你可以找到 javadoc,如果是 Windows 下的 JDK,它的文件名为 javadoc.exe。使用 javdoc 编译 .java 源文件时,它会读出 .java 源文件中的文档注释,并按照一定的规则与 Java 源程序一起进行编译,生成文档。

  介绍 javadoc 的编译命令之前,还是先了解一下文档注释的格式吧。不过为了能够编译下面提到的若干例子,这里先介绍一条 javadoc 命令:

  javadoc -d 文档存放目录 -author -version 源文件名.java

  这条命令编译一个名为 “源文件名.java”的 java 源文件,并将生成的文档存放在“文档存放目录”指定的目录下,生成的文档中 index.html 就是文档的首页。-author 和 -version 两个选项可以省略。


二. 文档注释的格式

  文档注释可以用于对类、属性、方法等进行说明。写文档注释时除了需要使用 /** .... */ 限定之外,还需要注意注释内部的一些细节问题。

  1. 文档和文档注释的格式化

  生成的文档是 HTML 格式,而这些 HTML 格式的标识符并不是 javadoc 加的,而是我们在写注释的时候写上去的。比如,需要换行时,不是敲入一个回车符,而是写入 <br>,如果要分段,就应该在段前写入 <p>。

  因此,格式化文档,就是在文档注释中添加相应的 HTML 标识。

  文档注释的正文并不是直接复制到输出文件 (文档的 HTML 文件),而是读取每一行后,删掉前导的 * 号及 * 号以前的空格,再输入到文档的。如

  /**
* This is first line. <br>
***** This is second line. <br>
This is third line.
*/

  编译输出后的 HTML 源码则是

  This is first line. <br>
This is second line. <br>
This is third line.

  前导的 * 号允许连续使用多个,其效果和使用一个 * 号一样,但多个 * 号前不能有其它字符分隔,否则分隔符及后面的 * 号都将作为文档的内容。* 号在这里是作为左边界使用,如上例的第一行和第二行;如果没有前导的 * 号,则边界从第一个有效字符开始,而不包括前面的空格,如上例第三行。

  还有一点需要说明,文档注释只说明紧接其后的类、属性或者方法。如下例:

 
/** comment for class */
public class Test {

    /** comment for a attribute */
    int number;

    /** comment for a method */
    public void myMethod() { ...... }

    ......
}

  上例中的三处注释就是分别对类、属性和方法的文档注释。它们生成的文档分别是说明紧接其后的类、属性、方法的。“紧接”二字尤其重要,如果忽略了这一点,就很可能造成生成的文档错误。如

 
import java.lang.*;

/** commnet for class */

public class Test { ...... }

// 此例为正确的例子

  这个文档注释将生成正确的文档。但只需要改变其中两行的位置,变成下例,就会出错:

 
/** commnet for class */

import java.lang.*;

public class Test { ...... }

// 此例为错误的例子

  这个例子只把上例的 import 语句和文档注释部分交换了位置,结果却大不相同——生成的文档中根本就找不到上述注释的内容了。原因何在?

  “/** commnet for class */”是对 class Test 的说明,把它放在“public class Test { ...... }”之前时,其后紧接着 class Test,符合规则,所以生成的文档正确。但是把它和“import java.lang.*;”调换了位置后,其后紧接的就是不 class Test 了,而是一个 import 语句。由于文档注释只能说明类、属性和方法,import 语句不在此列,所以这个文档注释就被当作错误说明省略掉了。

  2. 文档注释的三部分

  根据在文档中显示的效果,文档注释分为三部分。先举例如下,以便说明。

 
/**
 * show 方法的简述.
 * <p>show 方法的详细说明第一行<br>
 * show 方法的详细说明第二行
 * @param b true 表示显示,false 表示隐藏
 * @return 没有返回值
 */
public void show(boolean b) {
    frame.show(b);
}

  第一部分是简述。文档中,对于属性和方法都是先有一个列表,然后才在后面一个一个的详细的说明。列表中属性名或者方法名后面那段说明就是简述。如下图中被红框框选的部分:

001.gif

  简述部分写在一段文档注释的最前面,第一个点号 (.) 之前 (包括点号)。换句话说,就是用第一个点号分隔文档注释,之前是简述,之后是第二部分和第三部分。如上例中的 “* show 方法的简述.”。

  有时,即使正确地以一个点号作为分隔,javadoc 仍然会出错,把点号后面的部分也做为了第一部分。为了解决这个问题,我们可以使用一个 <p> 标志将第二分部分开为下一段,如上例的“* <p>show 方法的详细说明第一行 ....”。除此之外,我们也可以使用 <br> 来分隔。

  第二部分是详细说明部分。该部分对属性或者方法进行详细的说明,在格式上没有什么特殊的要求,可以包含若干个点号。它在文档中的位置如下图所示:

002.gif 

  这部分文档在上例中相应的代码是:

  * show 方法的简述.
  * <p>show 方法的详细说明第一行<br>
  * show 方法的详细说明第二行

  发现什么了?对了,简述也在其中。这一点要记住了,不要画蛇添足——在详细说明部分中再写一次简述哦!

  第三部分是特殊说明部分。这部分包括版本说明、参数说明、返回值说明等。它在文档中的位置:

003.gif

  第三部分在上例中相应的代码是

  * @param b true 表示显示,false 表示隐藏
  * @return 没有返回值

  除了 @param 和 @return 之外,还有其它的一些特殊标记,分别用于对类、属性和方法的说明……不要推我,我马上就说。


三. 使用 javadoc 标记

  javadoc 标记是插入文档注释中的特殊标记,它们用于标识代码中的特殊引用。javadoc 标记由“@”及其后所跟的标记类型和专用注释引用组成。记住了,三个部分——@、标记类型、专用注释引用。不过我宁愿把它分成两部分:@ 和标记类型、专用注释引用。虽然 @ 和 标记类型之间有时可以用空格符分隔,但是我宁愿始终将它们紧挨着写,以减少出错机会。

  javadoc 标记有如下一些:

标记 用于 作用
@author 对类的说明 标明开发该类模块的作者
@version 对类的说明 标明该类模块的版本
@see 对类、属性、方法的说明 参考转向,也就是相关主题
@param 对方法的说明 对方法中某参数的说明
@return 对方法的说明 对方法返回值的说明
@exception 对方法的说明 对方法可能抛出的异常进行说明

  下面详细说明各标记。

  1. @see 的使用

  @see 的句法有三种:

  @see 类名
  @see #方法名或属性名
  @see 类名#方法名或属性名

  类名,可以根据需要只写出类名 (如 String) 或者写出类全名 (如 java.lang.String)。那么什么时候只需要写出类名,什么时候需要写出类全名呢?

  如果 java 源文件中的 import 语句包含了的类,可以只写出类名,如果没有包含,则需要写出类全名。java.lang 也已经默认被包含了。这和 javac 编译 java 源文件时的规定一样,所以可以简单的用 javac 编译来判断,源程序中 javac 能找到的类,javadoc 也一定能找到;javac 找不到的类,javadoc 也找不到,这就需要使用类全名了。

  方法名或者属性名,如果是属性名,则只需要写出属性名即可;如果是方法名,则需要写出方法名以及参数类型,没有参数的方法,需要写出一对括号。如

成员类型 成员名称及参数 @see 句法
属性 number @see number
属性 count @see count
方法 count() @see count()
方法 show(boolean b) @see show(boolean)
方法 main(String[] args) @see main(String[])

  有时也可以偷懒:假如上例中,没有 count 这一属性,那么参考方法 count() 就可以简写成 @see count。不过,为了安全起见,还是写全 @see count() 比较好。

  @see 的第二个句法和第三个句法都是转向方法或者属性的参考,它们有什么区别呢?

  第二个句法中没有指出类名,则默认为当前类。所以它定义的参考,都转向本类中的属性或者方法。而第三个句法中指出了类名,则还可以转向其它类的属性或者方法。

  关于 @see 标记,我们举个例说明。由于 @see 在对类说明、对属性说明、对方法说明时用法都一样,所以这里只以对类说明为例。

 
/**
 * @see String
 * @see java.lang.StringBuffer
 * @see #str
 * @see #str()
 * @see #main(String[])
 * @see Object#toString()
 */
public class TestJavaDoc {

}

  生成的文档的相关部分如下图:

004.gif

  String 和 StringBuffer 都是在 java.lang 包中,由于这个包是默认导入了的,所以这两个类可以直接写类名,也可以写类全名。str、str() 为同名属性和方法,所以方法名需要用 () 区分。main 是带参数的方法,所以在 () 中指明了参数类型。toString() 虽然在本类中也有 (从 Object 继承的),但我们是想参考 Object 类的 toString() 方法,所以使用了 Object#toString()。

  奇怪的是,为什么其中只有 str、str() 和 main(String[]) 变成了链接呢?那是因为编译时没有把 java.lang 包或者 Stirng、StringBuffer、Object 三个类的源文件一起加入编译,所以,生成的文档没有关于那三个类的信息,也就不可以建立链接了。后面讲解 javadoc 编译命令的时候还会详细说明。

  上例中如果去把类中的 str 属性去掉,那么生成的文档又会有什么变化呢?你会发现,原来是 str, str(),而现在变成了 str(), str(),因为 str 属性已经没有了,所以 str 也表示方法 str()。

  2. 使用 @author、@version 说明类

  这两个标记分别用于指明类的作者和版本。缺省情况下 javadoc 将其忽略,但命令行开关 -author 和 -version 可以修改这个功能,使其包含的信息被输出。这两个标记的句法如下:

  @author 作者名
  @version 版本号

  其中,@author 可以多次使用,以指明多个作者,生成的文档中每个作者之间使用逗号 (,) 隔开。@version 也可以使用多次,只有第一次有效,生成的文档中只会显示第一次使用 @version 指明的版本号。如下例

 
/**
 * @author Fancy
 * @author Bird
 * @version Version 1.00
 * @version Version 2.00
 */
public class TestJavaDoc {

}

  生成文档的相关部分如图:

005.gif

  从生成文档的图示中可以看出,两个 @author 语句都被编译,在文档中生成了作者列表。而两个 @version 语句中只有第一句被编译了,只生成了一个版本号。

  从图上看,作者列表是以逗号分隔的,如果我想分行显示怎么办?另外,如果我想显示两个以上的版本号又该怎么办?

  ——我们可以将上述两条 @author 语句合为一句,把两个 @version 语句也合为一句:

  @author Fancy<br>Bird
  @version Version 1.00<br>Version 2.00

  结果如图:

  我们这样做即达到了目的,又没有破坏规则。@author 之后的作者名和 @version 之后的版本号都可以是用户自己定义的任何 HTML 格式,所以我们可以使用 <br> 标记将其分行显示。同时,在一个 @version 中指明两个用 <br> 分隔的版本号,也没有破坏只显示第一个 @version 内容的规则。

  3. 使用 @param、@return 和 @exception 说明方法

  这三个标记都是只用于方法的。@param 描述方法的参数,@return 描述方法的返回值,@exception 描述方法可能抛出的异常。它们的句法如下:

  @param 参数名 参数说明
  @return 返回值说明
  @exception 异常类名 说明

  每一个 @param 只能描述方法的一个参数,所以,如果方法需要多个参数,就需要多次使用 @param 来描述。

  一个方法中只能用一个 @return,如果文档说明中列了多个 @return,则 javadoc 编译时会发出警告,且只有第一个 @return 在生成的文档中有效。

  方法可能抛出的异常应当用 @exception 描述。由于一个方法可能抛出多个异常,所以可以有多个 @exception。每个 @exception 后面应有简述的异常类名,说明中应指出抛出异常的原因。需要注意的是,异常类名应该根据源文件的 import 语句确定是写出类名还是类全名。   示例如下:

 
public class TestJavaDoc {

    /**
     * @param n a switch
     * @param b excrescent parameter
     * @return true or false
     * @return excrescent return
     * @exception java.lang.Exception throw when switch is 1
     * @exception NullPointerException throw when parameter n is null
     */
    public boolean fun(Integer n) throws Exception {
        switch (n.intValue()) {
        case 0:
            break;
        case 1:
            throw new Exception("Test Only");
        default:
            return false;
        }
        return true;
    }

}

  使用 javadoc 编译生成的文档相关部分如下图:

  可以看到,上例中 @param b excrescent parameter 一句是多余的,因为参数只是一个 n,并没有一个 b但是 javadoc 编译时并没有检查。因此,写文档注释时一定要正确匹配参数表与方法中正式参数表的项目。如果方法参数表中的参数是 a,文档中却给出对参数 x 的解释,或者再多出一个参数 i,就会让人摸不着头脑了。@exceptin 也是一样。

  上例程序中并没有抛出一个 NullPointerException,但是文档注释中为什么要写上这么一句呢,难道又是为了演示?这不是为了演示描述多余的异常也能通过编译,而是为了说明写异常说明时应考运行时 (RunTime) 异常的可能性。上例程序中,如果参数 n 是给的一个空值 (null),那么程序会在运行的时候抛出一个 NullPointerException,因此,在文档注释中添加了对 NullPointerException 的说明。

  上例中的 @return 语句有两个,但是根据规则,同一个方法中,只有第一个 @return 有效,其余的会被 javadoc 忽略。所以生成的文档中没有出现第二个 @return 的描述。

  讲到这里,该怎么写文档注释你应该已经清楚了,下面就开始讲解 javadoc 的常用命令。


四. javadoc 命令

  运行 javadoc -help 可以看到 javadoc 的用法,这里列举常用参数如下:

用法:
  javadoc [options] [packagenames] [sourcefiles]

选项:

  -public 仅显示 public 类和成员
  -protected 显示 protected/public 类和成员 (缺省)
  -package 显示 package/protected/public 类和成员
  -private 显示所有类和成员
  -d <directory> 输出文件的目标目录
  -version 包含 @version 段
  -author 包含 @author 段
  -splitindex 将索引分为每个字母对应一个文件
  -windowtitle <text> 文档的浏览器窗口标题

  javadoc 编译文档时可以给定包列表,也可以给出源程序文件列表。例如在 CLASSPATH 下有两个包若干类如下:

  fancy.Editor
  fancy.Test
  fancy.editor.ECommand
  fancy.editor.EDocument
  fancy.editor.EView

  这里有两个包 (fancy 和 fancy.editor) 和 5 个类。那么编译时 (Windows 环境) 可以使用如下 javadoc 命令:

  javadoc fancy\Test.java fancy\Editor.java fancy\editor\ECommand.java fancy\editor\EDocument.java fancy\editor\EView.java

  这是给出 java 源文件作为编译参数的方法,注意命令中指出的是文件路径,应该根据实际情况改变。也可以是给出包名作为编译参数,如:

  javadoc fancy fancy.editor

  用浏览器打开生成文档的 index.html 文件即可发现两种方式编译结果的不同,如下图:

  用第二条命令生成的文档被框架分成了三部分:包列表、类列表和类说明。在包列表中选择了某个包之后,类列表中就会列出该包中的所有类;在类列表中选择了某个类之后,类说明部分就会显示出该类的详细文档。而用第一条命令生成的文档只有两部分,类列表和类说明,没有包列表。这就是两种方式生成文档的最大区别了。

  下面再来细说选项。

  -public、-protected、-package、-private 四个选项,只需要任选其一即可。它们指定的显示类成员的程度。它们显示的成员多少是一个包含的关系,如下表:

-private (显示所有类和成员)
-package (显示 package/protected/public 类和成员)
-protected (显示 protected/public 类和成员)
-public (仅显示 public 类和成员)

  -d 选项允许你定义输出目录。如果不用 -d 定义输出目录,生成的文档文件会放在当前目录下。-d 选项的用法是

  -d 目录名

  目录名为必填项,也就是说,如果你使用了 -d 参数,就一定要为它指定一个目录。这个目录必须已经存在了,如果还不存在,请在运行 javadoc 之前创建该目录。

  -version 和 -author 用于控制生成文档时是否生成 @version 和 @author 指定的内容。不加这两个参数的情况下,生成的文档中不包含版本和作者信息。

  -splitindex 选项将索引分为每个字母对应一个文件。默认情况下,索引文件只有一个,且该文件中包含所有索引内容。当然生成文档内容不多的时候,这样做非常合适,但是,如果文档内容非常多的时候,这个索引文件将包含非常多的内容,显得过于庞大。使用 -splitindex 会把索引文件按各索引项的第一个字母进行分类,每个字母对应一个文件。这样,就减轻了一个索引文件的负担。

  -windowtitle 选项为文档指定一个标题,该标题会显示在窗口的标题栏上。如果不指定该标题,而默认的文档标题为“生成的文档(无标题)”。该选项的用法是:

  -windowtitle 标题

  标题是一串没有包含空格的文本,因为空格符是用于分隔各参数的,所以不能包含空格。同 -d 类似,如果指定了 -windowtitle 选项,则必须指定标题文本。

  到此为止,Java 文档和 javadoc 就介绍完了。javadoc 真的能让我们在 Java 注释上做文章——生成开发文档。

posted @ 2006-02-20 15:41 qiyadeng 阅读(1402) | 评论 (1)编辑 收藏

ISBN号是国际标准书号的简称,它是国际标准化组织于1972年公布的一项国际通用的出版物统一编号方法。所有正规出版的普通图书版权页都有ISBN 号,ISBN是 international standard of book number 几个英文字母的缩写,即国际标准书号。它由10位数字组成,这10位数字由组号、出版者号、书名号、校验号这四部分组成,其间用“--”相连。

  ISBN号是由10位数字组成,共分四段:

1.组号: 代表出版者的国家,地理区域,语种等.我国的组号为"7"。

2.出版者号: 代表组内所属的一个具体出版者(出版社,出版公司等)。由国家或地区的ISBN中心设置和分配,可取1-7位数字。

3.书名号:书名号是由出版者给予每种出版物的编号。

4. 校验号: 校验号是ISBN号的最后一位数值,它能够校验出ISBN号是否正确,即:将ISBN1-9位数字顺序乘以10-2这9个数字,将这些乘积之和再加上校验 号,假如能被11整除,则这个ISBN号是正确的,算式为7*10+3*9+0*8 +5*7+0*6+1*5+5*4+6*3+8*2+7= 198,198/11=18,能被11整除。校验号只能是1位数,当为10时,记为罗马数字X。

posted @ 2006-02-17 10:18 qiyadeng 阅读(389) | 评论 (0)编辑 收藏

 该文章在<<EJB编程指南>>的实例的基础上建立的,主要是给新手一个比较直观的例子和作为自己的日志,并不打算介绍EJB的原理性的东西。另外,由于本人水平有限,请不吝赐教。
    笔者使用的IDE为:Eclipse3.0+MyEclipse4.01GA
    J2EE容器为:JBoss4.0
   
    本文描述一个帮助存款和取款的无状态会话Bean的完整开发及部署的过程。步骤如下:
1、编写无状态会话Bean的实现类。
2、编写无状态会话Bean的主接口和组件接口。
3、将Bean汇编成应用程序,编写部署描述项。
4、在EJB服务器上部署应用程序。
5、用Java应用程序进行测试。
上面是主要的过程,有些步骤可以不用手工完成,通过IDE可以简化开发过程,如果你对IDE的该功能不太清楚可以参考产品文档(http: //myeclipseide.com/enterpriseworkbench/help/index.jsp?topic=/com.genuitec.myeclipse.doc/html/quickstarts/firstejb/index.html)。

一、新建一个EJB Project,工程名字为FundEJB,其他默认就好。
二、创建Session Bean:
    1、在src目录下新建包:qiya.deng.fund.ejb,请注意包名最后一定要以ejb为后缀,因为后面我们需要使用的XDoclet工具。
    2、新建SessionBean class,命名为StatelessFundManagerEJB,要需要以EJB为后缀,原因同上,而且根据规范最好是以EJB或是Bean为后缀。
   

    3、配置XDoclet :
    右击项目选择Properties,选择MyEclipse-XDoclet,点击Add Stander...,选择Standard EJB。
   
    选中Standard EJB,在ejbxdoclet上点击右键添加Add,在其中选择jboss,因为该例子中使用jboss作为应用服务器。选中jboss,修改下列属性
    Version = 4.0
    destDir = src/META-INF
   修改完毕,点击OK按钮回到主窗口。

    4、运行Xdoclet:
    右击项目选择MyEclipse->run Xdoclet。运行是console窗口会产生提示信息,运行完毕可以看到目录结构发生变化。
   
    5、编辑实现类StatelessFundManagerEJB:
    在编辑StatelessFundManagerEJB类之前选观察下StatelessFundManager接口,一定可以发现这个远程组件接口的接口方法和StatelessFundManager的方法是有对应关系的。
    在StatelessFundManager.java文件最后添加:

        /**
     *
     * @param balance
     * @param amount
     * @return
     *
     * @ejb.interface-method
     */
    public double addFunds(double balance,double amount){
        balance += amount;
        return balance;
    }
   
    /**
     *
     * @param balance
     * @param amount
     * @return
     * @throws InsufficientBalanceException
     *
     * @ejb.interface-method
     */
    public double withdrawFunds(double balance,double amount)throws InsufficientBalanceException {
        if (balance < amount) {
            throw (new InsufficientBalanceException());
        }
        balance -= amount;
        return balance;
    }
    重复第4步运行Xdoclet,之后观察StatelessFundManager接口。

   6、部署该应用到EJB服务器:
    部署描述项在IDE自动生成了,该文件的位置在/META-INF/ejb-jar.xml。打开ejb-jar.xml,jboss.xml文件描述进行查看。
    利用MyEclipse提供的部署工具进行部署:
   
    然后运行JBoss容器,可以看到有如下信息提示:

   

    关于MyEclipse中Application Server的使用请查看文档(http://www.myeclipseide.com/images/tutorials/quickstarts/appservers/)。
    到现在为止,你已经发布了一个简单的无状态的会话Bean。下面写个简单的应用程序进行测试.
   
三、编写进行测试的Java客户端程序。
    客户端程序可以是Web程序也可以是Application应用程序。这里以Application应用程序为例。
    同样使用Eclipse,新建Java Project,这里命名为FundClient。右击该项目选择properties->Java Build path,在Projects中加入上面的Project:FundEJB。在Libraries中点击Add External JARs...,把$JBoss_Home/client的目录下的所有jar文件添加到Libraries中。
    最后,就是编写客户端代码:

package qiya.deng.client;
    //import省去
public class StatelessFundManagerTestClient extends JFrame implements
        ActionListener {

    double balance = 0;
    JTextField amount = new JTextField(10);
    JButton addFunds = new JButton("Add Funds");
    JButton withdrawFunds = new JButton("Withdraw Funds");
    String msg = "Current account balance";
    String strBal = "0";
    JLabel status;
    StatelessFundManager manager;
    NumberFormat currencyFormatter;
   
    public StatelessFundManagerTestClient(){
        super("Fund Manager");
    }
   
    public static void main(String[] args){
        new StatelessFundManagerTestClient().init();
    }
   
    private void init() {
       
        buildGUI();
       
        addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent event){
                System.exit(0);
            }
        });
       
        addFunds.addActionListener(this);
        withdrawFunds.addActionListener(this);
       
        createFundManager();
       
        currencyFormatter = NumberFormat.getCurrencyInstance();
        String currencyOut = currencyFormatter.format(0);
        status.setText(msg + currencyOut);
       
        pack();
        show();
    }

    private void buildGUI() {
        GridBagLayout gl = new GridBagLayout();
        GridBagConstraints gc = new GridBagConstraints();
        Container container = getContentPane();
        container.setLayout(gl);
       
        gc.fill = GridBagConstraints.BOTH;
        JLabel label = new JLabel("Enter Amount");
        gl.setConstraints(label,gc);
        container.add(label);
       
        gc.gridwidth = GridBagConstraints.REMAINDER;
        gl.setConstraints(amount,gc);
        container.add(amount);
       
        gl.setConstraints(addFunds,gc);
        container.add(addFunds);
        gl.setConstraints(withdrawFunds,gc);
        container.add(withdrawFunds);
       
        status = new JLabel(msg);
        gl.setConstraints(status,gc);
        container.add(status);
    }

    public void createFundManager(){
        try {
            Properties prop = new Properties();
            prop.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
            prop.put(Context.PROVIDER_URL,"localhost:1099");
            Context initial = new InitialContext(prop);
            Object objref = initial.lookup("ejb/StatelessFundManager");//JINI-Name
            StatelessFundManagerHome home =
                (StatelessFundManagerHome) PortableRemoteObject.narrow(objref,StatelessFundManagerHome.class);
            manager = home.create();
        } catch (ClassCastException e) {
            e.printStackTrace();
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        } catch (CreateException e) {
            e.printStackTrace();
        }
    }

    public void actionPerformed(ActionEvent e) {
       
       
       
        if (e.getActionCommand().equalsIgnoreCase("Withdraw Funds")) {
            System.out.println("Withdraw Funds");
        }
        if (e.getActionCommand().equalsIgnoreCase("Add Funds")) {
            System.out.println("Add Funds");
        }
       
        if (e.getSource().equals(addFunds)){
            System.out.println("addFunds");
            try {
                status.setText(msg + currencyFormatter.format(manager.addFunds(0,Double.parseDouble(amount.getText()))));
            } catch (NumberFormatException e1) {
                e1.printStackTrace();
            } catch (RemoteException e1) {
                e1.printStackTrace();
            }
        }
        if (e.getSource().equals(withdrawFunds)){
            System.out.println("withdrawFund");
            try {
                status.setText(msg + currencyFormatter.format(manager.withdrawFunds(100,Double.parseDouble(amount.getText()))));
            } catch (NumberFormatException e1) {
                e1.printStackTrace();
            } catch (RemoteException e1) {
                e1.printStackTrace();
            } catch (InsufficientBalanceException e1) {
                e1.printStackTrace();
            }
        }
    }

}
    然后,你可以运行该程序进行测试了:
     
    至此,恭喜你,你已经大功告成,基本上对EJB建立了感性的认识,可以参考资料进行深入的学习了。

posted @ 2006-02-04 20:17 qiyadeng 阅读(734) | 评论 (0)编辑 收藏

   今天是大年的初一,新年的第一天!!!祝所有的朋友春节快乐,狗年旺旺(好像关于狗年的贺词不多)!也希望自己新的一年来进步多多,有所作为。

posted @ 2006-01-29 22:50 qiyadeng 阅读(265) | 评论 (0)编辑 收藏

因为需要对网络环境进行监控,做了个Java程序在linux服务器上运行。但是每次重新启动的时候都要手动的运行,这样就不太现实。所以想到把Java程序做成像Windows的系统服务那样,开机就会自动在后台运行。以前使用过一个工具http://javaservice.objectweb.org/,可以把Java程序注册成为Windows的系统服务,而且使用起来很简单,但是遗憾的是该工具不能注册linux的后台服务。所以不得不另外寻找工具。

 

   最后找到了JavaService Wrapper(http://wrapper.tanukisoftware.org/doc/english/introduction.html),该工具能在很多中平台下面注册为系统服务(查看支持平台)。该工具使用方法有三种模式,我用的是第一种WrapperSimpleApp帮助类,另外的两种方式都需要在原来的程序上进行适当的编码。下面就用我的程序NetWatchDog为例子说明下大概的配置步骤。(其实文档中已经用Jboss进行了演示)

 

1.建立一个目录名为NetWatchDog,并在该目录下建立bin,lib,conf,logs目录。以下把NetWatchDog目录称为$DOG_HOME。

2.把下载来的文件解压,把$WRAPPER_HOME/bin/wrapper,$WRAPPER_HOME/src/bin/sh.script.in文件copy到$DOG_HOME/bin目录中。

3.把sh.script.in文件该名为你的服务名称,这里改为NetWatchDog。

4.编辑NetWatchDog,把Application的相关信息改为如下:

APP_NAME="NetWatchDog"
APP_LONG_NAME="NetWatchDog Application"

5.把你的程序的打包成jar文件,拷贝到$DOG_HOME/lib目录下,并把$WRAPPER_HOME/lib/libwrapper.so,$WRAPPER_HOME/lib/wrapper.jar文件也拷贝到$DOG_HOME/lib目录下面。

6.这步比较重要是成败的关键,把$WRAPPER_HOME/conf/wrapper.conf文件拷贝到$DOG_HOME/conf目录下(文档上面说的是wrapper.conf.in文件,但是我下载来的文件就是wrapper.conf,所以步需要改名的)。

7.编辑wrapper.conf文件:

#java命令的位置

wrapper.java.command=%JAVA_HOME%/bin/java

#wrapper的主类

wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp

#java classpath

wrapper.java.classpath.1=../lib/wrapper.jar
wrapper.java.classpath.2=%JAVA_HOME%/jre/lib/ext/log4j-1.2.13.jar
wrapper.java.classpath.3=%JAVA_HOME%/jre/lib/ext/activation.jar
wrapper.java.classpath.4=%JAVA_HOME%/jre/lib/ext/commons-email-1.0.jar
wrapper.java.classpath.5=%JAVA_HOME%/jre/lib/ext/mail.jar
wrapper.java.classpath.6=../lib/NetWatchDog.jar
#你的程序的主类,将作为wrapper的参数

wrapper.app.parameter.1=qiya.deng.main.Main

8.这样基本就大功告成了,现在可以运行命令./NetWatchDog  start,如果提示权限不够就用chmod 755 NetWatchDog命令改变权限。如果没出现错误提示,这样基本上就正确了。
另外Windwos版本可以参考:http://blog.chinaunix.com/u/1677/?u=http://blog.chinaunix.com/u/1677/showart.php?id=67084

posted @ 2006-01-25 09:34 qiyadeng 阅读(5952) | 评论 (3)编辑 收藏

仅列出标题
共9页: 上一页 1 2 3 4 5 6 7 8 9 下一页