posts - 97,  comments - 93,  trackbacks - 0
  2006年5月8日
Rank 1:


       SIGMOD: ACM SIGMOD Conf on Management of Data
       PODS: ACM SIGMOD Conf on Principles of DB Systems
       VLDB: Very Large Data Bases
       ICDE: Intl Conf on Data Engineering

       CIKM: Intl. Conf on Information and Knowledge Management
       ICDT: Intl Conf on Database Theory


Rank 2:

SSD: Intl Symp on Large Spatial Databases
DEXA: Database and Expert System Applications
FODO: Intl Conf on Foundation on Data Organization
EDBT: Extending DB Technology
DOOD: Deductive and Object-Oriented Databases
DASFAA: Database Systems for Advanced Applications
SSDBM: Intl Conf on Scientific and Statistical DB Mgmt
CoopIS - Conference on Cooperative Information Systems
ER - Intl Conf on Conceptual Modeling (ER)


参考 http://www3.ntu.edu.sg/home/assourav/crank.htm

posted @ 2009-09-25 00:02 wqwqwqwqwq 阅读(271) | 评论 (0)编辑 收藏
     摘要: That’s why I don’t want to hear people’s ideas.
I’m not interested until I see their execution.  阅读全文
posted @ 2008-08-11 11:21 wqwqwqwqwq 阅读(1295) | 评论 (1)编辑 收藏
     摘要: 这两天在学习python,主要参考简明教程http://www.swaroopch.com/byteofpython/ , 入门很不错,有兴趣推荐参考。
在16章中,作者建议读者写一个地址簿程序,还记得写它都是在大一学c语言的年代了,不过下午还是抽出了一点时间来写这个程序,写了两个版本,一个是使用python 字典来存储名字和地址,另一个版本则使用python的面向对象特性,来链式存储联系人对象。  阅读全文
posted @ 2008-07-24 17:51 wqwqwqwqwq 阅读(1549) | 评论 (3)编辑 收藏
     摘要: 据说最近psp最近要升值了~无论是因为破解的原因还是什么,但总之估计sony还是很难想到,当然我们也很值得庆幸的是这帮hack的大牛已然将kvm,python stackless等移植到了psp平台,强大的ppc支持,可足以媲美几年前的personal computer,这一点毋庸置疑,更不用去与手机平台相对比了。  阅读全文
posted @ 2008-07-24 12:21 wqwqwqwqwq 阅读(2493) | 评论 (4)编辑 收藏
     摘要: org.eclipse.jface.viewers.TreeViewer

的继承关系是  阅读全文
posted @ 2008-04-23 00:10 wqwqwqwqwq 阅读(4826) | 评论 (3)编辑 收藏
目前 ext已经全面升级了主站,而且也release2.1版本,并新增了一些例子。
最近发布的Firefox3 beta 5版本,个人认为还是比较不错,运行JS的也更快、上网速度也快了很多。
但经原来做的一些js程序测试,ext2.0版本运行在FF3Beta5上还存在一些显示问题。

posted @ 2008-04-22 12:50 wqwqwqwqwq 阅读(1458) | 评论 (1)编辑 收藏
     摘要: 昨天写了个关于图库的总结mail 在这贴下,以供参考,当然望不吝赐教  阅读全文
posted @ 2008-04-21 18:09 wqwqwqwqwq 阅读(1416) | 评论 (0)编辑 收藏
     摘要: 前两天写了一个处理逻辑表达式的小程序,可以用来处理专家系统实事等逻辑关系表达式。  阅读全文
posted @ 2008-02-26 19:05 wqwqwqwqwq 阅读(2578) | 评论 (2)编辑 收藏
     摘要: EasyMock 是一套通过简单的方法对于指定的接口或类生成 Mock 对象的类库,它能利用对接口或类的模拟来辅助单元测试。本文将对 EasyMock 的功能和原理进行介绍,并通过示例来说明如何使用 EasyMock 进行单元测试。   阅读全文
posted @ 2008-02-18 22:14 wqwqwqwqwq 阅读(741) | 评论 (0)编辑 收藏
     摘要: Craigslist的网站上没有图片,只有密密麻麻的文字,标着各种生活信息,是个巨大无比的网上分类广告加BBS的组合...  阅读全文
posted @ 2008-01-21 13:06 wqwqwqwqwq 阅读(2530) | 评论 (0)编辑 收藏
posted @ 2007-12-25 20:25 wqwqwqwqwq 阅读(433) | 评论 (0)编辑 收藏
     摘要: Trie树是一棵度 m ≥ 2 的树,它的每一层分支不是靠整个关键码的值来确定,而是由关键码的一个分量来确定。  阅读全文
posted @ 2007-12-13 20:07 wqwqwqwqwq 阅读(1734) | 评论 (0)编辑 收藏
     摘要: For myself learning.
Personal Mastery  阅读全文
posted @ 2007-12-09 18:28 wqwqwqwqwq 阅读(1455) | 评论 (3)编辑 收藏
     摘要: Have you read Jess In Action by Earnest J. Freedman-Hill? It's one of the better books out there on rule engines, though it does require some experience to get the most out of the book.
A variation on the bookstore could be recommendation engine. That would provide an opportunity to use a rule engine for direct matching on category/subcategory and aggregations.  阅读全文
posted @ 2007-11-29 10:42 wqwqwqwqwq 阅读(970) | 评论 (5)编辑 收藏
     摘要: IBM Dump Analyzer for Java是来分析虚拟机稳定性的一种可扩展框架。对Java虚拟机生成的产物进行自动诊断。  阅读全文
posted @ 2007-11-16 15:36 wqwqwqwqwq 阅读(1243) | 评论 (1)编辑 收藏
     摘要: 实在忍受不了sun的做事风格和它的开发工具了,nb的beta6一踏糊涂一堆bug,唉~想着就想起来sun中国弄个nb插件的比赛不仅过程糟糕,获奖了居然还不兑现承诺,到现在也杳无音信,估计是证书也不想发了,真是让大家对它越发感到没有信心~~~~~~~~~不提这个了,还是讲讲Europa 和 myeclipse, 最近在写一个基于规则的引擎,用的Europa 和myeclipse6 感觉非常舒服,myeclipse的功能也大大加强了比如改进了javaEE5 提高了EJB3开发效率可以支持从数据模型到bean的转换,java的持久化程度及其Spring-JPA的高度集成。开发ajax的朋友可以发现 myeclipse对ajax的开发和测试做的也非常好,尤其是对js的调试。Web开发的另一个特点是支持RAD web。nb原来喊的一项特色是集成了matisse,在myeclipse目前也集成了它而且对于可视化swing开发非常方便,当然你也可以自己按照,不直接更新。
myeclipse中集成的derby和tomcat也大大加速了服务器的连接和部署,调试等。至于db视图个人使用oracle  阅读全文
posted @ 2007-11-11 15:11 wqwqwqwqwq 阅读(2243) | 评论 (11)编辑 收藏
     摘要: Given a picture composed entirely of horizontal and vertical line segments, calculate the minimum number of times you must lift your pen to trace every line segment in the picture exactly n times.
Each line segment will be of the form " " (quotes for clarity), representing a segment from (x1,y1) to (x2,y2). Segments may cross each other. Segments may also overlap, in which case you should count the overlapping region as appearing in the drawing only once. For example, say t  阅读全文
posted @ 2007-10-30 21:36 wqwqwqwqwq 阅读(1183) | 评论 (0)编辑 收藏
     摘要: In most states, gamblers can choose from a wide variety of different lottery games. The rules of a lottery are defined by two integers (choices and blanks) and two boolean variables (sorted and unique). choices represents the highest valid number that you may use on your lottery ticket. (All integers between 1 and choices, inclusive, are valid and can appear on your ticket.) blanks represents the number of spots on your ticket where numbers can be written.  阅读全文
posted @ 2007-10-24 21:20 wqwqwqwqwq 阅读(1202) | 评论 (1)编辑 收藏
     摘要:
Let's say you have a binary string such as the following:
011100011
One way to encrypt this string is to add to each digit the sum of its adjacent digits. For example, the above string would become:
123210122  阅读全文
posted @ 2007-10-23 13:34 wqwqwqwqwq 阅读(1050) | 评论 (1)编辑 收藏
     摘要: People enjoy mazes, but they also get them dirty. Arrows, graffiti, and chewing gum are just a few of the souvenirs people leave on the walls. You, the maze keeper, are assigned to whiten the maze walls. Each face of the wall requires one liter of paint, but you are only required to paint visible faces. You are given a map of the maze, and you must determine the amount of paint needed for the job.  阅读全文
posted @ 2007-10-21 21:28 wqwqwqwqwq 阅读(1457) | 评论 (1)编辑 收藏
     摘要: In written languages, some symbols may appear more often than others. Expected frequency tables have been defined for many languages. For each symbol in a language, a frequency table will contain its expected percentage in a typical passage written in that language. For example, if the symbol "a" has an expected percentage of 5, then 5% of the letters in a typical passage will be "a". If a passage contains 350 letters, then 'a' has an expected count of 17.5 for that passage (17.5 = 350 * 5%). Pl  阅读全文
posted @ 2007-10-21 20:14 wqwqwqwqwq 阅读(913) | 评论 (1)编辑 收藏
     摘要: A speed radar is installed in a highway zone where the maximum speed limit is maxLimit mph, and the minimum speed limit is minLimit mph.  阅读全文
posted @ 2007-10-20 13:25 wqwqwqwqwq 阅读(1258) | 评论 (1)编辑 收藏
     摘要: 好长时间没写程序了感觉,忘了很多东西,呵呵,今天打开Eclipse写了一个Struts的小应用,也回顾了一遍它的主要内容,这篇随笔就把整理的一些东西贴出来吧。  阅读全文
posted @ 2007-10-07 16:55 wqwqwqwqwq 阅读(1004) | 评论 (0)编辑 收藏
     摘要: 本程序为优化,比较好的方法是,进行曲线积分,算误差比进行方程约束,由于时间比较少,稍候会给出优化程序。  阅读全文
posted @ 2007-08-14 17:27 wqwqwqwqwq 阅读(1001) | 评论 (0)编辑 收藏
     摘要: A simple implement of own stack  阅读全文
posted @ 2007-08-03 18:14 wqwqwqwqwq 阅读(992) | 评论 (0)编辑 收藏
     摘要: To find a max segment in a array which includes negative and positive no.There r several methods to solve this question.  阅读全文
posted @ 2007-07-31 12:45 wqwqwqwqwq 阅读(840) | 评论 (0)编辑 收藏
     摘要: 今天很早的来到公司,首先查收了一下邮箱,发现5封新邮件,仔细的看了下都是关于我前天申请一个IBM USA那边的一个DB访问权限的邮件。  阅读全文
posted @ 2007-07-27 08:55 wqwqwqwqwq 阅读(290) | 评论 (2)编辑 收藏
     摘要: Sun has just announced the winners of netbeans plugin competition  阅读全文
posted @ 2007-07-21 23:34 wqwqwqwqwq 阅读(1133) | 评论 (0)编辑 收藏
PMI
     摘要: PMI(Performance MonitoringInfrastructure)   阅读全文
posted @ 2007-07-13 17:32 wqwqwqwqwq 阅读(1182) | 评论 (2)编辑 收藏
there r so many sundries during these days and almost every point is focussing on papers\projects\ ...\recommending data for my next master degree, but my thought just is in a mess, i cannot describe the stage && status except paying more attention,well,just feeling time is out of my hand.the only thing I am looking forward is the result of nb plugin competition and i will send the request and willing letter to the professors later but then.I m believing that though  have lost the opportunity of my target ~~God, it's so pity for a sudden change,at the same time, I stood with everything.I have got another time now and have prepared all the condition for the coming applying.thx in advance for my friends, because u have give a stage and some suporting.especially to stand^-^.TracyYan now has just rushing in && strangely,I find~~~~after six years,why not then, I have also no answers, may be pretty but not really for the feeling,~~~~~.
Yestoday I have collected some data about computer science department professors of pku, bless.
benny is a so kind person though he(she is a judge, but i really want to say,actually not to him.here the only puzzlement is why now after a month asking the method how to use the tool and why dont know the document which has contains all the info he want to know, I know, really, each guy is busy, busy with one's sundries,so many! Symptom.


posted @ 2007-07-11 22:19 wqwqwqwqwq 阅读(522) | 评论 (0)编辑 收藏
     摘要: 首先说点别的:),今天google adsense给我回信关于blog头搜索不好用的原因是嵌在了里。我评论的前两条是表扬google...  阅读全文
posted @ 2007-06-02 23:16 wqwqwqwqwq 阅读(1513) | 评论 (8)编辑 收藏
     摘要: 好长时间没写随笔了^^,主要是因为这几天很忙,ibm的、学校的、还有sun的插件大赛,但是这段时间自己确一直在学习,在继续关注技术的进展,随着这篇关注焦点,在之后的几天里,我会继续写一些,IBM SOA、SOAP、RBD、EGL还有我们HotJava的 SmallWorld等内容。
JavaFX当前是备受SUN推崇和重点推广的项目之一,也是Java技术继续演化的内容之一。  阅读全文
posted @ 2007-05-31 11:03 wqwqwqwqwq 阅读(1218) | 评论 (0)编辑 收藏
     摘要: 今天浏览网页,看见篇写JNDI比较基础,也比较详细的文章,又自己整理了一下,post到新手区了,。。。。:)JNDI是java访问名字和目录服务的接口,与JDBC一样,它仅仅只定义了一套服务接口,实现由具体厂商提供。作为j2ee核心组件之一,它为应用程序查找其他程序组件和资源提供了统一的接口,其中最常见的用途就是数据源的配置、EJB名字查找、JMS相关配置等。JNDI的架构如下图。在JDK1.3中...  阅读全文
posted @ 2007-05-14 23:33 wqwqwqwqwq 阅读(812) | 评论 (0)编辑 收藏
ITM
     摘要: 开篇,哈哈哈,我喜欢这句话“NO MONEY ONLY WORK DADADI”。
ITM provides out of box uses to quickly deploy and active the app with the best ibm practice.admins can define the user's views,threshold and so on.Tivoli Enterprise Monitoring Agents are available for monitoring different types of platforms and applications, including mainframes,middleware,distributed,and database...  阅读全文
posted @ 2007-05-11 23:00 wqwqwqwqwq 阅读(954) | 评论 (0)编辑 收藏
     摘要: CLI command line interface ...  阅读全文
posted @ 2007-05-10 23:23 wqwqwqwqwq 阅读(985) | 评论 (0)编辑 收藏
     摘要: 据说极有可能迅速取代目前流行的SWING和SWT技术。  阅读全文
posted @ 2007-05-07 22:30 wqwqwqwqwq 阅读(985) | 评论 (1)编辑 收藏
北京今天有些风,但是依然挡不住本有的闷热。傍晚下楼吃饭,就像突然走进蒸笼一样的感觉,想象着眼前如果是大海该多好啊,说到这真是惭愧,我在大连待了20多年,居然不会游泳,哎~...吃完饭,我从上地佳园溜达到公司,休息了一下。本想着看点书,但是这个时候似乎是快到下班的时间了,看着白领一族的匆匆离去、联想围栏旁悠然自得的粉刷小匠,我突然萌生要离开这儿,去高校转转的念头。
绕过DASCOM沿着信息路来到了五街,在路牌下等者656...我真的实在受不了了太阳的直射和等车的烦躁,终于决定今天也学一次抗日前的长征,学一次开学前的军训,...自己走到北大,也算熟悉熟悉一路的环境。现在回来我真的发现这是一个了不起的决定,因为这实在太累,走去五环-北大-四环,又跑回上地,即使在地图上只能算作一指之距。想想先前走到北京体校时看见一个学生绕学校跑时的窃窃思绪,我更敬佩自己。脚累得很,但我也算是准备好了这段时间出门在外的辛苦...RuiRui,你说得很好,坚持久了,也就好了。

posted @ 2007-05-07 21:40 wqwqwqwqwq 阅读(441) | 评论 (0)编辑 收藏
     摘要: 今天自己突然想起来整理一下标准的charset,感觉还算有必要。当然java...  阅读全文
posted @ 2007-05-06 19:50 wqwqwqwqwq 阅读(611) | 评论 (0)编辑 收藏
昨天来得北京,准备我以后几个月的实习生活。北京还是和我原来来的感觉一样,到处都是人流车流,太阳总是离得很近,风吹起的扬尘让我透不过气...唯一使人感觉现代感的和不很疲惫的就是坐着北京的城铁和地铁,起码它们不会因为宣泄而停滞。有些安慰的是坐在IBM的办公大厅,我喜欢IT深邃的魅力,和品茶的悠然...
昨天一天十分疲倦,或许正如跟个远方的小弟在instantChat上所谈的,这一天真的让我品到了生活的很多酸涩和劳苦,我渐渐发现走路也是一件非常非常累得事情,渐渐发现与人相处的道理和囊中的羞涩。其实昨天一天就花了我3千多,房屋的中介赚得很多感觉,1200的房子,中介费也要得1200,还有押金。不过房子我到是感觉还好,在上地佳园,至少感觉这的环境和保安还算可以,只是与人合租,不是很自在。
昨天也累坏了我一个高中同学,她陪我到处转了一天,真的很谢谢她。
不知道下一步会如何,但是我得准备好在这煎熬闷热、运筹自己的生活、学会太多太多...

posted @ 2007-05-06 12:24 wqwqwqwqwq 阅读(432) | 评论 (0)编辑 收藏
     摘要: 这两天找了一些portal相关的资料,也从中学到了很多东西。据说我们学校还有个portal,不过现在不知为什么down掉了...  阅读全文
posted @ 2007-04-27 20:48 wqwqwqwqwq 阅读(2775) | 评论 (6)编辑 收藏
     摘要: Sun has rolled out the Temple of Sun Contest with a US$5,000 cash prize. This is a great vehicle to promote Sun Studio on campus.  阅读全文
posted @ 2007-04-24 11:00 wqwqwqwqwq 阅读(1351) | 评论 (2)编辑 收藏
ANT
     摘要: ANT是一个基于JAVA的自动化脚本引擎,脚本格式为XML。除了做JAVA编译相关任务外,ANT还可以通过插件实现很多应用的调用。  阅读全文
posted @ 2007-04-19 14:56 wqwqwqwqwq 阅读(242) | 评论 (0)编辑 收藏
     摘要: 软件开发习惯中一个细微更改都可能会对软件质量产生巨大改进。将单元测试合并到开发过程中,然后从长远角度来看它可以节省多少时间和精力。本文通过使用代码样本说明了单元测试的种种好处,特别是使用 Ant 和 JUnit 带来的各种方便。  阅读全文
posted @ 2007-04-19 14:52 wqwqwqwqwq 阅读(469) | 评论 (0)编辑 收藏
     摘要: 在Ant出现之前,构建和部署Java应用需要使用包括特定平台的脚本、Make文件、各种版本的IDE甚至手工操作的“大杂烩”。现在,几乎所有的开源 Java项目都在使用Ant,大多数公司的内部项目也在使用Ant。Ant在这些项目中的广泛使用自然导致了读者对一整套Ant最佳实践的迫切需求。  阅读全文
posted @ 2007-04-19 14:45 wqwqwqwqwq 阅读(480) | 评论 (0)编辑 收藏
     摘要: By the way,there is a tool,Sun Device Detection Tool ,which is based on jnlp protocol, can tell us in just a few minutes whether the Solaris OS supports the devices that are detected in our x86 system, in advance.  阅读全文
posted @ 2007-04-14 23:52 wqwqwqwqwq 阅读(1270) | 评论 (0)编辑 收藏
     摘要: 昨晚同学找我帮忙写一个利用GOOGLE API的小程序,也比较感兴趣所以就应下了。下载了GOOGLE提供的googleapi.jar,大约花了20多分钟,写了这个小程序,由于需要提供GOOGLE key所以也懒得去申请,就没有测试~~呵呵  阅读全文
posted @ 2007-04-14 15:22 wqwqwqwqwq 阅读(3556) | 评论 (9)编辑 收藏
     摘要: 元数据是利用JDBC创建和操作数据库对象的一个很重要的概念和应用,所以今天我特地的找了一些详细解析个概念的资料,和利用java来操作的实例。  阅读全文
posted @ 2007-04-12 23:58 wqwqwqwqwq 阅读(1715) | 评论 (0)编辑 收藏
出于java的安全限制,System.getProperty("line.seperator")是不能够直接取得的。可以这样做:
String lineSeparator = (String) java.security.AccessController.doPrivileged(
               
new sun.security.action.GetPropertyAction("line.separator"));
具体参考java.io.BufferedWriter的源代码就可以找到上面这行代码。 DriverManager里也有
 1     private static void loadInitialDrivers() {
 2         String drivers;
 3 
 4         try {
 5             drivers = (String) java.security.AccessController
 6                     .doPrivileged(new sun.security.action.GetPropertyAction(
 7                             "jdbc.drivers"));
 8         } catch (Exception ex) {
 9             drivers = null;
10         }
11         println("DriverManager.initialize: jdbc.drivers = " + drivers);
12         if (drivers == null) {
13             return;
14         }
15         while (drivers.length() != 0) {
16             int x = drivers.indexOf(':');
17             String driver;
18             if (x < 0) {
19                 driver = drivers;
20                 drivers = "";
21             } else {
22                 driver = drivers.substring(0, x);
23                 drivers = drivers.substring(x + 1);
24             }
25             if (driver.length() == 0) {
26                 continue;
27             }
28             try {
29                 println("DriverManager.Initialize: loading " + driver);
30                 Class.forName(driver, true, ClassLoader.getSystemClassLoader());
31             } catch (Exception ex) {
32                 println("DriverManager.Initialize: load failed: " + ex);
33             }
34         }
35     }
sun.security.action.GetPropertyAction() hasn't been publiced.actually and exactly,it's not be doced,which reflects that sun doesn't surport us to use these class or method which is lower class,usually, we use the classes api tells us is proier and maybe has called these undoc class  but usually for us ,it's not necessary.so in the program of us or even others ,we could and i think it's really better for us to neglect  them which u can find out in the jar file of rt.jar.

posted @ 2007-04-11 16:35 wqwqwqwqwq 阅读(560) | 评论 (0)编辑 收藏
     摘要: 可供程序利用的资源(内存、CPU时间、网络带宽等)是有限的,优化的目的就是让程序用尽可能少的资源完成预定的任务。优化通常包含两方面的内容:减小代码的体积,提高代码的运行效率。本文讨论的主要是如何提高代码的效率。  阅读全文
posted @ 2007-04-09 11:12 wqwqwqwqwq 阅读(465) | 评论 (0)编辑 收藏
1.变量引用的时候,空指针情况的防止,即为空检查.
2.数学运算异常,如除0的情况.数组越界异常,字符串访问过界
3.数据库检索记录,结果记录行数状况的处理.
4.画面显示项目的确认.
5.画面显示项目达到上限时情况的处理.
6.系统出错的时候,异常信息是否正确.
7.数据库连接,游标的处理.
8.数学运算时,数据精度的处理.
posted @ 2007-04-09 11:06 wqwqwqwqwq 阅读(213) | 评论 (0)编辑 收藏
Today with tomcat admin, a Graphic interface for us to config the JNDI for our program,I configured the context and connection pool jioning IBM DB2 ExC-9.Actually,JNDI is an API specified in Java technology that provides naming and directory functionality to applications written in the Java programming language. It is designed especially for the Java platform using Java's object model. Using JNDI, applications based on Java technology can store and retrieve named Java objects of any type. In addition, JNDI provides methods for performing standard directory operations, such as associating attributes with objects and searching for objects using their attributes (Name-Value,context).JNDI is also defined independent of any specific naming or directory service implementation. It enables applications to access different, possibly multiple, naming and directory services using a common API. Different naming and directory service providers can be plugged in seamlessly behind this common API. This enables Java technology-based applications to take advantage of information in a variety of existing naming and directory services, such as LDAP, NDS, DNS, and NIS(YP), as well as enabling the applications to coexist with legacy software and systems. Using JNDI as a tool, we can build new powerful and portable applications that not only take advantage of Java's object model but are also well-integrated with the environment in which they are deployed.
A directory is typically used to associate attributes with objects. A person object, for example, can have a number of attributes, such as the person's surname, fisrtName,telephone numbers, electronic mail address and so on. Using JNDI, to retrieve the email address of a person object, the code looks as follows.
1 Attribute personAttribute=directory.getAttributes(personName).get("email");
2 String email = (String)personAttribute.get();
(Recently,finding that blogjava can help us format our code,that's perfect,but if can max the editor area which will enhance the function and coursely be better:).)
An intuitive model for the Java programmer is to be able to lookup objects like printers and databases from the naming/directory service. Using JNDI, to lookup a printer object, the code looks as follows. (it's important and most used)
1 Printer printer =(Printer)namespace.lookup(printerName);
2 printer.print(document);

posted @ 2007-04-08 15:10 wqwqwqwqwq 阅读(466) | 评论 (0)编辑 收藏

//*******************The Log class
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.uitl.Date;
import java.text.DateFormat;

public class Log{
   private static final String filePath = PropertyReader.getResource("Log_File_Path");//Supposing we have define in the last ProperyReader class and the file
  
   public static final String EXCEPTION                  =   "Exception";
   public static final String CREATE_STAFF           =   "Create Staff";
   public static final String EDIT_STAFF                 =   "Edit Staff";
   public static final String DELETE_STAFF            =   "Delete Staff";
   public static final String RECORD_HAS_EXIST  =   "Record Has Exist";

   public static void log(String msg_type, Exception e){
      StringBuffer errMsg = new StringBuffer(e.toString);
     
      for(int i=0;i<e.getStackTrace().length;i++){
         errMsg.append("\n\t at");
         errMsg.append(e.getStackTrace()[i].toString);
      }
      log(msg_type,errMsg.toString());
      OptionPanel.showErrMsg("Sorry,System may have an error \n System will exit");
      System.exit(-1);
   }

  public static void log(String msg.type,Staff staff){
     String msg = null;
     if(msg_type == CREATE_STAFF){
         msg = staff.toString() + "has benn created";
     }else if(msg_type == EDIT_STAFF){
         msg = staff.toString() + "has been Changed";
     }else if(msg_type == DELETE_STAFF){
         msg = staff.toString() + "has been Deleted";
     }else if(msg_type == RECORD_HAS_EXIST){
         msg = staff.toString() + "has exist in the database";
     }
     log(msg_type,msg);
  }

  private static void log(String msg_type,String msg){
      BufferedWriter out = null;
      DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
     
      try{
        out = new BufferedWriter(new FileWriter(getLogFilePath(),true));//如果为 true,则将字节写入文件末尾处,而不是写入文件开始处
        out.write("["+df.format(new Date()) + "] <" + msg_type + "> :" + msg);
        out.newline();
        out.newline();
      }catch(IOException e){
          e.printStackTrace();
      }finally{
         try{
           if(out!=null){
              out.close();
           }
         }catch(IOException e){
            e.printStackTrace();
         }
      }
  }

  private static String getLogFilePath(){
     File logDir = new File(filePath);
     if(!logDir.exists()){
       logDir.mkdir();
     }
    
     int i = 1;
     String fileName = filePath + "log_";
     File file = new File(fileName + i + ".txt");
   
     while(file.exists() && file.length() > 30000L) {
         i++;
         file = new File(fileName + i + ".txt");
     }
   
      return fileName + i + ".txt"
  }
}

//*****************************The OptionPanel Dialog Class for the Log Class
import javax.swing.JOptionPane;

public class OptionPanel {
   private static final String appTitle = PropertyReader.getResource("App_Title");//suposing the file has been established and the property app-title stands for the name of application
   private static final MainFrame frame = MainFrame.getMainFrame();

   public static void showWarningMsg(String msg){
      JOptionPane.showMessageDialog(frame,msg,appTitle,JOptionPane.WARNING_MESSAGE);
   }
   public static void showErrMsg(String msg){
       JOptionPane.showMessageDialog(frame,msg,appTitle,JOptionPane.Error_MESSAGE);
   }
   public static int showConfirmMsg(String msg){
        return JOptionPane.showConfirmDialog(frame,msg,appTitle,JOptionPane.YES_NO_OPTON,JOptionPane.QUESTION_MESSAGE);
   }
}

posted @ 2007-04-05 10:01 wqwqwqwqwq 阅读(865) | 评论 (1)编辑 收藏

In a project, we can write a class to read the properties.As following,

import java.io.InputStream;
import java.io.IOException;
import java.util.Properties;

public class PropertyReader{
   private static Properties property = null;
  
   static{
      InputSteam stream = null;
      try{
        stream=PropertyReader.class.getResourceAsStream("/resource/properties.properties");
        property = new Properties();
        property.load(stream);
      }catch(IOException e){
          e.printStackTrace();
      }finally{
          if(stream != null){
             try{
                stream.close();
             }catch(IOException e){
                e.printStackTrace();
             }           
          }
      }
   }
   public static String getResource(String key){
     if(property == null){
       return null;// init error;
     }
     
     return property.getProperty(key);
   }
}

posted @ 2007-04-05 08:13 wqwqwqwqwq 阅读(478) | 评论 (0)编辑 收藏
These days I want to review some java classes and post them,cos i come to realize that i hava been coming to forget some of them, my god,Katrina,....:) it's really the sound,and u ? ...regarding MVC,cos be delayed, and may be will better.

List a class to use the title Properties.

import java.util.Properties;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FirstDayTestProperties {
   public static void main(String[] args) throws Exception{
       Properties ProTest = new Properties();
       String  fileName="PropertiesTest.properties";
      
       try{
          ProTest.setProperty("lastDir","C:\\PropertyTest");
          ProTest.store(new FileOutputStream(fileName),null);
       }catch(IOException e){
            e.printStackTrace();
       }

       try{
          FileInputStream inStream=new FileInputStream(fileName);
          ProTest.load(inStream);
          ProTest.list(System.out);
       }catch(FileNotFoundException e){
          e.printStackTrace();
       }
   }
}
The class I just write now without any testing,but i think it seems no errors:).Share.

posted @ 2007-04-04 21:32 wqwqwqwqwq 阅读(475) | 评论 (0)编辑 收藏
U may come across model view controller desigh pattern.It was first introduced by  Trygve Reenskaug. More details,MVC can be broken down into three elements.
<1>Module  Usually,in enterprise software,it presents the logic of the commercial bean.To the SE Swing GUI,it contains data and the rules that govern access to and updates of this data.
<2>View  It specifies exactly how the module data should be presented,changing with the model data.
<3>Controller   Controller defines all the methods connecting to the user action which are called by the View.
Especially,the model doesn't carry a reference to the view but instead uses an event-notification model to notify insteaded parties of a change.One of the consequences of this powerful design is that many views can have the same model.When a change in the data model occurs,each view is notified by a property change event and can change itself accordingly.Hence, the controller may mediate the data flow between the model and the view in both directions,which helps to more completely decouple the model from the view,and the controller may also provide the methods which effect the model's property changes for one or more views that are registered with it.

....Next,may be the two days after tomorrow ,I ll give a real example to explain this schema in details.......
posted @ 2007-03-26 23:16 wqwqwqwqwq 阅读(432) | 评论 (0)编辑 收藏
这几天忙忙乱乱的,也没顾及这个blog,其实说句实话,自己也好几天没在研究技术的东西了,只是在看看IBM的一些个产品,哎~所以今天还是没打算写写技术,只是来post自己这几天的一些琐琐碎碎。还算高兴的事情是自己的小队伍获得了国际数学建模竞赛2等奖,虽然不是很理想,但自己还是满足了,毕竟带的娘子(当然是除了我了)队伍实力不是很强,况且大过年的我原来的伙伴早飞回温暖的南方了。其实我本身早厌倦了那种比赛,不过还是比较欣赏美国人的精明和对中国人明知故犯的无奈,也许吧,其实还是要庆祝一下自己的最后一次这种竞赛...
这周学校组织无偿献血,虽然我并不在乎学校不给什么所谓的补偿,我也不会因为献血怎么怎么的就有所目的,只是感觉这种行为还算是对社会作出了一点贡献。最岖奇的是导员居然不让我献血,当然他的劝告算能让我接受,但是自己还是很固执的感觉,无奈的导员也只好应下了。哎~我这个人真是经不起别人的劝告发现,在好些个朋友的“吓唬”下,终于作出了心虚的妥协...哎~,不过也算给我的母亲一个很好的交代了。
不说这些令人扫兴的话题了,还有一件好事,就是跟我关系很铁的一个老师有了21个月的小宝宝,其实他才告诉我的,还是在网上。不过早应该猜到了,因为这几天就发现他“不误正业”,整天不在办公室,往家里一个劲的跑,不过在这里,虽然他不会知道,还是祝愿他博士论文顺利通过吧,双喜临门...
想早些休息了,Good night&& Good dream.
posted @ 2007-03-22 23:18 wqwqwqwqwq 阅读(437) | 评论 (0)编辑 收藏
刚刚看看过鲁豫有约的两期节目,是采访的年轻轻但身价过亿的李想、高燃、戴志和茅侃侃。其实,我并不因为他们的年轻或是很有钱,而感到任何诧异,但自己却很欣常他们各自所持有的信念和创业过程中对资金的运营勇气,我真的不知道随着他们事业的增长、社会的变更,他们还是否会是浪潮的宠儿、是否会和原来一样,对待更多的运营资本同样的保持清醒地头脑,但我还是很祝福他们...

看过之后,我的感触很深,在这个社会上,或许是因为随着一个人学历的渐渐增长,他也会变得懒惰,因为他再也不会像社会地位很卑微的人一样为生计担心,我本也相信,人在骨子里是懒惰的。其实,我自己也曾想过,以后能找个比较大的外企工作,几年之后一个月拿个几W块就ok了,然后就是一辈子平平淡淡的生活...:),或许我的思想还不够先进吧。他们的经历,也让我重新思考,说句实话,其实他们并没什么,只是在坎坷的社会中,为了自己的信念坚持了下来,并一直做到了现在。我想我也该在为别人打工的同时,定位自己的目标,并坚定的追求。高燃是我很佩服的一个人,完全是因为他的执著,无论是他考清华、追GirlFriend 还是去找投资人,最后到办好公司。人的天赋很重要,但我还是更喜欢执著...
posted @ 2007-03-18 23:32 wqwqwqwqwq 阅读(628) | 评论 (2)编辑 收藏
Yestoday night,CA coordinator emailed and phoned me for Sunstudio running and test the ping-home function,I m sorry that I really didn't know what's this really mean under Unix,I am not sure,maybe about to edit the file of host,but I just ping -s localhost,well,maybe another ip destination.more awful,I cannot run the #./SUNWspro/bin/f95, #./SUNWspro/bin/cc, #./SUNWspro/bin/CC...I have sent the first test result,and continue to learn more about it,but I m really sorry.

 


 


posted @ 2007-03-17 07:36 wqwqwqwqwq 阅读(161) | 评论 (0)编辑 收藏
The day before yestoday,I have received the intern offer letter from IBM CDL...to my surprise,cos of my little time,only can support 3-4ms.it's too absurd that when the assistant
ask my IdCard num,well,God,I forgot it...:) During the time,not so along,exactly,only a few days ago,I met a manager in the IBM(BJ)CRL,She is a very kind person,also a manager(i think),she has recommended me to her colleagues,which I really thank her.so yestoday,these persons phoned me and asked if wanted to do some QA jobs,if though,they knew that i was admired by CDL.To the manners,I think today I should take their phone test though I will not accept their opportunity as to my promise to the CDL,That's important I think.
Now I was a junior student,coming to realize that the campus life will be end,I was lucky I think,especailly about so many friends,can be ambassador of Sun Microsystems.lnc,can be a intern of IBM and so on.Now in my dream,hope that I can be a recommend student to get the master degree of tsingHua or BJUniversity this Sep.,then can go aboard for future research,last,back to the motherland to have a peace life,for which I will try my hard and best.
posted @ 2007-03-16 12:19 wqwqwqwqwq 阅读(462) | 评论 (0)编辑 收藏
Maybe,u are tied of Windows and come to thinking of trying Linux,so many good Operation Systems,like,Suse Redhat ...or Novell have all enterprise u might need,as well,support communities.well,it's true enough--Solaris is also available and as a OpenSolaris form with AMD and Intel friends,with a pretty community going && more and more third-party supporting.U may download the Solaris form www.opentech.org.cn, www.opensolaris.org, ...Sun.
I very like OpenSolaris not only its security,its creative,convinient...whereas,its all:).The Java Desktop is cool and we may also use click to operate,well,I like the terminal more.Now I use Solaris as a developer desktop,it integrates the Netbeans to develop Java which is also a excellent enviroment to develop others after u plug in,Sun Studio,a platform to develop C/C++ &&fortan,with sun compiler,efficient.If u think Solaris is too big and Enterprise-heavy,u will make a mistake,Solaris is very small but excellent perform,:),U can try urself.
yestoday i make a techtalk about Sun openSolaris and Java,C/C++ development under it in my campus(DaLian University of Technology).To my surprise There were more students from the  disrelated computer science Department,more,even more girls.I saw a Linux teachers attending,I was very pleased,cos of Solaris is sure to attract the fancy of the Linux users,at least,It's better in my...our's eyes.:),as following I attach some of pics of my tech-talking to share with u.
   
posted @ 2007-03-12 11:01 wqwqwqwqwq 阅读(606) | 评论 (0)编辑 收藏

Most developers have heard of, and possibly used, scripting languages such as Ruby, JavaScript, and Python. These dynamic languages are enjoying a resurgence in popularity, largely because of their flexibility and simplicity, and the productivity gains they promise.

Java 6 comes with built-in support for scripting languages. You can embed scripts in various scripting languages into your Java applications, passing parameters, evaluating expressions, and retrieving results. And you can do it all pretty seamlessly.

First of all, you obtain a new ScriptEngine object from a ScriptEngineManager, as shown here:

ScriptEngineManager manager = new ScriptEngineManager();

ScriptEngine engine = manager.getEngineByName("js");

Each scripting language has its own unique identifier. The "js" here means you're dealing with JavaScript.

Now you can start having some fun. Interacting with a script is easy and intuitive. You can assign scripting variables using the put() method and evaluate the script using the eval() method,. which returns the most recently evaluated expression processed by the script. And that pretty much covers the essentials. Here's an example that puts it all together:

engine.put("cost", 1000);
String decision = (String) engine.eval(
"if ( cost >= 100){ " +
"decision = 'Ask the boss'; " +
"} else {" +
"decision = 'Buy it'; " +
"}");
assert ("Ask the boss".equals(decision));

You can do more than just pass variables to your scripts— you can also invoke Java classes from within your scripts. Using the importPackage() function enables you to import Java packages, as shown here:

				

engine.eval("importPackage(java.util); " +
"today = new Date(); " +
"print('Today is ' + today);");

Another cool feature is the Invocable interface, which lets you invoke a function by name within a script. This lets you write libraries in scripting languages, which you can use by calling key functions from your Java application. You just pass the name of the function you want to call, an array of Objects for the parameters, and you're done! Here's an example:

				

engine.eval("function calculateInsurancePremium(age) {...}");
Invocable invocable = (Invocable) engine;
Object result = invocable.invokeFunction("calculateInsurancePremium",
new Object[] {37});

You actually can do a fair bit more than what I've shown here. For example, you can pass a Reader object to the eval() method, which makes it easy to store scripts in external files, or bind several Java objects to JavaScript variables using a Map-like Binding object. You can also compile some scripting languages to speed up processing. But you probably get the idea that the integration with Java is smooth and well thought-out.

posted @ 2007-03-07 21:49 wqwqwqwqwq 阅读(463) | 评论 (0)编辑 收藏
刚刚结束了IBM的电面,一个GG和JJ,问的主要问题都放在我的项目上了,尤其是Netbeans的插件。由于我申请的实习生,所以在之中也问了很多实习时间的问题,感觉IBM问问题很不含糊,甚至要问出几月几号......这一点可以说明IBM是一个很值得人去的地方。英文问题我感觉我答得不是很好,先问得IBM的文化之类的,之后居然问得IBM person惭愧啊 本来还知道几个的,一紧张都忘了。在角色兑换时,我问得我的表现,和职业生涯建议,好小子,他们居然还反问我职业生涯,说了一通......整个电面是从4:10-4:45,最后GG说面试表现还好,只是我能实习的时间比他们要求的时间要少,唉~~ 我的系主任啊,等待结果中....希望自己能去IBM体验一下蓝色巨人的风范吧。
posted @ 2007-03-02 17:05 wqwqwqwqwq 阅读(798) | 评论 (0)编辑 收藏
一会4:30要参加北京IBM研究院的一个电面,快到时间了,不免心里稍有些紧张,不知道先前积累的一点英语一会是否会奏效,呵呵,,,,不过,无论如何我会尽可能抓住这次来之不易的机会的。
posted @ 2007-03-02 14:44 wqwqwqwqwq 阅读(529) | 评论 (0)编辑 收藏
     摘要: This post had been writen long before,...but  阅读全文
posted @ 2007-02-15 23:36 wqwqwqwqwq 阅读(465) | 评论 (1)编辑 收藏
     摘要: Java SE 6.0(代号Mustang,野马)已经发布,详情请见 野马奔腾而出,Java SE 6 正式版发布 ,它给我们带来了哪些新的特性了。     首先,我们看看JDK 6.0包含了大量的JSR,分为四组,分别为:     在简化开发方面: 199: Compiler API...  阅读全文
posted @ 2007-02-08 11:18 wqwqwqwqwq 阅读(2030) | 评论 (1)编辑 收藏

前几天好不容易下到了JDK6mustang,今天恰好有时间升级了一下Netbeans默认的JDK版本。这里简单的说明一下升级的方法。如果我 们不修改Netbeans的属性,需要在JavaPlatform manager中加入另一版本的类库。新建工程后如果要修改类库,还需要修改项目的类库属性,现在通过修改默认的JDK类库,便可方便很多,更不需要重新 安装NB。

我的NB装在D盘中,可以在该路径找到文件D:\Netbeans-5.5\etc\Netbeans.conf,我们将原有的默认类库netbeans_jdkhome="D:\Java\jdk1.5.0_07"修改为 netbeans_jdkhome="D:\Java\jdk1.6.0"便轻松的完成了升级,当然在tools-〉JavaPlatform manager〉中当然也可以将我们惯用的D:\Java\jdk1.5.0_07加入为可选用类库。

posted @ 2007-01-30 23:01 wqwqwqwqwq 阅读(472) | 评论 (0)编辑 收藏
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>拖拽Demo</title>
<style type="text/CSS">
body

{

    margin:0px;

}

 

#aim

{

    position:absolute;

    width:200px;

    height:30px;

    border:1px solid #666666;

    background-color:#FFCCCC;

}

 

#sourceLayer, #cloneLayer

{

    position:absolute;

    width:300px;

    height:50px;

    border:1px solid #666666;

    background-color:#CCCCCC;

    cursor:move;

}

 

.docked

{

    display:none;

    filter:alpha(opacity=100);

}

 

.actived

{

    display:block;

    filter:alpha(opacity=70);

}

</style>

</head>

 

<body >

 

<div id="aim">locate</div>

<div id="sourceLayer" unselectable="off"><img src="http://www.baidu.com/img/logo.gif" alt="Drag Demo">Source of the demo</div>

<div id="cloneLayer" class="docked" unselectable="off"></div>


<script type="text/javascript" language="javascript">


var aim;

var sourceLayer;

var cloneLayer;

var aimX;

var aimY;

var orgnX;

var orgnY;

var draging = false;

var offsetX = 0;    

var offsetY = 0;    

var back;        

var thisX ;        

var thisY ;        

var time ;

var stepX ;        

var stepY ;       



 

function getLayer(inAim,inSource,inClone)

{

    aim = document.getElementById(inAim);

    sourceLayer = document.getElementById(inSource);

    cloneLayer = document.getElementById(inClone);

}

 

function initDrag(initAimX,initAimY,initOrgnX,initOrgnY)

{

    aimX = initAimX;

    aimY = initAimY;

    orgnX = initOrgnX;

    orgnY = initOrgnY;

    aim.style.pixelLeft = aimX;

    aim.style.pixelTop = aimY;

    sourceLayer.style.pixelLeft = orgnX;

    sourceLayer.style.pixelTop = orgnY;

    cloneLayer.style.pixelLeft = orgnX;

    cloneLayer.style.pixelTop = orgnY;

}


function BeforeDrag()

{

    if (event.button != 1)

    {

        return;

    }

    cloneLayer.innerHTML = sourceLayer.innerHTML; 容

    offsetX = document.body.scrollLeft + event.clientX - sourceLayer.style.pixelLeft;

    offsetY = document.body.scrollTop + event.clientY - sourceLayer.style.pixelTop;

    cloneLayer.className = "actived";

    draging = true;

}



function OnDrag()

{

    if(!draging)

    {

        return;

    }

    event.returnValue = false;

    cloneLayer.style.pixelLeft = document.body.scrollLeft + event.clientX - offsetX;

    cloneLayer.style.pixelTop = document.body.scrollTop + event.clientY - offsetY;

}

function EndDrag()

{

    if (event.button != 1)

    {

        return;

    }

    draging = false;

 

    if (event.clientX >= aim.style.pixelLeft && event.clientX <= (aim.style.pixelLeft + aim.offsetWidth) &&

        event.clientY >= aim.style.pixelTop && event.clientY <= (aim.style.pixelTop + aim.offsetHeight))

    {


        sourceLayer.style.pixelLeft = aim.style.pixelLeft;

        sourceLayer.style.pixelTop = aim.style.pixelTop;

         cloneLayer.className = "docked";



    }

    else

    {

     thisX = cloneLayer.style.pixelLeft;

     thisY = cloneLayer.style.pixelTop;

     offSetX = Math.abs(thisX - orgnX);

     offSetY = Math.abs(thisY - orgnY);

     time = 500;

     stepX = Math.floor((offSetX/time)*20);

     stepY = Math.floor((offSetY/time)*20);

     if(stepX == 0)

         stepX = 2;

     if(stepY == 0)

         stepY = 2;

     moveStart();

    }   

}

 

 

function moveStart()

{

     back = setInterval("MoveLayer();",15);

}

 

function MoveLayer()

{


     if(cloneLayer.style.pixelLeft <= orgnX && cloneLayer.style.pixelTop <= orgnY)

     {

         cloneLayer.style.pixelLeft += stepX;

         cloneLayer.style.pixelTop += stepY;


         if(cloneLayer.style.pixelLeft > orgnX)

         {

              stepX = 1;

         }

         if(cloneLayer.style.pixelTop > orgnY)

         {

              stepY = 1;

         }

         //if the coordinate of X Y  are  same

         if(cloneLayer.style.pixelLeft == orgnX)

         {

              stepX = 0;

         }

         if(cloneLayer.style.pixelTop == orgnY)

         {

              stepY = 0;

         }

         if(cloneLayer.style.pixelLeft == orgnX && cloneLayer.style.pixelTop == orgnY)

         {

              EndMove();

         }

     }

    

     //locate to the downleft of the object

     else if(cloneLayer.style.pixelLeft <= orgnX && cloneLayer.style.pixelTop >= orgnY)

     {

         cloneLayer.style.pixelLeft += stepX;

         cloneLayer.style.pixelTop -= stepY;

         if(cloneLayer.style.pixelLeft > orgnX)

         {

              stepX = 1;

         }

         if(cloneLayer.style.pixelTop < orgnY)

         {

              stepY = 1;

         }

         if(cloneLayer.style.pixelLeft == orgnX)

         {

              stepX = 0;

         }

         if(cloneLayer.style.pixelTop == orgnY)

         {

              stepY = 0;

         }

         if(cloneLayer.style.pixelLeft == orgnX && cloneLayer.style.pixelTop == orgnY)

         {

              EndMove();

         }

     }



     else if(cloneLayer.style.pixelLeft >= orgnX && cloneLayer.style.pixelTop <= orgnY)

     {

         cloneLayer.style.pixelLeft -= stepX;

         cloneLayer.style.pixelTop += stepY;

         if(cloneLayer.style.pixelLeft < orgnX)

         {

              stepX = 1;

         }

         if(cloneLayer.style.pixelTop > orgnY)

         {

              stepY = 1;

         }

         if(cloneLayer.style.pixelLeft == orgnX)

         {

              stepX = 0;

         }

         if(cloneLayer.style.pixelTop == orgnY)

         {

              stepY = 0;

         }

         if(cloneLayer.style.pixelLeft == orgnX && cloneLayer.style.pixelTop == orgnY)

         {

              EndMove();

         }

     }

    

     //locate to the right of the object

     else if(cloneLayer.style.pixelLeft >= orgnX && cloneLayer.style.pixelTop >= orgnY)

     {

         cloneLayer.style.pixelLeft -= stepX;

         cloneLayer.style.pixelTop -= stepY;

         if(cloneLayer.style.pixelLeft < orgnX)

         {

              stepX = 1;

         }

         if(cloneLayer.style.pixelTop < orgnY)

         {

              stepY = 1;

         }

         if(cloneLayer.style.pixelLeft == orgnX)

         {

              stepX = 0;

         }

         if(cloneLayer.style.pixelTop == orgnY)

         {

              stepY = 0;

         }

         if(cloneLayer.style.pixelLeft == orgnX && cloneLayer.style.pixelTop == orgnY)

         {

              EndMove();

         }

     }

    

     //to the design

     else

     {

         EndMove();

     }

}

 

//stop and then back to the state ()carton

function EndMove()

{

         sourceLayer.style.pixelLeft = orgnX;

         sourceLayer.style.pixelTop = orgnY;

         cloneLayer.style.pixelLeft = orgnX;

         cloneLayer.style.pixelTop = orgnY;

         cloneLayer.className = "docked";

         clearInterval(back);

}

 

//Main function of this demo

function startDraging(inAim,inSource,inClone,initAimX,initAimY,initOrgnX,initOrgnY)

{

    getLayer(inAim,inSource,inClone)

    initDrag(initAimX,initAimY,initOrgnX,initOrgnY);

    sourceLayer.onmousedown = BeforeDrag;

    document.onmousemove = OnDrag; //if we use cloneLayer,then the content will be draged ,and well a bug

    cloneLayer.onmouseup = EndDrag;   

}

 

//transfer

startDraging("aim","sourceLayer","cloneLayer",600,500,50,50);

//-->

</script>

</body>

</html>
posted @ 2007-01-29 14:42 wqwqwqwqwq 阅读(630) | 评论 (0)编辑 收藏
As beginning,still don't know how to begin this post~but really should begin to write something about tech.Sometimes some one like to talk that A good bazoo can
make a good bussiness card~,may be so,may be not,I really want to throw it away,but cannot,just can to learn and write ...off topics...
  From now I propose to write a route about js tech with my learning steps.Ajax is a good thing maybe the world just like it some good but really short. Js is called for the full JavaScriptlanguage,it's welcomed because it can be run at the piont of client and also effective.when we talk about java object orientation is the focus piont which attracts our attention.we can define a class and then a function.But to JS ,when we create a function and make a instance of this function,we just regard it as a class,so we may say a newable function was a class.The class may have its own attributes or methods,but now we can use the sign["~"]to quote it(refer to).
Now I give a simple example about this
{449D36E0-28B6-4914-B96E-37606AA5E247}.BMP
Of course,u can express with arr.push("Eric").After this,I want to say,we can insert,update & delete attributes or methods when we need.As following
user.name="Eric";
user.age="21";
user.sex="male";
//we insert 3 Atts/
user.show=function(){
  alert("Name is"+this.name);
}
//we insert 1 Mes/
delete is very very easy,a old story.. we use undefined
user.name=undefined;
user.show=undefined;
//....
This is js today's post,easiness goes,.~ ..
posted @ 2007-01-27 23:17 wqwqwqwqwq 阅读(632) | 评论 (0)编辑 收藏
I/O
java的i/o恐怕是java体系里最复杂的内容之一了,有时候这个之一可以去了。不像c语言一个fopen()就可以解决一大堆问题。到了java 呢,又是stream又是reader,读一个文件的方式不下十种,造成很多人因此而放弃了java,当初刚学java的时候班里很多人都对java有很 高的热情,可到了现在,不知道还有多少人坚持下来了。具有讽刺意味的事java i/o的设计者的初衷是让i/o变得简单一点,哪知道若干年后,弄出这么一大摊子来。现在又加了一个nio----就是newio,不知道日后还会弄出什 么东西来。
 
用i/o可以解决文件,网络通讯等几乎所io问题。功能强大,唯一的缺点就是复杂。但仔细一分析,还是有门路可走的。整个io体系主要分为两大门派。一派 为流类也就是用于字节的InputStream和OutputStream,另一派为用于字符的Reader和Writer派(简称rw派)。认清了这两 派就知道*Stream的东东全都是流派的,不是继承而来就是通过实现接口而来。如此,*Reader,*Writer那就是出身于rw派了。还有一个 File派来处理文件创建,删除,修改,属性问题。对文件的内容进行操作不是他的工作。搞清楚这两大派一小派那么解决io指日可待。
 
那么说了这么多怎么创建文件呢?举例说明(主函数就不写了)
File newfile = new File("text.txt");
newfile.createNewFile();
这样就在同一个文件夹下创建了一个名为text.txt的文本文件,那枚怎么删除呢?
File newfile = new File("text.txt");
newfile.delete();
这样就把这个文件删除了。是不是很简单呢。那么怎么把文件写入这个文本文件呢?
File writetext = new File("text.txt");
[readtext.createNewFile();]//可有可无,因为文件不存在的话,会自动创建
FileWriter fw = new FileWriter(writetext);//就像创建打印机
PrintWriter pw = new PrintWriter(fw);//这个呢打印针头了。
pw.println("this is a new file for read");//这个是说,把这些东西给我写进去吧
fw.close();//然后关闭打印机
有点复杂,当懂了以后,也就感觉不到什么了,那么如何读取这个文本文件呢?
File readtext = new File("text.txt");
FileReader fr = new FileReaer(readtext);//创建一个扫描仪
BufferedReader br = new BufferedReader(fr);//这是扫描仪内的缓存
String content = br.readLine(); //读一行文本
 
用熟练了之后可以这么写:
BufferedReader in = new BufferedReader(new FileReader("text.txt");
String content="";
while((content=in.readLine())!=null){
    System.out.println(content);//读一行输出一行
}
posted @ 2006-12-04 13:27 wqwqwqwqwq 阅读(361) | 评论 (0)编辑 收藏
jar2exe是国产软件,看来这方面的需求还是很旺盛的。点击这里下载。
过程极为简单,第一步
第二步,选择应用程序类型

第三步,输入启动类。输入带有 main 方法的类名

第四步,输入要生成的 Exe 文件名:

posted @ 2006-12-04 13:18 wqwqwqwqwq 阅读(1583) | 评论 (0)编辑 收藏
正则表达式主要应用于文本的处理,如检索,替换,检查错误,文字拆分...实在是一言难尽,如果要全部写出来,一本书都不差不多。还好oreilly已经为我们出了一本了。
 
讲具体内容以前先给个完整的例子,这样能有个感性的认识。
import java.util.regex.*;
public class Regex{
   public static void main(String[] args){
        String text = "my email address is "nicky.jcoder@gmail.com";
        Pattern pattern = Pattern.compile("\\w+@\\w+.\\w+");
        Matcher matcher = pattern.matcher(text);
        if(matcher.find()){
            System.out.println(matcher.group());
        }
 
   }
}
把这段程序用jdk或jcreator或水腻的便了。反正运行起来就是了
输出结果:xhinker@163.com
当你看完下面的东西回头再看看这段程序就会发现,这不过是小菜一碟
 
字符和字符类

表格 A: 字符匹配

操作

解释

例子

结果

.

单个字符匹配

   .ord

匹配 “ford”, “lord”, “2ord”,

[ ]

多个字符列表

   [cng]

只会匹配 “cord”, “nord”, 和 “gord”

[^ ]

不出现字符列表

   [^cn]

匹配 “lord”, “2ord”, 等. 但不会匹配 “cord” or “nord”



  [a-zA-Z]

匹配 “aord”, “bord”, “Aord”, “Bord”等



   [^0-9]

匹配 “Aord”, “aord”, 等. 但不会匹配“2ord”, 等.

 

表格 B: 重复操作符

操作

解释

例子

结果

?

匹配0次或1次

 “?erd”

匹配 “berd”, “herd”“erd”等

*

匹配0次以上

“n*rd”

匹配 “nerd”, “nrd”, “neard”, 等.

+

匹配1次以上

“[n]+erd”

匹配 “nerd”, “nnerd”, 等., 但不匹配 “erd”

{n}

匹配n次

“[a-z]{2}erd”

匹配“cherd”, “blerd”, 等. 但不匹配 “nerd”, “erd”, “buzzerd”, 等.

{n,}

匹配n次以上

“.{2,}erd”

匹配 “cherd” and “buzzerd”, but not “nerd”

{n,N}

匹配n-N次

 “n[e]{1,2}rd”

匹配 “nerd” and “neerd”等

 
常用符号:
\d:[0-9]
\D:[^0-9]
\w:[a-zA-Z0-9]
\W:[^a-zA-Z0-9]
 
{?i):大小写无关
 
\b和\B分别表示词边界和非词边界
当然上面这些只不过是最常用的,写出几个正则表达式是没有问题了。接下来说说java。
在java里\有其自身的意义,所以在用\s,\d的时候要加上一个\也就是\\s 、\\d \\(等
java自1.4后开始支持正则表达式,东西都放在java.util.regex包里,用Pattern生成一个模式对象,然后用matcher进行匹 配。如果要输出匹配结果的话,一定要记得写上matcher.find();否则会出错。当然也可以用替换,这就要看你的喜好拉。想看更多的例子就去 jdk帮助文档。
posted @ 2006-12-04 13:16 wqwqwqwqwq 阅读(422) | 评论 (0)编辑 收藏
如何在java swing里使用JTree,就像下面这样的树

A tree

手工创建:
首先,你需要创建一个JScrollPane,然后创建一个JTree,再然后创建节点TreeNode
JScrollPane是盛放JTree的容器,JTree是一个结构相当于一个房子的钢筋框架,真正的内容是节点node。学过数据结构里的树的话可能会好理解一点。写代码的时候,三个过程的创建顺序不一定,也可以倒着过来写。
比如,创建一个简单的初始化 树的方法
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.JTree;
import javax.swing.tree.*;
public class NewTree {
    public NewTree() {
        JFrame jframe=new JFrame();//创建窗体
        Container c=jframe.getContentPane();//创建容器
       
        JScrollPane scrollPane=new JScrollPane();//创建一个用于树的容器
        DefaultMutableTreeNode root=new DefaultMutableTreeNode("root");//创建树根节点
        DefaultMutableTreeNode file=new DefaultMutableTreeNode("file1");//创建一个文件节点
        root.add(file);//将文件节点添加到根节点下
        JTree tree=new JTree(root);//以根节点为参数创建一个树对象
        scrollPane.setViewportView(tree);//将树添加到scrollPane里面,并显示

       
        c.add(scrollPane);//将scrollPane添加到窗体里
        jframe.pack();
        jframe.setVisible(true);
        jframe.addWindowListener(new WindowAdapter(){//这段代码用于默认关闭
            public void windowClosing(WindowEvent e){
                    System.exit(0);   
            }
        });
    }
    public static void main(String[] args){
        new NewTree();
    }
}
结果是这样的:注意关键的是斜体的代码,其他的都是swing的东西

那么如何在netbeans里,创建和使用树呢?好多人看到的都是下面这样的:

这是为什么呢?我找过代码结果没找到,后来发现这都是假的,你还是可以通过该改变代码来创建和使用你的树:改什么?改TreeModel.
到源代码界面下创建一个初始化树的方法:
public void treeInitialize(){
   JScrollPane scrollPane=new JScrollPane();
   DefaultMutableTreeNode root=new DefaultMutableTreeNode("root");
   DefaultMutableTreeNode file=new DefaultMutableTreeNode("file1");
   root.add(file);
   JTree tree=new JTree(root);
   TreeModel treeModel = new DefaultTreeModel(root);
   tree.setModel(treeModel);
}
注意黑体代码,这样在窗体的构造方法中调用treeInitialize()方法,你的树就被改变了,tree是你用netbeans生成树对象的引用或者名字,一般会是jTree1。
接下来就是对树的操作了,限于篇幅不能再讲了
posted @ 2006-12-04 13:11 wqwqwqwqwq 阅读(3857) | 评论 (2)编辑 收藏
今天在sun的网站上转了一圈,等了好几天的Visual Web Pack终于出来了.
先介绍一下
Creates a new Visual Web Pack project containing an empty web application. This project enables you to use Visual Web Pack features like the Visual Designer to drag and drop JSF components, visual and dialog box support for binding components to data providers, and generation of Java code and Web XML files. The project uses the IDE-generated build script to build, run, and debug your project.
创建一个可视化页面工程包 包含一个空白页面应用程序.这个工程能让你使用可视化开发包的各种属性,诸如用可视化设计工具拖放JSF(java server face)组件,可视化的对话框支持将组件数据源(或者数据提供者)绑定在一起,并且生成java代码和xml页面文件。这一工程由集成开发环境(IDE)生成的构建脚本来构造,执行和调试你的项目。
(翻译的不好请见谅)
还支持ajax,呵~~呵~~~。
最终装好的效果图:
全面支持拖放,呵呵,上次装了一个java studio creator结果运行死慢死慢的,这一次把这一功能转移到了netbeans挺好用,速度也不错,我这台笔记本都能挺过来,台式机估计没什么问题。
安装时要注意的地方:
1.netbeans必须为5.5正式版本,beta版本的检测不到。点击进入netbeans首页
2.下载JDK 5_60或者以后的版本我用的是JDK 5_09版本,安装的时候最好不要把原来的卸载,有时候老程序不认新的JDK。点击进入JDK下载页面
点击这里进入Visual Web Pack 的下载页面。
posted @ 2006-12-04 13:07 wqwqwqwqwq 阅读(2796) | 评论 (2)编辑 收藏

October 20, 2006 - Anyone who believes college students today are lacking in initiative, creativity, or work ethic should take a close look at the recent accomplishments of a team of students at the Ecole de Technologie Superieure (ETS) in Montreal, Quebec. Over the past three years, this team of 12 has been heads-down working on the mechanical design, electrical system, and Java™ control and navigation software for an AUV—a submarine—and preparing it for the International Autonomous Underwater Competition sponsored by the Association for Unmanned Vehicles Systems International (AUVSI) and the Office of Naval Research (ONR) in San Diego, California.

SONIA Team
Click here for more images

For no college credits, no pay, and no guarantee of success, the ETS team designed and built an AUV that could meet the complex and demanding mission requirements of the competition. Detailed in an 18-page document, these requirements included the ability to autonomously pass through a gate, detect a flashing light, find and connect with a docking station, locate a pipe and drop material into a bin—all underwater and with no communication with the team.

The submarine is called SONIA, which stands for Système d’Opérations Nautiques Intelligent et Autonome, and is just over one meter long, with a dry weight of 20 kg and a unique box-shaped design. It is equipped with sensors and two color video cameras. Navigation data input is provided by a compass and two gyroscopes as well as active and passive sonar arrays.

SONIA outperformed all but two of the 21 entries in the student competition, securing a place for ETS on the podium for a fourth year in a row. With an overall budget of just $15,000 U.S. (provided by ETS and a variety of corporate sponsors), the ETS team scored higher than teams with six-figure budgets. The competition was won by the University of Florida, but the ETS team came out ahead of renowned engineering schools such as MIT, Georgia Tech, and Virginia Tech.

Innovative Design, Expert Software Engineering

Two of the characteristics that set SONIA apart from competitors were its innovative box-shaped design and the sophistication of its core software systems.

SONIA underwater
Click here for more images
“The traditional tube shape requires a lot of extra design work because electronics boards are square,” said David Mercier, technical leader of the ETS team. “The only disadvantage of the box shape is how it moves through the water, and we overcame that by making the hull out of machined aluminum and hand-polishing it for 25 hours to make it glide through the water more easily.”

The ETS team’s expertise with Java software proved a decisive advantage. Martin Morissette, software team leader of the SONIA team, is currently entering his third year in software engineering, and recently completed a six-month internship at Sun Labs, where he worked on the “Squawk VM,” a small J2ME™ virtual machine (VM) written almost entirely in Java. The Squawk VM provides the ability to run wireless transducer applications directly on the CPU without any underlying OS, saving overhead and improving performance.

“I learned a great deal during my time with Sun Labs that was extremely useful in the development of the navigation software for SONIA,” said Morissette. “The fact is, Java is an excellent programming language for robotics. All schools teach Java, so everyone on the software team knows how to use it. It’s object-oriented; it’s portable so it runs on Macs, PCs, Linux, whatever; it’s very efficient so we don’t have to worry about memory management; and there are lots of APIs available. And if you know how to write your applications properly, it can be very fast.”

The ETS team used Java for mission control and SONIA’s control systems, Java Management Extensions (JMX) for management, and a Java 3-D Simulator to simulate a broad range of mission scenarios. The team is now investigating the possibilities of Real-time Java, introduced at this year’s JavaOne Conference, for AUV and other robotics applications.

Consensus Building and Peer Review

According to Mr. Mercier, teamwork was every bit as important as technology in the ETS team’s success. “I can’t stress strongly enough that our ability to work together was the key to our success in the competition,” he said. “This is not about 12 individuals working on separate tasks by themselves. Every step of the way, we worked as a team and built consensus, so in the end everyone learned more. And that’s what this is really all about.”

For example, each software change was subject to peer review. All team members would receive an e-mail containing the previous version of the software, the new version incorporating a proposed change, and the rationale behind the change. Far from slowing the process down, the peer review concept got more team members more actively engaged, and ultimately resulted in far higher quality, according to Mr. Mercier. These peer reviews also ease the integration of new team members. Being a volunteer based project, volunteers come and go on a regular basis.

At the same time, the team shared tips and tricks with peers at other educational institutions. “This is more of a friendly rivalry than a dog-eat-dog competition,” said Tennessee Carmel-Veilleux, electrical team leader of the SONIA team. “We like to exchange information with some of the other teams, keep in touch with them. Who knows—we may all be working together some day.”

In recognition of the team’s willingness to work with other teams, and for achievements at the Unmanned Underwater Vehicle Competition, Felix Pageau, team captain, won the Andy Estabrook Award for "initiative and vision in the unmanned underwater systems.” Given for the first time to a student, the award was presented by the Lindbergh Chapter, San Diego, CA, of the AUVSI. Andy Estabrook was a pioneer in unmanned robotics and this award was created to honor his accomplishments in the advance of unmanned systems technology.

What’s next for the ETS team? The team itself is growing rapidly, thanks in part to the success at this year’s competition. The team leaders now find themselves in management roles as the team’s ranks have swollen to 34. “We’re going to compete again next year, and we’re going to focus on making our software more stable, more reliable, and faster,” said Mr. Morissette. In the mean time, the team leaders will be presenting their work at a variety of conferences worldwide—from Florida and Washington D.C. to Cologne, Germany.

And when will they get around to more traditional college activities such as frat parties and beer runs? “Probably never,” said Mr. Mercier. “We’re geeks. We’re doing what we love.”

For more information:

posted @ 2006-12-01 20:57 wqwqwqwqwq 阅读(538) | 评论 (0)编辑 收藏
   Sun Microsystems公司宣布,其免费提供的适用于Solaris和Linux 操作系统的开发工具――Sun Studio 11软件,再次就标准性能评测公司(SPEC)提出的新的基准性能标准创立了破记录的性能记录。此外,Sun还发布了Sun Studio Express项目,采用C、C++和Fortan等编程语言的开发者可以通过该项目预览Sun Studio未来版本准备提供的新特性。在过去的6个月内,对Sun Studio 11软件的注册下载次数已超过50,000次,Sun Studio Express项目的创立响应了业界对Sun Studio 11软件的极大兴趣和迅速采用的需求。

Sun在基于AMD Opteron和UltraSPARC®处理器的系统上,采用Sun Studio 11和Solaris 10软件,创立了四大基准性能测试中的三项性能测试(SPECint2006、SPECfp2006和SPECint_rate2006)的最高记录,确 立了Sun在标准性能方面的领导地位。采用Sun Studio 11软件所具有的先进性能,如自平行技术(Auto-Parallelism Technology),基于AMD Opteron处理器的Sun Fire X4200服务器,其性能超越了基于Intel处理器的竞争对手的系统,如HP ProLiant DL380 G4服务器和HP ProLiant DL385服务器。Sun还公布了其旗舰产品Sun Fire E25K服务器的优异性能,兑现了它曾对高端商务计算领域做出的承诺。据IDC公司2006年第二季度全球服务器市场季度报告得知,Sun的高端系统针对 Sun Studio软件做了优化,这帮助Sun成为了这一季度内取得市场份额增长的唯一的服务器厂商。

所创立的SPEC CPU2006基准性能的测试记录是2006年8月24日发布的。这一记录是上个最高记录的4倍。该基准性能测试针对了各种各样的负载,得到了实际应用中 更好的适用性结果。这一新的基准性能测试在各种计算密集的负载上测试了计算机处理器、内存架构和编译器的性能,这些负载应用包括有,蛋白质排序、MPEG -4编码、XML处理、流体动力学、结构性力学和语音识别等。

“Sun Studio软件继续显示了在帮助开发商最大化其应用程序性能的能力上的领导地位,”Sun公司开发工具高级总监Don Kretsch说,“6个月内50,000次下载,使采用Sun Studio 11软件的企业开源开发者们获得了诸多好处:减少了开发时间,提高了便携性,还改善了他们所开发的应用程序的性能。”

Sun Studio 11软件为开发者带来的最大好处之一就是各个组件之间的集成性非常好,这些组件包括有:编译器优化组件、多线程警示调试器、性能分析工具和一个基于 NetBeans的集成开发环境(IDE)。这些工具组件还可以在其他的编译器上工作,这就使开发者们可以很容易地将Sun Studio工具与他们现有的开发环境混和在一起使用。新发布的Sun Studio Express项目对正在研发中的Sun Studio未来版本的主要特性将定期予以提供。包括针对Linux的编译器优化组件在内的最新的一些性能在最近于旧金山举行的2006 LinuxWorld上做了演示。此外,新的Data Race Detection Tool(数据族探查工具)对现有的多线程库、多线程工具和编译器优化等特性是一个重要的补充,可使多线程应用的开发变得更加简化和容易。

开发者可从网站http://developers.sun.com/sunstudio下载免费的、无限制的Sun Studio软件。

技术规格
  • 产品系统要求:

    SPARC 平台

    • 内存:至少为 512 MB 内存;建议使用 1 GB
    • 磁盘空间:1.7 GB
    • 安装光盘

    x86/x64 平台

    • 内存:至少为 512 MB 内存;建议使用 1 GB
    • 磁盘空间 (Solaris OS):1.1 GB
    • 磁盘空间 (Linux OS):0.6 GB
    • 安装光盘
  • 支持的操作系统::

    Solaris OS

    Solaris 8、9 和 10 操作系统整个 Solaris 软件组、整个 Solaris 软件组加 OEM 支持或者开发人员 Solaris 软件组

    Linux OS

    • Sun Java Desktop System,版本 3
    • SUSE Linux Enterprise Server 9
    • Red Hat Enterprise Linux 4
  • 许可要求::

    免许可费的运行时库 (.so) 分发

  • 使用限制::

    您应承诺软件不会被设计、许可或计划用于任何核设施的设计、修建、操作或维护。

  • 支持的相关标准::

    C:

    • ISO/IEC 9899:1999,编程语言 - C ("C99")
    • ISO/IEC 9899:1996,C
    • FIPS 160 标准。
    • K&R C
    • OpenMP C API Version 2.5

    C++:

    • ISO/IEC 14992:2003 C++ 标准
    • OpenMP C++ API 2.5 版

    Fortran:

    • ANSI X3.198-1992 Fortran 90
    • ISO 1539:1991 Fortran
    • ISO/IEC 1539-1:1997 Fortran 95
    • OpenMP Fortran API 2.5 版
  • 第三方兼容应用程序::

    GNU Compiler Collection(Linux 平台)

  • 升级计划::

    源和目标级与以前版本的兼容性以及 GNU C/C++ 兼容性功能,简化升级和采用。


posted @ 2006-11-17 23:22 wqwqwqwqwq 阅读(631) | 评论 (0)编辑 收藏
     摘要: 今天翻译了一篇实录,先发到自己的blog上吧,呵呵 开放Java平台(Micro Edition,微型版)源码:对话Sun公司移动&嵌入式平台高级主管香农.林奇 在2006年5月的JavaOne会议上,Sun微系统公司宣布即将开放Java技术的源码。目前,Sun已经计划开放大部分Java平台的源码,包括在2006年末之前开放Micro Edition (Java ME)和Java平...  阅读全文
posted @ 2006-11-15 19:46 wqwqwqwqwq 阅读(416) | 评论 (5)编辑 收藏

Sun发布Solaris ZFS-全球最先进的文档系统
Solaris 10 OS最新升级版包括Solaris ZFS 1.0文档系统
提供了端到端的数据完整性,重新定义缩放能力,大大降低数据管理成本


(2006年5月25日讯) Sun Microsystems公司发布了一个具有革命性的新的文档系统Solaris ZFS 1.0,它提供了多项突破性的功能,包括公共管理任务的自动化、保护数据免受非法行为的侵害,以及提供实际上无限的缩放能力。Solaris ZFS 1.0将作为我们这个星球上最先进的操作系统Solaris 10 OS的下一个商业版本的一个组成部分在今年6月份对外正式提供。此外,Solaris 10 OS的最新版本Solaris 10 6/06将先进的前摄性自愈技术和联网技术,与对PostgreSQL开源数据库的全面支持结合起来,进一步强化了Solaris 10 OS作为宿主高性能的关键数据库解决方案的首选平台的地位。

作为世界上最先进的文档系统,Solaris ZFS可以自动检测和修改细小的数据错误或遭遇意外侵害的数据,以提供信息的完整性。Solaris ZFS还因为不需要卷宗管理器而大大简化了数据的管理,而卷宗管理器是今天数据管理事务中最耗时、最费钱的部分。例如,今天,一项典型的系统管理任务可能 需要40多分钟来完成,但是采用Solaris ZFS,仅仅需要几秒钟的时间,且没有系统宕机的危险,从而大大降低了数据管理的成本费用。此外,Solaris ZFS还是世界上第一个128位的文档系统,这使系统具有了实际上无限的数据容量。Solaris ZFS提供的先进的缩放能力和管理能力,使它成为许许多多传统UNIX?文档系统的理想替代品。

Solaris是宿主高性能数据库的杰出平台。最近,Oracle指名Solaris 10 OS作为其开源64位开发和部署环境的理想平台。现在,Sun还将开源PostgreSQL数据库集成在Solaris 10 OS的最新版本内,对PostgreSQL数据库提供全面支持。Sun与PostgreSQL社团开展合作,让他们采用Solaris 10 OS提供的各种先进技术,如前摄性自愈技术、Solaris分区特性和Solaris动态跟踪能力(DTrace)等。

“面对不断增长的依顺性要求,今天的数据量每9~12个月就要翻番,但今天的文档系统还植根在上世纪70年代的技术之中,”Sun公司主管系统软件部的 副总裁Tom Goguen说,“Solaris ZFS从设计之初就是要迎接今天数据管理的挑战,它的预期寿命是20~30年。这一128位的文档系统所能存储的自愈数据是今天已有文档系统的160亿 倍,同时还大大简化了卷宗的管理。Solaris ZFS将是今年内发布的最重要的创新技术之一。”

Solaris 10是我们这个星球上最先进的操作系统,它可在650多款SPARC和x64/x86平台上运行,获得来自独立软件厂商的2,200多种应用程序的支持。 其无与伦比的功能性和硬件平台的支持,加上它所提供的行业唯一的应用兼容性保证,加快了Solaris 10 OS在全球的应用步伐,目前Solaris 10 OS的注册许可数已超过450万。

具有革命性的新的文档系统技术

Solaris ZFS 1.0具有任何其他商用文档系统技术所无法匹敌的优异性能。客户可以从Solaris ZFS技术中享用到先进的数据完整性技术、使用和管理的简易性、难以置信的高性能,以及实际上无限的缩放能力。

  • 端到端的数据完整性―― 基于校验和与事务性写入复制(copy-on-write)机制的突破性的结合,Solaris ZFS可提供满足CIO和系统管理员要求的数据准确性。Solaris ZFS拥有先进的错误检测机制,能识别被损坏的数据,并将之在运行中修改过来。例如,镜像的一侧被意外地重写,ZFS可以对之检测、修补和恢复,且完全不 干扰服务的进行。
  • 简化的管理――Solaris ZFS提供了一种基于共享的架构模式,使所有的共享数据和功能纳入虚拟内存管理。Solaris ZFS文档系统可以自动地增长或收缩,而无需占据额外存储空间的卷宗管理器。Solaris ZFS还提供了在任何时间点上对文档系统进行瞬间快照的能力,这就大大节约了一般系统管理员手工恢复文档所花费的时间和资源。
  • 性能的巨大提升――Solaris ZFS的架构设计有助于提高速度。写入复制的设计可将随意写入转变为快速连续写入。其输入/输出(I/O)带宽在有数据存储时可自动加大。无论工作量如 何,多种字区尺寸会自动做出最佳配合。智能化的预取感式读取可加快运行速度。而且,它的高级的、可扩展的I/O子系统设计采用了记分板式的流水线操作和依 赖性时序安排,同样提供了极大的性能提升。
  • 无限的数据容量――Solaris ZFS是世界上第一个128位文档系统,具有实际上无限的数据容量。
Solaris 10 OS是Solaris Enterprise System的组成部分。Solaris Enterprise System还包括Sun Java Enterprise System (Java ES)、Sun N1 System Manager软件和Sun Studio Software Developer工具,这些软件都可免费提供用于开发和部署。正是具有这么多软件,使Solaris Enterprise System成为今天可采用的唯一的综合性开放架构的软件平台。欲了解更多的相关信息或得到相关新闻稿件,请访问http: //www.sun.com/aboutsun/media/presskits/networkcomputing06q2。

Sun公司简介

一个独具特色的理念――“网络就是计算机”,指引着Sun各项技术的发展,为全球各个重要的市场增添活力。Sun共享创新和创建社团的思想体系处于新 一代网络计算-参与时代-的最前沿。Sun的足迹遍及全球100多个国家和地区,其互联网的网址为http://www.sun.com。Sun公司的中 文网址为http://www.sun.com.cn

ZFS是第一个128位的文件系统,同时ZFS又被Sun Microsystems称作史上最后一个文件系统。因为这个文件系统含有多项创新技术,不仅成功地解决现有文件系统的问题和陋习,而且前瞻性地考量了未 来对存储空间的需求,单个文件系统可以达到256 quadrillion(264) Zettabytes(221)。 ZFS不仅符合POSIX文件系统的标准,而且提供了许多高级功能比如:Quota(配额),Reservation(预留), Compression(压缩), Snapshot(快照),Clone(克隆)等。如果你还在坚持使用现有32位或者64位的文件系统,如果你还在“痛并不快乐着”地用着各式各样的 Volume Manager,那就很值得看看这里列出的使用ZFS的十条理由。

1. 再也不需要fsck, scandisk

不管你是在用Linux,UNIX还是Windows,相信大家都有过类似的体会:当系统意外断电或者非法关机,系统重起后发现文件系统有 inconsistent的问题,这时 候就需要fsck或者scandisk 来修复,这段时间是非常耗时而且最后不一定能够修复成功。更糟糕的是,如果这是一台服务器需要做fsck的时候,只能offline(下线),而且现有应 用往往都是大硬盘,相应fsck修 复时间也很长,这对许多使用该服务器的用户来说几乎不能忍受的。而使用ZFS后大家可以彻底抛弃fsck这种工具,因为ZFS是一个基于COW(Copy on Write)机制的文件系统。COW是不会对硬盘上现有的文件进行重写,保证所有硬盘上的文件都是有效的。所以不会有这种inconsistent的概 念,自然就不需要这种工具了。

2. 管理简单

  ZFS作为一个全新的文件系统,全面抛弃传统File System + Volume Manager + Storage的架构,所有的存储设备是通过ZFS Pool进行管理,只要把各种存储设备加 入同一个ZFS Pool,大家就可以轻松的在这个ZFS Pool管理配置文件系统。大家再也不用牢记各种专业概念,各种命令newfs, metinit及各种Volume Manager的用法。在ZFS中我们只需要两个命令,zpool(针 对ZFS Pool管理)和zfs(针对ZFS文件系统的管理),就可以轻松管理128位的文件系统。举个例子,我们经常会遇到系统数据增长过 快,现有存储容量不够,需要添加硬盘,如果依照传统的Volume Manager管理方式,那我 们需要预先要考虑很多现有因素,还要预先根据应用计算出需要配置的各种参数。在ZFS情况下,我们的系统管理员可以彻底解放,再也不需要这种人为的复杂 考虑和计算,我们可以把这些交给ZFS,因为ZFS Pool会自动调节,动态适应需求。我们只需一个简单的命令为 这个ZFS Pool加入新的硬盘就可以了:

zpool add zfs_pool mirror c4t0d0 c5t0d0

  基于这个动态调节的ZFS Pool之上的所有的文件系统就可以立即使用到这个新的硬盘,并且会自动的选择最优化的参数。

  而且ZFS同时也提供图形化的管理界面,下面是一个ZFS图形化管理的一个截屏:

[attachment=2119]

3. 没有任何容量限制

ZFS(Zettabyte File System)文件系统就如其名字所预示,可以提供真正的海量存储,在现实中几乎不可能遇到容量问题。在现有的64位kernel(内 核)下,它可以容纳达到16 Exabytes(264)大小的单个文件,可以使用264个存储设备,可以创建264个文件系统。

4. 完全保证 数据 的正确和完整

由于ZFS所有的数据操作都是基 于Transaction(事务),一组相应的操作会被ZFS解 析为一个事务操作,事务的操作就代表着一组操作要么一起失败,要么一起成功。而且如前所说,ZFS对 所有的操作是基于COW(Copy on Write), 从而保证设备上的数 据始终都是有效的,再也不会因为系统崩溃或者意外掉电导致数据文件的inconsistent。

还有一种潜在威胁 数据的可能是来自于硬件设备的问题,比如磁 盘,RAID卡的硬件问题或者驱动bug。现有文件系统通常遇到这个问题,往往只是简单的把错误数据直接交给上层应用,通常我们把这个问题称作 Silent Data Corruption。而在ZFS中,对所有数据不管是用户数据还是文件系统自身的metadata数 据都进行256位的Checksum(校 验),当ZFS在提交数据时会进行校验,彻底杜绝这种Silent Data Corruption情况。

5. 提供优异 性能和扩展性

  和传统File System + Volume Manager + Storage架构不同,ZFS则是直接基于存储设备提供所有的功能,因此有自己独有的创新特性,性能自然非比寻常。

  * Dynamic Striping vs. Static Striping

由于ZFS是基于COW和一个全局动态的ZFS Pool,任何一次写 操作,都是对一块新数据块(Block)的一次写操作。ZFS从ZFS Pool中动态挑选出一个最优的设备,并且以一个transaction(事 务)线性写入,充分有效地利用了现有设备的带宽,我们把这个特性称为Dynamic Striping。而相对应的Static Striping则是传统文件系统所使用的方式,Static Striping需要管理员预先对这组Stripe进行正确地计算人为 设置,而且如果加入新的设备则需要再次人为的计算和设置,更为严重的是如果人为计算错误,则会直接影响系统的性能。而在使用Dynamic Striping这种特性之后,我们根本不需要人为介入,ZFS会自动调整,智能的为你 提供最佳的设备,最快的操作方式。

  * 支持多种 大小的数据块(Multiple Block Size)

  ZFS支持多种大小的数据块定义,从512字节到1M字节。和传统文件系统往往都是固定大小数据块不同,ZFS则是可以动态的根据不同 大小的文件进行计算,动态的选择最佳的数据块。

因为不同大小数据 块,直接影响到实际使用硬盘容量和读取速度。如果使用较小的数据块,存储文件所导致的碎片则较少,读写小文件更快一些,但是会导致需要创建更多的 metadata,读写大文件则会更费时。如果使用较大的数据块,使用的metadata较少,更利于读写大文件,但是会导致更多的碎片。ZFS根据实际 调查现有文件使 用的情况,分析出一个选择数据块大小的算法,动态的根据实际文件大小确定最佳的数据块。所以ZFS是 非常智能的,在不需要系统管理员介入,就可以得到一个自我调优的结果。当然ZFS也支持用户对单个文件或者整个文件系统 所使用的数据块大小的自定义设置。

  * 智能预读取(Intelligent Prefetch)

  多数的操作系 统都 有这种将数据预先读取的功能,而ZFS则是建立在文件系统上直接提供的一种更加智能的数据预读取功能。它不仅可以智能地识别出多种读取模式, 进 行提前读取数据,而且可以对每个读取数据流进行这种预读取智能识别,这个对许多流媒体提供者来说是件非常好的事情。

  在扩展性上,和现有文件系统多是基于一个受限的静态模型不同,ZFS是采用ZFS Pool这个动态概念,它的metadata也是动态,并且读写操作都是可并行的,并且具有优先级概念,所以即使在大数据量,多设备的情况下仍可以保证性能的线性增长。

6. 自我修复功能

  * ZFS Mirror 和 RAID-Z

传统的硬盘Mirror及RAID 4,RAID 5阵列方式都会遇到前面提到过的问题:Silent Data Corruption。如果发生了某块硬盘物理问题导致数据错误,现有的Mirror,包括RAID 4,RAID 5阵列会默默地把这个错误数据提交给上层应用。如果这个错误发生在Metadata中,则会直接导致系统的Panic。 而且还有一种更为严重的情况是:在RAID 4和RAID 5阵列中,如果系统正在计算Parity数值,并再次写入新数据和新Parity值的时候发生断电,那么整个阵列的所有存储的数据都毫无意义了。

在ZFS中则提出了相对应的ZFS Mirror和RAID-Z方式,它在负责读取数据的时候会自动和256位校验码进行校验,会主动发现这种Silent Data Corruption,然后通过相应的Mirror硬 盘或者通过RAID-Z阵列中其他硬盘得到正确的数据返回给上层应用,并且同时自动修复原硬盘的Data Corruption 。

  * Fault Manager

在Solaris 10中,包含 一个ZFS诊断引擎和Solaris的 Fault Manager(这也是Solaris 10的 另一个新特性)交互,可以实时地诊断分析并且报告ZFS Pool和存储设备的错误,用户可以通过Fault Manager及时得到一个非常友善的消息。这个诊断引擎虽然不会采取主动的行为去修复或者解决 问题,但是会在消息中提示系统管理员可采取的动作。类似下面一个ZFS报错消息,其中REC-ACTION就是建议采取的动作:

SUNW-MSG-ID: ZFS-8000-D3, TYPE: Fault, VER: 1, SEVERITY: Major

EVENT-TIME: Fri Mar 10 11:09:06 MST 2006

PLATFORM: SUNW,Ultra-60, CSN: -, HOSTNAME: neo

SOURCE: zfs-diagnosis, REV: 1.0

EVENT-ID: b55ee13b-cd74-4dff-8aff-ad575c372ef8

DESC: A ZFS device failed. Refer to http://sun.com/msg/ZFS-8000-D3 for more information.

AUTO-RESPONSE: No automated response will occur.

IMPACT: Fault tolerance of the pool maybe compromised.

REC-ACTION: Run ’zpool status -x’ and replace the bad device.

7. 安全

  在安全上,ZFS支持类似NT风格NFSv4版的ACL(读取控制列表)。而且前面所提到的256位验证码,用户可选择多种验证方式,包括SHA-256验证算法,从而在物理存储单元级别上保证数据的安全性。

8. 超强功能

ZFS作为“最后一个文件系统”,涵盖了基本的文件系统和Volume管理的功能,同时 一并提供许多企业级别的超强功能:Quota(配额),Reservation(预留), Compression(压 缩), Snapshot(快照),Clone(克隆)。并且速度非常快。有了这个文件系统,大家再也不需要任何Volume Manager了。

9. 兼容性

ZFS是一个完全兼容POSIX规范的文件系统,所以处于上层的应用程序是完全不受影响。ZFS也提供一个Emulated Volume模块,可以把任何一个ZFS文件系统作为普通的块设备使用。同时ZFS也可以使用基于Volume Manager构建的Volume作为存储设备单 元。这样在不需要修改应用程序,不修改已有文件系统下,给了大家最大的自由度去获得ZFS提供的各 种特性。

10. 开源

  ZFS是Sun Microsystems公 司作为OpenSolaris的一个开源项目运作并且完全免费使用,点击这里(http://www.opensolaris.org/os/community/zfs/source/) 可以直接浏览到ZFS的代码。 这就代表着我们不仅同时可以享受商业公司的高质量,也可以获得开源模式的优点。

虽然目前只有Solaris支持该文件系统,但是这种开源的模式必定会促进更多基于ZFS的应用。现在已经有国外开发者正在将ZFS移植到Linux和 Mac OS上来。如果想要体验一下ZFS,由于目前它和Solaris 10绑定在一起,所以需要下载最新版的Solaris 10 6/06 (http://www.sun.com/software/solaris/get.jsp)。

参考:

Solaris ZFS Administration Guide: http://docs.sun.com/app/docs/doc/819-5461?l=zh&q=ZFS

Solaris 10 Zone FAQ: http://www.sun.com/software/solaris/faqs/zfs.xml

Automatic Performance Tuning in the Zettabyte File System: http://tesla.hpl.hp.com/self-manage03/Finals/henson-self-tune.pdf



posted @ 2006-10-30 10:19 wqwqwqwqwq 阅读(1494) | 评论 (0)编辑 收藏
  昨天是我sun技术大使入职第一天,即兴奋又感觉自己充满了责任。下周要去北京和兄弟院校的大使,参加技术培训。
   我一直很努力的学习着,虽然也曾彷徨,也曾摒弃过中国的教育,但是我知道我逃脱不掉,所以我还要好好学习,要保研,很想出国......大三了,让我认识了sun中国研究院,并加入了sun校园技术大使的行列,让我荣幸万分。所以我又不断地告诉自己,好好学习,好好学习技术,好好服务自己的母校、祖国.....真的
   今天早上,我和几个同学,早早的起来,出去挂上了Sun技术讲座的条幅,去北京前,我会先作一个讲座,我真的很感谢我的同学......其实,正是很多小事,才会让我们真正感动。
posted @ 2006-10-27 07:49 wqwqwqwqwq 阅读(436) | 评论 (0)编辑 收藏
  vold存在于进程之中,我们可以通过ps -ef命令进行查询,它的存在使得插上U盘后,系统可以自动识别设备。
  如果无法自动识别,我们可以尝试重新启动vold,操作方法如下:pkill -HUP vold 这个时候插上U盘,是否U盘灯亮了?
  如果还不亮,请执行rmformat命令,这个东西类似Windows中的检查硬件改变操作,它可以自动查出刚刚插上的U盘(极个别品牌U盘例外,依照以往经验……爱国者的U盘最容易被识别)。
   系统识别了U盘,接下来我们就要mount一下了,具体操作是:mount -F pcfs -o ro /dev/dsk/
c2t0d0p0:c /mnt,不过你的U盘是不是c2t0d0p0这个设备,我这里可是说不好,你自己试验一下吧 用mount查一下就OK了。

1、直接插上u盘,然后ls -l /dev/usb,看是否发现usb设备。 不过今天用 ls -l |grep usb 自动就识别咯。(Netac朗科) 2、在/etc/dsk里查询到usb对应的设备名称(ls -l /dev/dsk) 3、直接mount -F pcfs /dev/dsk/c1t0d0s0 /mnt 然后就可以了。 进/mnt目录。ls就可以查看到u盘里的内容了。

# rmformat
姝e湪鏌ユ壘璁惧...
     1. Logical Node: /dev/rdsk/c3t0d0s2
        Physical Node: /pci@0,0/pci1028,182@1d,2/storage@1/disk@0,0
        Connected Device: Netac    OnlyDisk         1.21
        Device Type: Removable
     2. Logical Node: /dev/rdsk/c3t0d0p0
        Physical Node: /pci@0,0/pci1028,182@1d,2/storage@1/disk@0,0
        Connected Device: Netac    OnlyDisk         1.21
        Device Type: Removable
# mount -f pcfs /dev/dsk/c3t0d0s2:c /usb
mount: No such device or address
# mount -f pcfs /dev/rdsk/c3t0d0p0:c /usb
mount: Block device required
# mount -f pcfs /dev/rdsk/c3t0d0s2 /usb
mount: Block device required
# mount -f pcfs /dev/rdsk/c3t0d0s2:c /usb
mount: Block device required
# mount -f pcfs /dev/dsk/c3t0d0p0:c /usb

卸载 #umount /usb
     #eject /dev/rdsk/c3t0d0p0



今天还发现,(朗科)u盘 在用户注销重新登陆时,可以自动挂载
posted @ 2006-10-22 08:50 wqwqwqwqwq 阅读(3555) | 评论 (0)编辑 收藏
   昨天在自己的笔记本(DellD610)上安装了Solaris10操作系统,分区情况如下,c0d0/c/d/e/f+(2.9G),c盘放的Xp系统,D盘还是原来windows下的软件。f盘装的则是Solaris操作系统。首先,在安装过程中,Solaris给我的印象很好,因为似乎显卡它已经识别了,所以显示的很清楚,java的风格我本人也是比较喜欢的。
   其它的软件安装: 网站:sun软件包最主要的网站是http://www.sunfreeware.com,其次是各开源网站如http://mirror.vmmatrix.net ,还有其他一些(如apache 的网站 www.apache.org)。如果不知道某个软件的下载地址,可以在 www.google.com里搜索。安装包下载到本地磁盘,必须把这些包存放到运行 solaris10的机器上。Wget似乎是一个很受欢迎的下载工具,情况也是如此。不巧的是,solaris10本身不带wget这个工具,所以初始安 装的系统还不能使用这个便利。有的网友先把文件下载到windows,然后用ssh secure file transfer把它传输到solaris 10的某个目录。
1、wget下载。例如下载apache到当前目录的命令为:wget ftp://ftp.sunfreeware.com/pub/freeware/intel/10/apache-2.2.0-sol10-x86-local.gz
下载完成后,用命令# ls -al查看当前目录是否有刚才现在的文件存在。
  2、用ssh secure file transfer传送。这个比较简单,不再多说。
当然,我也认为使用挂载也是完全可以的。
   
Solaris10 安装软件包的方法主要有三种:solaris包、二进制源码、安装脚本。接下来分别介绍这几种安装方法。
    1、solaris 10包。Solaris包的文件格式大致是*-local.gz ,如apache的包文件apache-2.2.0-sol10-x86-local.gz。在安装一个包之前,我们应当先查看系统中是否已经安装了该软 件包;通过运行包管理工具pkginfo来了解系统中已安装的包。运行 # pkginfo 可能有较长的输出,以至于需要多屏才能显示完整,为方便阅读,最好在后面加一管道(# pkginfo | more)。如果所需的包没有安装到系统,执行下面两个命令来安装(此处以包wget为例):# gzip –d wget-1.10.2-sol10-x86-local.gz   //把包解开,解开后原压缩包自动删除,当前目录下生成文件wget-1.10.2-sol10-x86-local。
# pkgadd –d wget-1.10.2-sol10-x86-local //执行后会有交互命令,请根据具体的环境做出选择.在回答了包管理管理器若干问题之后,一个软件包就安装到系统上,再运行包管理命令 # pkginfo –l | grep <包名>查看详细的安装信息。从这个过程我们可以知道,安装solaris包确实是很容易的事情,但笔者认为,在安装过程中,它会把解开后的 文件复制到不同的目录(位置),究竟都复制了那些文件到那些目录,并不是一个容易弄清楚的。
  2、二进制源码。二进制源码是通用的linux/unix软件包安装方法,也是管理员最爱的安装手段。相对于solaris包而言,二进制源码包的数量远 远大于前者(有很多GNU软件并不提供solaris 包),这也是选择二进制源码安装的原因,当然,用二进制源码安装,使得整个操作更具灵活性。在这里我们以web服务器apache的安装为例。
# gzip –d httpd-2.2.0.tar.gz  
# tar xvf httpd-2.2.0.tar
# cd httpd-2.2.0      
# ./configure –prefix=/usr/local/apache2 –enable-so //配置操作,具体的选项可以通过执行命令# ./configure –help查看。此处指定了安装apache的路径及模块的加载方式
# make                 //配置过程顺利完成后,才可以继续这个编译过程。
# make install             //同样需要等到编译操作(make)完成再进行安装,这一步是把文件及目录复制到指定的安装目录。
  这个例子是通用的linux/unix软件安装步骤,但不要认为所以的二进制源码都是这样的安装操作(请注意:这只是一般情况),一个好的习惯就是:在把 下载的源码包文件解压成目录后,打开里面的文件README或INSTALL文本文件,就可能看到安装软件包的方法,至于更多细节,可以登录该软件的发布 网站查询相关文档。在执行配置操作时,如果不指定安装路径的话,在安装结束以后,文件会分散到系统目录的各个角落(比如执行脚本会复制到 /usr/sbin,配置文件可能会在目录/etc中找到,等等),为了方便管理维护,强烈建议配置时指定安装目录。
   3、安装脚本。大型的软件为了方便用户的安装,往往提供一个安装脚本,比如sybase、oracle等。这种安装方法本身很简单,只需执行这个安装脚本而 已,接着安装程序会跟用户交互,比如指定安装路径等。不过,有些软件在执行安装前,需要配置环境变量诸如此类的预处理,以满足软件安装的特殊需求。就拿数 据库服务器oracle 10g为例,在执行安装脚本前,就必须配置环境变量和更改内核参数以及添加用户等预处理操作。
   
软件包的卸载。Solaris包:执行命令 # pkgrm <package name>。二进制源码:直接删除安装目录。
脚本方式安装:卸载脚本或直接删除安装目录。
posted @ 2006-10-20 08:09 wqwqwqwqwq 阅读(453) | 评论 (0)编辑 收藏
/**
    *@ the titlt  about a Random example about choose 7 from 33
    *@ the auther Nicky (EN) QuQiang(CH)
    *@ the date   2006.9.1
**/



/** the rules

//一等奖:选中6个正选号及特别号;

//二等奖:选中5个正选号及特别号;

//三等奖:选中5个正选号;

//四等奖:选中4个正选号及特别号;

//五等奖:选中4个正选号或选中3个正选号及特别号;

//六等奖:选中3个正选号。

**/

import java.util.*;

public class NotSameRandoml{
     private static String transform;
     private static String match="00";
     private static int special;


  //产生彩票主逻辑函数
   private static void Nicky(int[] guess){
      Random r = new Random();     //构造伪随机生成器
      //某些映射实现可明确保证其顺序,如 TreeMap 类;某些映射实现则不保证顺序,如 HashMap 类
      Map map = new TreeMap();   //Map 接口的实现
      int n = 0;
      int nt = 1;
      String[] temps=new String[7];
      
      while(true){
          n = r.nextInt(33)+1; //产生1~33的随机数
          //if( map.get(new Integer(n))!=null){
          //   nt = ((Integer)map.get(new Integer(n))).intValue();  
          //}
          //避免了产生的随机数字重复
          if(map.containsValue(n)){
            continue;
          }
          map.put(new Integer(nt),new Integer(n));//将指定的值与此映射中的指定键相关联
          if(map.size()==7){
             break;
          }
          nt++;
      }
      
      Iterator it = map.keySet().iterator(); //返回此映射中包含的键的 set 视图
      for(int i=0;it.hasNext();i++){
       Object o = it.next();
        // 为了更符合现实中33选7,数字为01。。。2位
       int temp=((Integer)map.get(o)).intValue();
       if(temp>=1&&temp<10){
           transform="0"+Integer.toString(temp);
           match=match+" "+transform;
           temps[i]=transform;
           if(((Integer)o).intValue()==7){
                   special=temp;
                   System.out.println(""+transform+"为产生的特别中奖中奖号码");
               }else  
                 System.out.println(""+transform+"为产生的第"+((Integer)o).intValue()+"个中奖号码");
        }else{
        temps[i]=Integer.toString(temp);
        match=match+" "+temps[i];
        if(((Integer)o).intValue()==7){
           System.out.println(""+transform+"为产生的特别中奖中奖号码");
        }else
        System.out.println(""+temp+"为产生的第"+((Integer)o).intValue()+"个中奖号码");
       }
      }
      String creat=match.substring(3);
      System.out.println("所产生的中奖号码串为:"+creat);
      //System.out.println("对产生的中奖号码顺序排序为:"+creats);
      Sort(temps);
      check(map,guess);
   }
   
   //实现排序,也可以调用方法,但是却必须要解决Void问题
    private static void Sort(String[] temps) {
         for(int i=0;i<temps.length;i++){
          for(int j=i+1;j<temps.length;j++){
         if(Integer.parseInt(temps[i])>Integer.parseInt(temps[j])){
            String k;
            k=temps[i];temps[i]=temps[j];temps[j]=k;
         }
        }
      }
      System.out.println("对产生的中奖号码顺序排序为:");
      for(int i=0;i<temps.length;i++){
          System.out.print(temps[i]+" ");
      }
      System.out.println("\n");
    }
   
   
  //输出结果类别  
   private static void check(Map map ,int[] guess){
        int flag=0;
         for(int i=0;i<guess.length-1;i++){
            if(map.containsValue(guess[i])){
                    flag++;
                }
         }
         if(guess[guess.length-1]==special){
            flag=flag+10;
         }
         switch(flag){
              case 16: System.out.println("恭喜您中一等奖");break;
              case 15: System.out.println("恭喜您中二等奖");break;
              case  5: System.out.println("恭喜您中三等奖");break;
              case 14: System.out.println("恭喜您中四等奖");break;
              case 13: System.out.println("恭喜您中五等奖");break;
              case  4: System.out.println("恭喜您中五等奖");break;
              case  3: System.out.println("恭喜您中六等奖");break;
              default: System.out.println("谢谢参与,祝您下次中奖");
         }
   }
   
   
   
  //说明
 
   private static void usage(){
      System.out.println("Usage:java Randomol program [the number you guess for the lucky nums.]");
      System.out.println("\t And the nums. you must typed 7,else you will be cancel by the game rules");
      System.out.println("\t The first 6 nums is your basic nums.,the last one is your special num.");
      System.exit(0);
   }
   
   
  //主函数
   public static void main(String []args){
        if(args.length==0||args.length>7){
              usage();
            }//带入参数
            int[] guess=new int[7];
            for(int i=0;i<args.length;i++){
               guess[i]=Integer.parseInt(args[i]);
            }
            //判断所输入的号码是否相同
        List <Integer> ls= new ArrayList<Integer>();
        for(int i=0;i<guess.length;i++){
           if(ls.contains(guess[i])){
              System.out.println("您所买的号码不可以相同");
              System.exit(0);
           }else  ls.add(guess[i]);
        }
        Nicky(guess);      
        System.exit(0);
   }
}
posted @ 2006-10-12 18:45 wqwqwqwqwq 阅读(446) | 评论 (0)编辑 收藏
呵呵 不知道写的如何。但是总感觉,在UltraEdit下写,还是很爽的,或许是因为学校办公室的电脑内存太小的缘故吧。
 1 /**
 2  * @the author:Nicky(EN) QuQiang(CH)
 3  * @the data :2006.8.27
 4  **/
 5 // 当然本算法最好编制成两到3个文件
 6 
 7 public class HalfSearch{
 8     private static int lengthValue;
 9     private static byte  flag=0;
10     private static int SearchValue=0;
11    
12     //定义返回数组类型的方法  此方法给出的public权限
13     public static int[] Sort(int[] b){
14         for(int i=0;i<b.length;i++){
15             for(int j=i+1;j<b.length;j++){
16                 int temp;
17                 if(b[i]>b[j]){
18                     temp=b[i];b[i]=b[j];b[j]=temp;
19                 }
20             }
21         }
22         System.out.println("\u6309\u5e8f\u6392\u5217\u4e3a:");  //对应汉字为     按序排列为:
23         for(int i=0;i<b.length;i++){
24           System.out.println(b[i]);
25         }                            //冒泡排序法排序  或直接使用JDK提供的sort()函数进行排列
26         return b;
27     }
28 
29     //折半查找
30     private static int Half(int[] a){
31         int m=a.length,k,n=1;
32         System.out.println("\u5f53\u524d\u5171\u8f93\u5165"+m+"\u4e2a\u6570\u7b26"); //对应汉字为  "当前共输入" 个数符
33         int index=0;
34         if(m==1){
35            if(a[0]==SearchValue){
36              flag=1;
37              index=1;
38            }
39            else{
40               flag=0;
41               index=1;
42            }
43         }             //考虑到用户除输入查找数符外,只输入一个数符,即n=m=1
44         for(int i=1;;i++){
45           if(n<m){
46              index+=1;
47              k=(n+m)/2;
48              if(a[k-1]>SearchValue){
49                  m=k-1;      //此时定义最大值为当前中间值的前一个值  //第 次查找未成功,当前值大于SearchValue
50                  System.out.println("\u7b2c"+index+"\u6b21\u67e5\u627e\u672a\u6210\u529f\uff0c \u5f53\u524d\u503c\u5927\u4e8e"+SearchValue);//否则将9改为变量
51              }else if(a[k-1]<SearchValue){
52                  n=k+1;          //未找到,则在后半区间进行查找  //小于
53                  System.out.println("\u7b2c"+index+"\u6b21\u67e5\u627e\u672a\u6210\u529f\uff0c \u5f53\u524d\u503c\u5c0f\u4e8e"+SearchValue);//否则将9改为变量
54              }else{
55                  System.out.println("\u67e5\u627e\u6210\u529f");  //查找成功
56                  flag=1;
57                  break;
58              }
59            }else break;
60          }
61         return index;
62     }                      //也可以定义一个用户需输入的查找值
63    
64     //使用说明
65    private static void usage(){
66       System.out.println("Usage:java HalfSearch program [the number you search] [the array list you give]");
67       System.out.println("\t [the number you search] the only number you want to use it to test this program");
68       System.out.println("\t [the Array list you give] A array list may be it contains it may be not");
69       System.exit(0);
70    }
71       
72     //主函数的功能  传入查找数组
73     public static void main(String[] args){
74         if(args.length==0||args.length==1){
75             usage();
76             System.exit(0);
77         }
78         SearchValue=Integer.parseInt(args[0]);
79         lengthValue=args.length;
80         int index=0;
81         int[] TransArray=new int[args.length-1];
82         for(int i=1;i<args.length;i++){
83             TransArray[i-1]=Integer.parseInt(args[i]);
84             System.out.println(TransArray[i-1]);
85         }
86         index=HalfSearch.Half(HalfSearch.Sort(TransArray));
87         //输出查询结果
88         switch(flag){
89              //在本次折半查找中共经过  次查找,未成功   成功
90             case 0: System.out.println("\u5728\u672c\u6b21\u6298\u534a\u67e5\u627e\u4e2d\u5171\u7ecf\u8fc7"+index+"\u6b21\u67e5\u627e,\u672a\u6210\u529f");break;
91             case 1: System.out.println("\u5728\u672c\u6b21\u6298\u534a\u67e5\u627e\u4e2d\u5171\u7ecf\u8fc7"+index+"\u6b21\u67e5\u627e,\u6210\u529f");break;
92         }
93         System.exit(0);
94     }
95 }


posted @ 2006-08-27 17:02 wqwqwqwqwq 阅读(636) | 评论 (0)编辑 收藏
前几天参加了SUN在大连的暑期免费培训,主要是介绍了Netbeans集成开发环境和jdk1.5、1.6的一些新的特性。原来很少使用netbeans 来作程序,即使它是sun的产品。主要是因为4.1以前的版本过于garbage.但是参加完这次培训之后,对其很有信心。这次培训之后,我对sun的了解更加进了一步。这次培训的老师是李涛老师和叶亮老师,这两位老师我还是很佩服的。虽然sun的中国研究院,没有微软的那么大的名气,但是我感觉这个团体还是一个很令人敬佩和挑战创新的团体。我们无法想象没有IDE的java编程,虽然在原来的文章中我更鼓励初学者使用文本编辑工具。
    对于J2EE的框架理念我感觉这次没有进行深入的介绍,或与也是我感觉比较遗憾的一点了。
下面给大家介绍一点JDK1.5种新引入的泛型:


以下代码摘自java.util包的List接口和Iterator接口的定义:

public interface List<E> {
  void add(E x);
  Iterator<E> iterator();
}
public interface Iterator<E> {
  E next();
  boolean hasNext();
}

类型参数

与尖括号有关的一些东西是JDK 5引入的新东西, 它们是List和Iterator接口的形式的类型参数(简称类型形参)声明.
而在对泛型声明List进行调用时(例如: List<Integer>), 所有出现的类型形参(如
E)的地方, 都会被实际的类型参数(简称类型实参, 如 Integer)所替换掉.

虽然与C++中的模板机制在形式上很想像, 但必需注意, Java中的泛型声明决不会在调用时被展成多份副本: 不论是在源码级, 二进制级, 还是在磁盘或内存中, 都不会被展开!

泛型声明只会也只需编译一次, 并生成一个类文件(class文件), 这一点跟普通的类或接口完全一样.

类型参数其实跟方法或构造器中所用的通常参数相类似. 一个方法中可以声明它用以处理的形式的值参数, 相似地, 泛型声明也有其形式的类型参数; 当方法被调用时, 实际参数会替换形式参数, 然后执行方法体, 同样, 当泛型声明被调用时, 实际的类型参数会替换掉形式的类型参数.

关于命名约定的备注: 推荐使用精炼而简明(如, 单个字符)的方式为形式的类型参数命名. 最好避免使用小写字符, 以便与普通的类或接口的参数相区分开来. 许多宣传品类型使用 E 表示其元素的类型形参.




先看以下两行代码是否合法:
List<String> ls = new ArrayList<String>(); // 1
List<Object> lo = ls; // 2
第一行没问题, 关键在第二行代码, 大多数人会认为, 一个String的List自然更是一个Object的List, 因此, 第2行没问题.

好, 接着看以下代码:
lo.add(new Object()); // 3
String s = ls.get(0); // 4: 试图将一个Object赋给一个String!

可见, 通过别名lo, 我们能对ls, 一个String的列表, 进行数据操作(特别是插入一个Object), 从而导致ls不仅仅是容纳了String对象! 这是Java编译器不容许的! 编译时, 第2行会报告一个编译错误的.

通常, 若Foo是Bar的一个子类型(子类或子接口), G是某个泛型声明, 则G<Foo>并不是G<Bar>的一个子类型.

这一点往往是最难以理解的, 因为它和通常的直观相左. 在直观的理解中, 我们实际上假定了集合是不会变动的, 但java语言中则非如此.




假定要输出一个集合中的所有元素. 以下分别是旧版本及新版本(JDK 1.5)中的写法:

void printCollection(Collection c) {
  Iterator i = c.iterator();
  for( k = 0; k < c.size(); k++) {
    System.out.println( i.next() );
}}

void printCollection(Collection<Object> c) {
  for(Object e : c) {
    System.out.println(e);
}}

问题在于, 新版本反而不如旧版本更有用些. 因为旧版本能使用各种类型的集合作为参数, 但新版本则只能使用Collection<Object>. 而正如上节看到的, Collection<Object>并不是其它各种集合的超类型(父类型).

所有集合的超类型应该写作: Collection<?>, 读作: collection of unknown(未知集合), 即一个集合, 其元素类型可以与任何类型相匹配. 因此称这种类型为通配类型.

正确实现上述旧版本的代码可以这么写:
void printCollection(Collection<?> c) {
  for(Object e : c) {
    System.out.println(e);
}}

这时, 可以用任意类型的集合来调用此方法. 注意在方法体中, 仍然从 c 中读入元素并赋给了Object, 这是没有错误的, 因此不论类型实参是何种集合, 它的元素都是object. 然而, 如果任意给它增加一个object则是不安全的:

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // 编译时的错误

由于我们不知道c的元素类型是什么, 所以不能给它增加一个object. 方法add()接受一个类型E的参数, 而E与集合的元素类型相同. 当类型实参是?时, 它表示未知的类型, 我们传递给add的参数必须是这个未知类型的子类型. 不幸的是, 既然类型未知, 也就无法决定其子类型, 于是什么也不能作为其参数. 唯一的例外是null, 因为null是所有类型的一个成员.

另一方面, 如果给了一个List<?>, 我们可以调用get()方法并使用其返回的元素. 虽然返回的元素类型是未知类型, 但它总归是一个object, 因此将get()返回的元素赋给一个Object类型的变量, 或将其传递给一个可接受Object的参数都是安全的.

posted @ 2006-08-05 14:36 wqwqwqwqwq 阅读(201) | 评论 (0)编辑 收藏

只对5以上的版本有效,官方网站上有的,不过很多人没看到罢了

Spicing Up Your NetBeans IDE 5.0 With Substance

 

 

This tech tip shows you how you can spice up your NetBeans IDE 5.0's look and feel with color themes, custom button-shapes and watermarks (wallpapers) using Kirill's Substance plug-in. To use Substance with IDE 4.1 or any other Swing-based application, refer to Spicing Up Your Swing GUI With Substance.

IDE with beyonce watermark

Preparations

  • The Substance Look and Feel NBM works with JDK 5.0+ in NetBeans IDE 5.0 (development version).
  • If you want to integrate a watermark into your Swing application, you need a suitable (wide) wallpaper image file. Download this aquamarine JPG from digitalblasphemy as a sample.
  • For some features, you need to know how to access your operating system's commandline

To install the substance-netbeans plugin into NetBeans IDE 5.0,

  1. download substance-netbeans.nbm from Kirill's project page and save the NBM file to your home directory. For this tutorial, I am using version 2.1_02.
  2. To plug the module in, open NetBeans IDE, and choose Tools > Update Center from the menu. In the Update Wizard window, check the box next to Install Manually Downloaded Modules (.nbm files), and then click the Next button.
  3. In the next screen, click the Add Button and select the substance-netbeans NBM file you just downloaded, then click OK. The NBM file shows up in the list of modules to install. Click the Next button.
  4. Make sure the NBM is visible in the field labelled Include to Install, then click the Next button. If a license agreement comes up, click Accept and then Next to proceed.
  5. A screen with the download progress bar appears. Again click the Next button.
  6. Check the Include box next to the line saying "NetBeans-Substance". If you are asked whether you really want to install an unsigned module, click Yes to proceed.
  7. Click the Finish button. If you are told that the IDE must be restarted, check the box saying Restart the IDE and then click the OK button.
  8. After the IDE has restarted, look into the View menu: If you see four new menu items, Button Shapes, Colors, Themes, and Watermarks, the plugin was installed successfully.

http://www.netbeans.org/kb/50/substance-look-and-feel.html#creating

按着步骤作就行了,先要下载一个.nbm的插件。
posted @ 2006-07-22 17:24 wqwqwqwqwq 阅读(565) | 评论 (0)编辑 收藏

在Java中,我们只要利用BigInteger类,可以完成同样功能;这里也测试了异常以及Dialog的产生。

开发环境:Windows Server 2003 Standard Edition SP1, J2SDK 1.5.0_06, Eclipse 3.1.2
源代码如下:

//Factorial.java
import java.math.BigInteger;
import javax.swing.*;


/**
 * 计算任意正整数的阶乘
 * 
 *
 */
public class Factorial {
 public static void main(String[] args) {
  BigInteger x = BigInteger.valueOf(1); //存储结果
  int num = 1; //待计算的整数
  String s = null;
  boolean correct = false;
  do {
   try {
    s = JOptionPane.showInputDialog(null, "请输入要计算的数(正整数):");
    if (s == null)
     break;
    else {
     num = Integer.parseInt(s);
     if (num < 0)
      throw new IllegalArgumentException();
     else correct = true;
    }  
   } catch (NumberFormatException e) {
    JOptionPane.showMessageDialog(null, "数据格式错误!");
    continue;
   } catch (IllegalArgumentException e) {
    JOptionPane.showMessageDialog(null,"请输入一个正整数!");
    continue;
   }
   break;
  } while (true);
  if (correct == true) {
   for (int i = 1; i <= num; i++)
    x = x.multiply(BigInteger.valueOf(i));
   JTextArea textArea = new JTextArea(x.toString(), 5, 30);
   textArea.setEditable(false);
   textArea.setLineWrap(true);
   Object[] object = {num + " ! : ",new JScrollPane(textArea)};
   JDialog dialog = new JOptionPane(object).createDialog(null,"阶乘的结果");
   dialog.setVisible(true);
  }
  System.exit(0);
 }
}

 

运行结果如下:

posted @ 2006-07-22 17:21 wqwqwqwqwq 阅读(2057) | 评论 (2)编辑 收藏

    通常我们学习一门语言的时候,第一个写的程序是输出"Hello,World!",C/C++/Java中的入口都是main方法。实际上,在Java中,即便没有main方法,我们也可以输出Hello,程序如下:

/**
 * @(#)Hello.java
 * 没有main方法,输出Hello,World!
 * 本程序请直接用javac编译,java解释运行
 * 经测试,如果在Eclipse中试图运行,默认情况下,会启动失败
 *
 * @version J2SDK 1.4.2_10-b03
 */
public class Hello {
 static {
  System.out.println("Hello,World!");
  System.exit(0);  //!如果缺少这一句,会出现运行期异常
 }
}

    假使我们为Hello类增加一个main方法,虽然它也是static的,但是静态初始化块会在main之前被执行。

posted @ 2006-07-22 17:19 wqwqwqwqwq 阅读(542) | 评论 (0)编辑 收藏
一直以来都对AI(人工智能)颇感兴趣,可惜都是些外层的皮毛,离入门的境界还远得很。最近在看《程序员》杂志2003年的合订本,突然发现了一个技术专题,就是Robocode,忙到网上下载了一个,初次尝试,感觉很有趣,特此推荐。

    一、Robocode简介:Robocode是一位IBM的工程师Mat Nelson用Java语言所创造的机器人战斗仿真引擎。Robocode不是一个完整游戏,它是个半成品,你所做的就是为你的机器人坦克编写智能程序, 让它能够移动、进攻、防御、躲避、开火。只用几十行代码,就能立刻创造出一个简单但完整机器人,你可以立即将它装入Robocode 引擎中,再从Robocode 自带的那些水平不一的示例机器人中选取一个进行一番对战,还可以在网上下载由其他程序员编写的水平更高的机器人,与它们比试一下,看看自己的水平到底如 何。
    开发Robocode,也是一个极佳的学习Java 语言的过程。随着你的机器人的”智力”水平的提高,你的编程能力也就跟着水涨船高了。


    二、如果您想了解更多的细节,请查看如下的资料:

    1.有关Robocode的详细资料,请查看如下的pdf文档,内含Robocode的详细介绍、Robocode安装、高水平机器人的代码分析、高级瞄 准策略、Robocode内核分析等7篇文章,帮助你入门,全部资料来自《程序员》2003年合订本配套光盘,请点击这里:http://www.loujing.com/mywork/java/Robocode/RobocodeBrief.pdf,(首先请确保你计算机内安装了pdf文档阅读器,可自Adobe的网站自由下载,http://www.chinese-s.adobe.com/products/acrobat/readstep2.html)。

    2.如果您需要了解Robocode更详细的信息,可参看如下网站:
    Robocode在IBM的官方网站为:http://www.alphaworks.ibm.com/tech/robocode;另外,现在Robocode项目已经终止,成为开源项目,您可以从如下站点下载其源代码:http://robocode.sourceforge.net/

    3.您可以自我的网站下载Robocode的1.0.6版本,下载地址为:http://www.loujing.com/mywork/java/Robocode/Robocode.rar,下载解压后双击其中的install.bat即可安装。当然,请首先确保您的机器里安装了J2SE SDK(Java软件开发包),如果您不知道如何设置Java运行环境,请参考本人的另一篇文章:ShowArticle.asp?ArticleID=31

    4.如果您是在Eclipse里进行Robocode的开发,您可以参考我的这篇文章http://www.loujing.com/Article/ShowArticle.asp?ArticleID=33

    希望您在游戏中也能不断提高自己的Java编程水平,新年快乐!
posted @ 2006-07-22 17:18 wqwqwqwqwq 阅读(1727) | 评论 (1)编辑 收藏

/**
 * 程序运行当年的日历,程序运行当日以*号表示
 */

import java.util.*;

public class CalendarTest {
 public static void main(String[] args) {
  GregorianCalendar d = new GregorianCalendar();
  int year = d.get(Calendar.YEAR);
  int month = d.get(Calendar.MONTH);
  int today = d.get(Calendar.DAY_OF_YEAR);
  d.set(d.get(Calendar.YEAR),0,1);                  //设置为当年1月1日(0表示1月)
  do {
   System.out.println(d.get(Calendar.MONTH) + 1 + "月");
   System.out.println("Sun Mon Tue Wed Thu Fri Sat"); //输出月表头
   month = d.get(Calendar.MONTH);                //取得月份    
   int weekday = d.get(Calendar.DAY_OF_WEEK);    //获得当月1号,在一周中是星期几
   for(int i = Calendar.SUNDAY; i < weekday; i++)//控制当月1号的起始位置
    System.out.print("    ");
   do {
    weekday = d.get(Calendar.DAY_OF_WEEK);
    if (d.get(Calendar.DAY_OF_MONTH) < 10)    //如果日期小于10,多输出一个空格,以便对齐
     System.out.print(" ");
    System.out.print(d.get(Calendar.DAY_OF_MONTH));//输出日期
    if (today == d.get(Calendar.DAY_OF_YEAR)) //如果是当日,则输出一个*号
     System.out.print("* ");
    else
     System.out.print("  ");
    if (weekday == Calendar.SATURDAY)         //到达周六,则换行
     System.out.println();
    d.add(Calendar.DAY_OF_YEAR,1);            //日期累加
   } while (d.get(Calendar.MONTH) == month);     //如果还是当月,继续循环
   System.out.println("\n");
  } while (d.get(Calendar.YEAR) == year);           //如果还是当年,继续循环
 }
}
posted @ 2006-07-22 17:17 wqwqwqwqwq 阅读(358) | 评论 (0)编辑 收藏
动机:
充分利用java阵营众多的类库

工具:

IKVM――把java bytecode 转换成IL程序,并提供大部分J2SE 1.4类的.net实现(IKVM.GNU.Classpath.dll)

winrar――提取jar,打包jar

Java IDE(可选)――阅读源代码,浏览类之间的关系,我用的是eclipse

反编译工具(可选)――没源代码时用,主要也是浏览类与类之间的关系,java反编译我用的是DJ Java Decompiler,.net用...
posted @ 2006-05-24 09:15 wqwqwqwqwq 阅读(441) | 评论 (0)编辑 收藏
SWT
Java语言的声望和它在桌面应用程序(GUI程序)所取得的成就显然极不相符,至今仍然很少能看到非常成功Java桌面程序。虽然有JBuilder, Netbean,JProbe等大型软件作为代表,但这仍不能证明Java的GUI程序是成功的:它们的外观总是和同一操作系统平台下的其它软件显得格格 不入。对机器配置的需求也似乎永无止境,这使得它们只能被一些总是拥有当前最高性能PC的程序员们所容忍,或是那些不在乎金钱和时间的专业用户所接受。对 绝大多数计算机使用者来说,AWT或SWING代表着怪异的界面和无法接受的速度。Standard Widget Toolkit(SWT)或许是Java这一噩梦的终结者,广大Java程序员终于可以开发出高效率的GUI程序,它们拥有标准的外观,几乎没有人能看出 你的程序是用Java写出来的,更为重要的是,这些程序是跨平台的。

SWT本身仅仅是Eclipse组织为了开发Eclipse IDE环境所编写的一组底层图形界面 API。或许是无心插柳,或是有意为之,至今为止,SWT无论是在性能和外观上,都超越了SUN公司提供的AWT和SWING。目前Eclipse IDE已经开发到了2.1版本,SWT已经十分稳定。这里指的稳定应该包含两层意思:

一是指性能上的稳定,其中的关键是源于SWT的设计理念。SWT最大化了操作系统的图形构件API,就是说只要操作系统提供了相应图形的构件,那么 SWT只是简单应用JNI技术调用它们,只有那些操作系统中不提供的构件,SWT才自己去做一个模拟的实现。可以看出SWT的性能上的稳定大多时候取决于 相应操作系统图形构件的稳定性。

另一个稳定是指SWT API包中的类、方法的名称和结构已经少有改变,程序员不用担心由于Eclipse组织开发进度很快(Eclipse IDE每天都会有一个Nightly版本的发布),而导致自己的程序代码变化过大。从一个版本的SWT更新至另一版本,通常只需要简单将SWT包换掉就可 以了。

第一个SWT程序

下面让我们开始一个SWT程序。(注意:以下的例子和说明主要针对Windows平台,其它的操作系统应该大同小异)。首先要在Eclipse安装文 件中找到SWT包,Eclipse组织并不提供单独的SWT包下载,必须下载完整的Eclipse开发环境才能得到SWT包。SWT是作为Eclipse 开发环境的一个插件形式存在,可以在${你的eclipse安装路径}\plugins路径下的众多子目录下去搜索SWT.JAR文件,在找到的JAR文 件中包含了SWT全部的Java类文件。因为SWT应用了JNI技术,因此同时也要找到相对应的JNI本地化库文件,由于版本和操作平台的不同,本地化库 文件的名称会有些差别,比如SWT-WIN32-2116.DLL是Window平台下Eclipse Build 2116的动态库,而在Unix平台相应版本的库文件的扩展名应该是.so,等等。注意的是,Eclipse是一个开放源代码的项目,因此你也可以在这些 目录中找到SWT的源代码,相信这会对开发很有帮助。下面是一段打开空窗口的代码(只有main方法)。

import com.e2one.example;
public class OpenShell{
public static void main(String [] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.open();
// 开始事件处理循环,直到用户关闭窗口
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}

确信在CLASSPATH中包括了SWT.JAR文件,先用Javac编译例子程序。编译无错后可运行java -Djava.library.path=${你的SWT本地库文件所在路径} com.e2one.example.OpenShell,比如SWT-WIN32-2116.DLL件所在的路径是C:\swtlib,运行的命令应该 是java -Djava.library.path=c:\swtlib com.e2one.example.OpenShell。成功运行后,系统会打开了一个空的窗口。

剖析SWT API

下面再让我们进一步分析SWT API的组成。所有的SWT类都用org.eclipse.swt做为包的前缀,下面为了简化说明,我们用*号代表前缀org.eclipse.swt, 比如*.widgets包,代表的是org.eclipse.swt.widgets包。

我们最常用的图形构件基本都被包括在*.widgets包中,比如Button,Combo,Text,Label,Sash,Table等等。其中 两个最重要的构件当数Shell和Composite。Shell相当于应用程序的主窗口框架,上面的例子代码中就是应用Shell构件打开一个空窗口。 Composite相当于SWING中的Panel对象,充当着构件容器的角色,当我们想在一个窗口中加入一些构件时,最好到使用Composite作为 其它构件的容器,然后再去*.layout包找出一种合适的布局方式。SWT对构件的布局也采用了SWING或AWT中Layout和Layout Data结合的方式,在*.layout包中可以找到四种Layout和与它们相对应的布局结构对象(Layout Data)。在*.custom包中,包含了对一些基本图形构件的扩展,比如其中的CLabel,就是对标准Label构件的扩展,上面可以同时加入文字 和图片,也可以加边框。StyledText是Text构件的扩展,它提供了丰富的文本功能,比如对某段文字的背景色、前景色或字体的设置。在 *.custom包中也可找到一个新的StackLayout布局方式。

SWT对用户操作的响应,比如鼠标或键盘事件,也是采用了AWT和SWING中的Observer模式,在*.event包中可以找到事件监听的 Listener接口和相应的事件对象,例如常用的鼠标事件监听接口MouseListener,MouseMoveListener和 MouseTrackListener,及对应的事件对象MouseEvent。

*.graphics包中可以找到针对图片、光标、字体或绘图的API。比如可通过Image类调用系统中不同类型的图片文件。通过GC类实现对图片、构件或显示器的绘图功能。

对不同平台,Eclipse还开发了一些富有针对性的API。例如,在Windows平台,可以通过*.ole.win32包很容易的调用ole控件,这使Java程序内嵌IE浏览器或Word、Excel等程序成为可能!

更复杂的程序

下面让我们展示一个比上面例子更加复杂一些的程序。这个程序拥有一个文本框和一个按键,当用户点击按键的时候,文本框显示一句欢迎信息。

为了文本框和按键有比较合理的大小和布局,这里采用了GradLayout布局方式。这种布局是SWT中最常用也是最强大的布局方式,几乎所有的格式 都可能通过GradLayout去达到。下面的程序也涉及到了如何应用系统资源(Color),以及如何释放系统资源。

private void initShell(Shell shell) {
//为Shell设置布局对象
GridLayout gShellLay = new GridLayout();
shell.setLayout(gShellLay);
//构造一个Composite构件作为文本框和按键的容器
Composite panel = new Composite(shell,SWT.NONE);
//为Panel指定一个布局结构对象。
这里让Panel尽可能的占满Shell,
也就是全部应用程序窗口的空间。
GridData gPanelData = new GridData(GridData.GRAB_HORIZONTAL| GridData.GRAB_VERTICAL|GridData.FILL_BOTH);
panel.setLayoutData(gPanelData);
//为Panel也设置一个布局对象。文本框和按键将按这个布局对象来显示。
GridLayout gPanelLay = new GridLayout();
panel.setLayout(gPanelLay);
//为Panel生成一个背景色
final Color bkColor = new Color(Display.getCurrent(),200,0,200);
panel.setBackground(bkColor);
//生成文本框
final Text text = new Text(panel,SWT.MULTI|SWT.WRAP);
//为文本框指定一个布局结构对象,
这里让文本框尽可能的占满Panel的空间。
GridData gTextData = new GridData (GridData.GRAB_HORIZONTAL| GridData.GRAB_VERTICAL|GridData.FILL_BOTH);
text.setLayoutData(gTextData);
//生成按键
Button butt = new Button(panel,SWT.PUSH);
butt.setText("Push");
//为按键指定鼠标事件
butt.addMouseListener(new MouseAdapter(){
public void mouseDown(MouseEvent e){
//当用户点击按键的时候,显示信息
text.setText("Hello SWT");
}
});
//当主窗口关闭时,会触发DisposeListener。这里用来释放Panel的背景色。
shell.addDisposeListener(new DisposeListener(){
public void widgetDisposed(DisposeEvent e) {
bkColor.dispose();
}
});
}

把这段代码中的方法initShell()加入到第一个打开空窗口的例子中,得到的是一段能成功运行的完整GUI应用程序。运行方法可参考第一个例子。  

系统资源的管理

在一个图形化的操作系统中开发程序,都要调用系统中的资源,如图片、字体、颜色等。通常这些资源都是有限的,程序员务必非常小心的使用这些资源:当不再使用它们时,就请尽快释放,不然操作系统迟早会油尽灯枯,不得不重新启动,更严重的会导致系统崩溃。
SWT是用Java开发的,Java语言本身的一大优势就是JVM的"垃圾回收机制",程序员通常不用理会变量的释放,内存的回收等问题。那么对SWT而言,系统资源的操作是不是也是如此?答案是一个坏消息,一个好消息。

坏消息是SWT并没采用JVM的垃圾回收机制去处理操作系统的资源回收问题,一个关键的因素是因为JVM的垃圾回收机制是不可控的,也就是说程序员不 能知道,也不可能做到在某一时刻让JVM回收资源!这对系统资源的处理是致命的,试想你的程序希望在一个循环语句中去查看数万张图片,常规的处理方式是每 次调入一张,查看,然后就立即释放该图片资源,而后在循环调入下一张图片,这对操作系统而言,任何时刻程序占用的仅仅是一张图片的资源。但如果这个过程完 全交给JVM去处理,也许会是在循环语句结束后,JVM才会去释放图片资源,其结果可能是你的程序还没有运行结束,操作系统已经宕掉。

但下面的好消息也许会让这个坏消息变得无关紧要。对于SWT,只需了解两条简单的"黄金"法则就可以放心的使用系统资源!之所以称为黄金法则,一是因 为少,只有两条,二是因为它们出奇的简单。第一条是"谁占用,谁释放",第二条是"父构件被销毁,子构件也同时被销毁"。第一条原则是一个无任何例外的原 则,只要程序调用了系统资源类的构造函数,程序就应该关心在某一时刻要释放这个系统资源。比如调用了

Font font = new Font (display, "Courier", 10, SWT.NORMAL);

那么就应该在不在需要这个Font的时候调用

font.dispose();

对于第二个原则,是指如果程序调用某一构件的dispose()方法,那么所有这个构件的子构件也会被自动调用dispose()方法而销毁。通常这里指的子构件与父构件的关系是在调用构件的构造函数时形成的。比如,

Shell shell = new Shell();
Composite parent = new Composite(shell,SWT.NULL);
Composite child = new Composite(parent,SWT.NULL);

其中parent的父构件是shell,而shell则是程序的主窗口,所以没有相应的父构件,同时parent又包括了child子构件。如果调用 shell.dispose()方法,应用第二条法则,那么parent和child构件的dispose()方法也会被SWT API自动调用,它们也随之销毁。

线程问题

在任何操作平台的GUI系统中,对构件或一些图形API的访问操作都要被严格同步并串行化。例如,在一个图形界面中的按键构件可被设成可用状态 (enable)或禁用状态(disable),正常的处理方式是,用户对按键状态设置操作都要被放入到GUI系统的事件处理队列中(这意味着访问操作被 串行化),然后依次处理(这意味着访问操作被同步)。想象当按键可用状态的设置函数还没有执行结束的时候,程序就希望再设置该按键为禁用状态,势必会引起 冲突。实际上,这种操作在任何GUI系统都会触发异常。

Java语言本身就提供了多线程机制,这种机制对GUI编程来说是不利的,它不能保证图形构件操作的同步与串行化。SWT采用了一种简单而直接的方式 去适应本地GUI系统对线程的要求:在SWT中,通常存在一个被称为"用户线程"的唯一线程,只有在这个线程中才能调用对构件或某些图形API的访问操 作。如果在非用户线程中程序直接调用这些访问操作,那么SWTExcepiton异常会被抛出。但是SWT也在*.widget.Display类中提供 了两个方法可以间接的在非用户线程的进行图形构件的访问操作,这是通过的syncExec(Runnable)和asyncExec(Runnable) 这两个方法去实现的。例如:

//此时程序运行在一个非用户线程中,并且希望在构件panel上加入一个按键。

Display.getCurrent().asyncExec(new Runnable() {
public void run() {
Button butt = new Button(panel,SWT.PUSH);
butt.setText("Push");
}
});

方法syncExec()和asyncExec()的区别在于前者要在指定的线程执行结束后才返回,而后者则无论指定的线程是否执行都会立即返回到当前线程。

SWT的扩展:JFace

JFace与SWT的关系好比Microsoft的MFC与SDK的关系,JFace是基于SWT开发,其API比SWT更加易于使用,但功能却没SWT来的直接。比如下面的代码应用JFace中的MessageDialog打开一个警告对话框:

MessageDialog.openWarning(parent,"Warning","Warning message");

如果只用SWT完成以上功能,语句不会少于30行!

JFace原本是为更加方便的使用SWT而编写的一组API,其主要目的是为了开发Eclipse IDE环境,而不是为了应用到其它的独立应用程序。因此在Eclipse 2.1版本之前,很难将JFace API完整的从Eclipse的内核API中剥离出来,总是要多多少少导入一些非JFace以外的Eclipse核心代码类或接口才能得到一个没有任何编 译错误的JFace开发包。但目前Eclipse组织似乎已经逐渐意识到了JFace在开发独立应用程序起到的重要作用,在正在开发的2.1版本中, JFace也开始变成了和SWT一样的完整独立的开发包,只是这个开发包还在变动中(笔者写本文时,应用的Eclipse2.1M3版本)。JFace开 发包的包前缀是以org.eclipse.jface开头。JAR包和源代码也和SWT一样,也在${你的eclipse安装路径}\plugins路径 下去找。

对开发人员来说,在开发一个图形构件的时候,比较好的方式是先到JFace包去找一找,看是不是有更简洁的实现方法,如果没有再用SWT包去自己实 现。比如JFace为对话框提供了很好的支持,除了各种类型的对话框(比如上面用的MessageDialog,或是带有Title栏的对话框),如要实 现一个自定义的对话框也最好从JFace中的Dialog类继承,而不是从SWT中的*.widget.Dialog继承。

应用JFace中的Preference包中的类很容易为自己的软件做出一个很专业的配置对话框。对于Tree、Table等图形构件,它们在显示的 同时也要和数据关联,例如Table中显示的数据,在JFace中的View包中为此类构件提供了Model-View方式的编程方法,这种方法使显示与 数据分开,更加利于开发与维护。JFace中提供最多的功能就是对文本内容的处理。可以在org.eclipse.jface.text.*包中找到数十 个与文本处理相关类。

与应用程序更近一步

Java程序通常是以class文件的方式发布的,运行class需要JRE或JDK的支持。这又是Java GUI程序的另一个致命的弱点,想象对一个面向广大用户的应用程序来说,无论你的程序功能有多简单,或是你的代码十分的精简,你都不得不让用户去下载一个 7、8M的JRE,那是多么令人沮丧的一件事。而且对程序员来说,Class通常意味着源代码的暴露,反编译的工具让那些居心叵测的人轻易得到你的源代 码。虽然有很多对Class的加密方法,但那总是以牺牲性能为代价的。好在我们还有其它的方式可用:把Class编译成exe文件!

通过SWT开发包,简单、跨平台、可靠等这些Java语言本身所具有的优点正渐渐融合到图形界面的应用程序开发中去。因此,我相信Java语言的另一扇成功之门正在逐渐打开。Java语言的声望和它在桌面应用程序(GUI程序)所取得的成就显然极不相符,至今仍然很少能看到非常成功Java桌面程序。虽然有JBuilder, Netbean,JProbe等大型软件作为代表,但这仍不能证明Java的GUI程序是成功的:它们的外观总是和同一操作系统平台下的其它软件显得格格 不入。对机器配置的需求也似乎永无止境,这使得它们只能被一些总是拥有当前最高性能PC的程序员们所容忍,或是那些不在乎金钱和时间的专业用户所接受。对 绝大多数计算机使用者来说,AWT或SWING代表着怪异的界面和无法接受的速度。Standard Widget Toolkit(SWT)或许是Java这一噩梦的终结者,广大Java程序员终于可以开发出高效率的GUI程序,它们拥有标准的外观,几乎没有人能看出 你的程序是用Java写出来的,更为重要的是,这些程序是跨平台的。

SWT本身仅仅是Eclipse组织为了开发Eclipse IDE环境所编写的一组底层图形界面 API。或许是无心插柳,或是有意为之,至今为止,SWT无论是在性能和外观上,都超越了SUN公司提供的AWT和SWING。目前Eclipse IDE已经开发到了2.1版本,SWT已经十分稳定。这里指的稳定应该包含两层意思:

一是指性能上的稳定,其中的关键是源于SWT的设计理念。SWT最大化了操作系统的图形构件API,就是说只要操作系统提供了相应图形的构件,那么 SWT只是简单应用JNI技术调用它们,只有那些操作系统中不提供的构件,SWT才自己去做一个模拟的实现。可以看出SWT的性能上的稳定大多时候取决于 相应操作系统图形构件的稳定性。

另一个稳定是指SWT API包中的类、方法的名称和结构已经少有改变,程序员不用担心由于Eclipse组织开发进度很快(Eclipse IDE每天都会有一个Nightly版本的发布),而导致自己的程序代码变化过大。从一个版本的SWT更新至另一版本,通常只需要简单将SWT包换掉就可 以了。

第一个SWT程序

下面让我们开始一个SWT程序。(注意:以下的例子和说明主要针对Windows平台,其它的操作系统应该大同小异)。首先要在Eclipse安装文 件中找到SWT包,Eclipse组织并不提供单独的SWT包下载,必须下载完整的Eclipse开发环境才能得到SWT包。SWT是作为Eclipse 开发环境的一个插件形式存在,可以在${你的eclipse安装路径}\plugins路径下的众多子目录下去搜索SWT.JAR文件,在找到的JAR文 件中包含了SWT全部的Java类文件。因为SWT应用了JNI技术,因此同时也要找到相对应的JNI本地化库文件,由于版本和操作平台的不同,本地化库 文件的名称会有些差别,比如SWT-WIN32-2116.DLL是Window平台下Eclipse Build 2116的动态库,而在Unix平台相应版本的库文件的扩展名应该是.so,等等。注意的是,Eclipse是一个开放源代码的项目,因此你也可以在这些 目录中找到SWT的源代码,相信这会对开发很有帮助。下面是一段打开空窗口的代码(只有main方法)。

import com.e2one.example;
public class OpenShell{
public static void main(String [] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.open();
// 开始事件处理循环,直到用户关闭窗口
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}

确信在CLASSPATH中包括了SWT.JAR文件,先用Javac编译例子程序。编译无错后可运行java -Djava.library.path=${你的SWT本地库文件所在路径} com.e2one.example.OpenShell,比如SWT-WIN32-2116.DLL件所在的路径是C:\swtlib,运行的命令应该 是java -Djava.library.path=c:\swtlib com.e2one.example.OpenShell。成功运行后,系统会打开了一个空的窗口。

剖析SWT API

下面再让我们进一步分析SWT API的组成。所有的SWT类都用org.eclipse.swt做为包的前缀,下面为了简化说明,我们用*号代表前缀org.eclipse.swt, 比如*.widgets包,代表的是org.eclipse.swt.widgets包。

我们最常用的图形构件基本都被包括在*.widgets包中,比如Button,Combo,Text,Label,Sash,Table等等。其中 两个最重要的构件当数Shell和Composite。Shell相当于应用程序的主窗口框架,上面的例子代码中就是应用Shell构件打开一个空窗口。 Composite相当于SWING中的Panel对象,充当着构件容器的角色,当我们想在一个窗口中加入一些构件时,最好到使用Composite作为 其它构件的容器,然后再去*.layout包找出一种合适的布局方式。SWT对构件的布局也采用了SWING或AWT中Layout和Layout Data结合的方式,在*.layout包中可以找到四种Layout和与它们相对应的布局结构对象(Layout Data)。在*.custom包中,包含了对一些基本图形构件的扩展,比如其中的CLabel,就是对标准Label构件的扩展,上面可以同时加入文字 和图片,也可以加边框。StyledText是Text构件的扩展,它提供了丰富的文本功能,比如对某段文字的背景色、前景色或字体的设置。在 *.custom包中也可找到一个新的StackLayout布局方式。

SWT对用户操作的响应,比如鼠标或键盘事件,也是采用了AWT和SWING中的Observer模式,在*.event包中可以找到事件监听的 Listener接口和相应的事件对象,例如常用的鼠标事件监听接口MouseListener,MouseMoveListener和 MouseTrackListener,及对应的事件对象MouseEvent。

*.graphics包中可以找到针对图片、光标、字体或绘图的API。比如可通过Image类调用系统中不同类型的图片文件。通过GC类实现对图片、构件或显示器的绘图功能。

对不同平台,Eclipse还开发了一些富有针对性的API。例如,在Windows平台,可以通过*.ole.win32包很容易的调用ole控件,这使Java程序内嵌IE浏览器或Word、Excel等程序成为可能!

更复杂的程序

下面让我们展示一个比上面例子更加复杂一些的程序。这个程序拥有一个文本框和一个按键,当用户点击按键的时候,文本框显示一句欢迎信息。

为了文本框和按键有比较合理的大小和布局,这里采用了GradLayout布局方式。这种布局是SWT中最常用也是最强大的布局方式,几乎所有的格式 都可能通过GradLayout去达到。下面的程序也涉及到了如何应用系统资源(Color),以及如何释放系统资源。

private void initShell(Shell shell) {
//为Shell设置布局对象
GridLayout gShellLay = new GridLayout();
shell.setLayout(gShellLay);
//构造一个Composite构件作为文本框和按键的容器
Composite panel = new Composite(shell,SWT.NONE);
//为Panel指定一个布局结构对象。
这里让Panel尽可能的占满Shell,
也就是全部应用程序窗口的空间。
GridData gPanelData = new GridData(GridData.GRAB_HORIZONTAL| GridData.GRAB_VERTICAL|GridData.FILL_BOTH);
panel.setLayoutData(gPanelData);
//为Panel也设置一个布局对象。文本框和按键将按这个布局对象来显示。
GridLayout gPanelLay = new GridLayout();
panel.setLayout(gPanelLay);
//为Panel生成一个背景色
final Color bkColor = new Color(Display.getCurrent(),200,0,200);
panel.setBackground(bkColor);
//生成文本框
final Text text = new Text(panel,SWT.MULTI|SWT.WRAP);
//为文本框指定一个布局结构对象,
这里让文本框尽可能的占满Panel的空间。
GridData gTextData = new GridData (GridData.GRAB_HORIZONTAL| GridData.GRAB_VERTICAL|GridData.FILL_BOTH);
text.setLayoutData(gTextData);
//生成按键
Button butt = new Button(panel,SWT.PUSH);
butt.setText("Push");
//为按键指定鼠标事件
butt.addMouseListener(new MouseAdapter(){
public void mouseDown(MouseEvent e){
//当用户点击按键的时候,显示信息
text.setText("Hello SWT");
}
});
//当主窗口关闭时,会触发DisposeListener。这里用来释放Panel的背景色。
shell.addDisposeListener(new DisposeListener(){
public void widgetDisposed(DisposeEvent e) {
bkColor.dispose();
}
});
}

把这段代码中的方法initShell()加入到第一个打开空窗口的例子中,得到的是一段能成功运行的完整GUI应用程序。运行方法可参考第一个例子。  

系统资源的管理

在一个图形化的操作系统中开发程序,都要调用系统中的资源,如图片、字体、颜色等。通常这些资源都是有限的,程序员务必非常小心的使用这些资源:当不再使用它们时,就请尽快释放,不然操作系统迟早会油尽灯枯,不得不重新启动,更严重的会导致系统崩溃。
SWT是用Java开发的,Java语言本身的一大优势就是JVM的"垃圾回收机制",程序员通常不用理会变量的释放,内存的回收等问题。那么对SWT而言,系统资源的操作是不是也是如此?答案是一个坏消息,一个好消息。

坏消息是SWT并没采用JVM的垃圾回收机制去处理操作系统的资源回收问题,一个关键的因素是因为JVM的垃圾回收机制是不可控的,也就是说程序员不 能知道,也不可能做到在某一时刻让JVM回收资源!这对系统资源的处理是致命的,试想你的程序希望在一个循环语句中去查看数万张图片,常规的处理方式是每 次调入一张,查看,然后就立即释放该图片资源,而后在循环调入下一张图片,这对操作系统而言,任何时刻程序占用的仅仅是一张图片的资源。但如果这个过程完 全交给JVM去处理,也许会是在循环语句结束后,JVM才会去释放图片资源,其结果可能是你的程序还没有运行结束,操作系统已经宕掉。

但下面的好消息也许会让这个坏消息变得无关紧要。对于SWT,只需了解两条简单的"黄金"法则就可以放心的使用系统资源!之所以称为黄金法则,一是因 为少,只有两条,二是因为它们出奇的简单。第一条是"谁占用,谁释放",第二条是"父构件被销毁,子构件也同时被销毁"。第一条原则是一个无任何例外的原 则,只要程序调用了系统资源类的构造函数,程序就应该关心在某一时刻要释放这个系统资源。比如调用了

Font font = new Font (display, "Courier", 10, SWT.NORMAL);

那么就应该在不在需要这个Font的时候调用

font.dispose();

对于第二个原则,是指如果程序调用某一构件的dispose()方法,那么所有这个构件的子构件也会被自动调用dispose()方法而销毁。通常这里指的子构件与父构件的关系是在调用构件的构造函数时形成的。比如,

Shell shell = new Shell();
Composite parent = new Composite(shell,SWT.NULL);
Composite child = new Composite(parent,SWT.NULL);

其中parent的父构件是shell,而shell则是程序的主窗口,所以没有相应的父构件,同时parent又包括了child子构件。如果调用 shell.dispose()方法,应用第二条法则,那么parent和child构件的dispose()方法也会被SWT API自动调用,它们也随之销毁。

线程问题

在任何操作平台的GUI系统中,对构件或一些图形API的访问操作都要被严格同步并串行化。例如,在一个图形界面中的按键构件可被设成可用状态 (enable)或禁用状态(disable),正常的处理方式是,用户对按键状态设置操作都要被放入到GUI系统的事件处理队列中(这意味着访问操作被 串行化),然后依次处理(这意味着访问操作被同步)。想象当按键可用状态的设置函数还没有执行结束的时候,程序就希望再设置该按键为禁用状态,势必会引起 冲突。实际上,这种操作在任何GUI系统都会触发异常。

Java语言本身就提供了多线程机制,这种机制对GUI编程来说是不利的,它不能保证图形构件操作的同步与串行化。SWT采用了一种简单而直接的方式 去适应本地GUI系统对线程的要求:在SWT中,通常存在一个被称为"用户线程"的唯一线程,只有在这个线程中才能调用对构件或某些图形API的访问操 作。如果在非用户线程中程序直接调用这些访问操作,那么SWTExcepiton异常会被抛出。但是SWT也在*.widget.Display类中提供 了两个方法可以间接的在非用户线程的进行图形构件的访问操作,这是通过的syncExec(Runnable)和asyncExec(Runnable) 这两个方法去实现的。例如:

//此时程序运行在一个非用户线程中,并且希望在构件panel上加入一个按键。

Display.getCurrent().asyncExec(new Runnable() {
public void run() {
Button butt = new Button(panel,SWT.PUSH);
butt.setText("Push");
}
});

方法syncExec()和asyncExec()的区别在于前者要在指定的线程执行结束后才返回,而后者则无论指定的线程是否执行都会立即返回到当前线程。

SWT的扩展:JFace

JFace与SWT的关系好比Microsoft的MFC与SDK的关系,JFace是基于SWT开发,其API比SWT更加易于使用,但功能却没SWT来的直接。比如下面的代码应用JFace中的MessageDialog打开一个警告对话框:

MessageDialog.openWarning(parent,"Warning","Warning message");

如果只用SWT完成以上功能,语句不会少于30行!

JFace原本是为更加方便的使用SWT而编写的一组API,其主要目的是为了开发Eclipse IDE环境,而不是为了应用到其它的独立应用程序。因此在Eclipse 2.1版本之前,很难将JFace API完整的从Eclipse的内核API中剥离出来,总是要多多少少导入一些非JFace以外的Eclipse核心代码类或接口才能得到一个没有任何编 译错误的JFace开发包。但目前Eclipse组织似乎已经逐渐意识到了JFace在开发独立应用程序起到的重要作用,在正在开发的2.1版本中, JFace也开始变成了和SWT一样的完整独立的开发包,只是这个开发包还在变动中(笔者写本文时,应用的Eclipse2.1M3版本)。JFace开 发包的包前缀是以org.eclipse.jface开头。JAR包和源代码也和SWT一样,也在${你的eclipse安装路径}\plugins路径 下去找。

对开发人员来说,在开发一个图形构件的时候,比较好的方式是先到JFace包去找一找,看是不是有更简洁的实现方法,如果没有再用SWT包去自己实 现。比如JFace为对话框提供了很好的支持,除了各种类型的对话框(比如上面用的MessageDialog,或是带有Title栏的对话框),如要实 现一个自定义的对话框也最好从JFace中的Dialog类继承,而不是从SWT中的*.widget.Dialog继承。

应用JFace中的Preference包中的类很容易为自己的软件做出一个很专业的配置对话框。对于Tree、Table等图形构件,它们在显示的 同时也要和数据关联,例如Table中显示的数据,在JFace中的View包中为此类构件提供了Model-View方式的编程方法,这种方法使显示与 数据分开,更加利于开发与维护。JFace中提供最多的功能就是对文本内容的处理。可以在org.eclipse.jface.text.*包中找到数十 个与文本处理相关类。

与应用程序更近一步

Java程序通常是以class文件的方式发布的,运行class需要JRE或JDK的支持。这又是Java GUI程序的另一个致命的弱点,想象对一个面向广大用户的应用程序来说,无论你的程序功能有多简单,或是你的代码十分的精简,你都不得不让用户去下载一个 7、8M的JRE,那是多么令人沮丧的一件事。而且对程序员来说,Class通常意味着源代码的暴露,反编译的工具让那些居心叵测的人轻易得到你的源代 码。虽然有很多对Class的加密方法,但那总是以牺牲性能为代价的。好在我们还有其它的方式可用:把Class编译成exe文件!

通过SWT开发包,简单、跨平台、可靠等这些Java语言本身所具有的优点正渐渐融合到图形界面的应用程序开发中去。因此,我相信Java语言的另一扇成功之门正在逐渐打开。
posted @ 2006-05-20 18:36 wqwqwqwqwq 阅读(480) | 评论 (0)编辑 收藏
使用JBuilder来制作EXE文件


倘若说看到标题后,以为jb真的提供了一种把java应用程序打包成exe文件的主流方法的话

你会失望的,下面的一个小技巧只是一个技巧而已。
 
使用JBuilder来制作可执行文件
这个是Borland不公开的使用技巧,能够通过JBuilder来制作exe文件来启动Java文件。JBui
lder并不支持本地编译机制。但是有一个隐藏的技巧可以让你从可执行文件来启动Java程序
,可以出现或者不出现console窗口。想做到这些,需要JBuilder的bin目录下的这些文件:
JBuilder.exe
JBuilderW.exe (可选)
JBuilder.config
jdk.config
JavaLauncher.dll
 
“JBuilder.exe”是一个通用的可执行外壳文件,用以启动Java程序,”JBuilderW.exe“

像是javaw.exe一样,它把”JBuilder.exe”包装起来,但是运行时候不显示那个console的
窗口。使用这些文件的关键是文件名。“JBuilder.exe”查找一个文件叫”JBuilder.confi
g”的配置文件,里面包含了运行Java程序的必须信息。同样的”JBuilderW.exe”查找”JB
uilder.exe”来启动不带Console窗口的Java程序。如果把JBuilder.exe重命名为”foo.exe
”,那”foo.exe”将去寻找”foo.config”配置文件,同样”JBuilderW.exe”被重命名为
”fooW.exe”,它会去寻找”foo.exe”文件。
说到这里,聪明的读者应该猜到怎样利用JBuilder.exe来启动应用程序了。只要把JBuilder
.exe,JBuilerW.exe,JBuilder.config改名成相应的文件名,在JBuilder.config里面指定主
类和类路径,就能够通过执行JBuilder.exe(或者被改名后的exe文件)来启动Java应用程序

。下面是用本机为例。
Borland JBuilder 5被安装在E:\jbuilder5\目录下,在E:\jbuilder5\bin\下建立一个temp
目录,然后把JBuilder.exe,JBuilder.config,JavaLauncher.dll,jdk.config四个文件拷贝
到E:\jbuilder5\bin\temp\目录下,然后在这个目录下建立一个hello目录,在这个目录下

成一个hello.java文件,即E:\jbuilder5\bin\temp\hello\hello.java文件,
file://hello.java
package hello;
public class hello{
    public static void main(String s[]){
        System.out.println("Hello, Exe file!");
    }
}
 
编译成class文件
 
编译所有java文件
 
然后打开Jbuilder.config文件,作相应的修改:
在JBuilder.config里面找到下面两行
# Start JBuilder using the its main class
mainclass com.borland.jbuilder.JBuilder
 
修改为
# Start JBuilder using the its main class
mainclass hello.hello
 
addpath E:/jbuilder5/bin/temp/
 
addpath命令是把目录加入类路径中,这个命令和其它config里面可以识别的命令可以在JBu
ilder/bin目录下的config_readme.txt里面找到详细说明。
然后将jdk.config里面的javapath修改成相对的路径,例如原来是
javapath ../jdk1.3/bin/java
修改成
javapath ../../jdk1.3/bin/java
 
最后
将JBuilder.exe,JBuilder.config修改成所需要的文件名,例如foo.exe和foo.config文件

 
现在执行foo.exe文件
可以看到执行的结果 
执行foo.exe后的运行结果
 
 
至此,通过修改JBuilder来使用exe文件启动自己的Java应用程序已经完成了。
 
但是好玩的地方并不在这个地方,下面的小技巧可能更有趣,将Jar文件打包进入exe文件!
 
假设利用上面的文件,生成hello.jar包,执行过程和运行结果jar cvf hello.jar hello\*.class 
  
 
将类文件打包成exe文件
 
然后将jar包附加到JBuilder.exe后面去,执行过程
copy /b ..\JBuilder.exe+hello.jar foo.exe 
 
将jar文件转化成exe文件
 
在foo.config(JBuilder.config)文件里面把前面加入的类路径去掉,并加入下面的路径:
addpath E:/jbuilder5/bin/temp/foo.exe
然后执行,执行结果
foo.exe 
  
变成exe文件的jar文件执行结果
 
 
看到了么?一个含jar包的exe文件被执行了!
这个过程的大致原理是:exe文件的重要信息都在文件头部,所以把乱七八糟的东西放exe文
件尾部是不要紧的;而jar/zip文件的重要信息是在文件尾部的,这样它们两不相干,能够

易的被执行。
 
请注意:读者如果使用这个功能,得自己承担可能带来的风险,因为Borland对这个功能不

供官方的支持!

posted @ 2006-05-16 19:50 wqwqwqwqwq 阅读(606) | 评论 (0)编辑 收藏
试题
第一,谈谈final, finally, finalize的区别。
final? 修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定 初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载
finally?再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。
finalize? 方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。

第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
匿名的内部类是没有名字的内部类。不能extends(继承) 其它类,但一个内部类可以作为一个接口,由另一个内部类实现。

第三,Static Nested Class 和 Inner Class的不同,说得越多越好(面试题有的很笼统)。
Nested Class (一般是C++的说法),Inner Class (一般是J***A的说法)。Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用上。具体可见http: //www.frontfree.net/articles/services/view.asp?id=704&page=1
注: 静态内部类(Inner Class)意味着1创建一个static内部类的对象,不需要一个外部类对象,2不能从一个static内部类的一个对象访问一个外部类对象

第四,&和&&的区别。
&是位运算符。&&是布尔逻辑运算符。

第五,HashMap和Hashtable的区别。
都属于Map接口的类,实现了将惟一键映射到特定的值上。
HashMap 类没有分类或者排序。它允许一个 null 键和多个 null 值。
Hashtable 类似于 HashMap,但是不允许 null 键和 null 值。它也比 HashMap 慢,因为它是同步的。

第六,Collection 和 Collections的区别。
Collections是个java.util下的类,它包含有各种有关集合操作的静态方法。
Collection是个java.util下的接口,它是各种集合结构的父接口。


第七,什么时候用assert。
断言是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为 true。如果表达式计算为 false,那么系统会报告一个 AssertionError。它用于调试目的:
assert(a > 0); // throws an AssertionError if a <= 0
断言可以有两种形式:
assert Expression1 ;
assert Expression1 : Expression2 ;
Expression1 应该总是产生一个布尔值。
Expression2 可以是得出一个值的任意表达式。这个值用于生成显示更多调试信息的 String 消息。
断言在默认情况下是禁用的。要在编译时启用断言,需要使用 source 1.4 标记:
javac -source 1.4 Test.java
要在运行时启用断言,可使用 -enableassertions 或者 -ea 标记。
要在运行时选择禁用断言,可使用 -da 或者 -disableassertions 标记。
要系统类中启用断言,可使用 -esa 或者 -dsa 标记。还可以在包的基础上启用或者禁用断言。
可 以在预计正常情况下不会到达的任何位置上放置断言。断言可以用于验证传递给私有方法的参数。不过,断言不应该用于验证传递给公有方法的参数,因为不管是否 启用了断言,公有方法都必须检查其参数。不过,既可以在公有方法中,也可以在非公有方法中利用断言测试后置条件。另外,断言不应该以任何方式改变程序的状 态。


第八,GC是什么? 为什么要有GC? (基础)。
GC是垃圾收集器。Java 程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:
System.gc()
Runtime.getRuntime().gc()

第九,String s = new String("xyz");创建了几个String Object?
两个对象,一个是“xyx”,一个是指向“xyx”的引用对象s。

第十,Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
Math.round(11.5)返回(long)12,Math.round(-11.5)返回(long)-11;

第十一,short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
short s1 = 1; s1 = s1 + 1;有错,s1是short型,s1+1是int型,不能显式转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确。

第十二,sleep() 和 wait() 有什么区别? 搞线程的最爱
sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非(a)“醒来”的线程具有更高的优先级
(b)正在运行的线程因为其它原因而阻塞。
wait()是线程交互时,如果线程对一个同步对象x 发出一个wait()调用,该线程会暂停执行,被调对象进入等待状态,直到被唤醒或等待时间到。



第十三,Java有没有goto?
Goto?java中的保留字,现在没有在java中使用。

第十四,数组有没有length()这个方法? String有没有length()这个方法?
数组没有length()这个方法,有length的属性。
String有有length()这个方法。

第十五,Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
方 法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重 载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方 法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

第十六,Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。
equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。

第十七,给我一个你最常见到的runtime exception。
ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException,
ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException

第十八,error和exception有什么区别?
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。


第十九,List, Set, Map是否继承自Collection接口?
List,Set是

Map不是

第二十,abstract class和interface有什么区别?
声 明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。
接 口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有 程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。 然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到 接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。

第二十一,abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
都不能

第二十二,接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?
接口可以继承接口。抽象类可以实现(implements)接口,抽象类是否可继承实体类,但前提是实体类必须有明确的构造函数。

第二十三,启动一个线程是用run()还是start()?
启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。



第二十四,构造器Constructor是否可被override?
构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading。

第二十五,是否可以继承String类?
String类是final类故不可以继承。


第二十六,当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
不能,一个对象的一个synchronized方法只能由一个线程访问。

第二十七,try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
会执行,在return前执行。


第二十八,编程题: 用最有效率的方法算出2乘以8等於几?
有C背景的程序员特别喜欢问这种问题。

2 << 3

第二十九,两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
不对,有相同的hash code。

第三十,当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
是值传递。Java 编程语言只由值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。


第三十一,swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
switch(expr1)中,expr1是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。

第三十二,编程题: 写一个Singleton出来。
Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。
一般Singleton模式通常有几种种形式:
第一种形式: 定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。
public class Singleton {
  private Singleton(){}
  //在自己内部定义自己一个实例,是不是很奇怪?
  //注意这是private 只供内部调用
  private static Singleton instance = new Singleton();
  //这里提供了一个供外部访问本class的静态方法,可以直接访问  
  public static Singleton getInstance() {
    return instance;   
   }
}
第二种形式:
public class Singleton {
  private static Singleton instance = null;
  public static synchronized Singleton getInstance() {
  //这个方法比上面有所改进,不用每次都进行生成对象,只是第一次     
  //使用时生成实例,提高了效率!
  if (instance==null)
    instance=new Singleton();
return instance;   }
}
其他形式:
定义一个类,它的构造函数为private的,所有方法为static的。
一般认为第一种形式要更加安全
posted @ 2006-05-16 19:45 wqwqwqwqwq 阅读(213) | 评论 (0)编辑 收藏

                                      

一,JBuilder光标定位不准确的修改:: 

在中文的Windows下面安装JBuilder后,
在IDE的代码编辑器里面光标定位会不准确,
很多人通过修改Editor的缺省字体来修改这个问题,
但是JBuilder预设的字体是最美观的。鱼与熊掌不能兼得,那么改怎么办才好呢?

其实最简单的办法就是把JBuilder的Editor里面的
缺省字体里面的语法高亮列表里面"Reserved word"的Bold的属性去掉,
就可以了,而且字体还更漂亮!

具体路径:"Editor Option"->"Color"->"Screen Element"->"Reserved word"
->"Attributes"->"Bold",把"Bold"uncheck就可以了!


Enjoy it!!
二,如何在Jbuilder中使用自定义的Server.xml文件?
这个问题相信困扰很多人了,解决办法如下
1,在jbuilder中运行web app
2,在输出窗口察看server0808的输出目录
我的jbuilder7是C:/myapp/Tomcat/conf/server8080.xml
3,把这个文件备份,
其中有这样一行

4,删除这一行,停止web app
5,此时Tomcat目录下没有conf目录了,建立这个目录,将删除了3中这句话的文件放在
conf目录,还叫做server8080.xml,把自己需要的连接池等信息加入

6,运行web app,我在jbuilder7中不会替换这个文件。

ok...........................


Using a Custom server.xml file with Tomcat in JBuilder
Question:  How do a use a custom server.xml with Tomcat in JBuilder 4,5 and 6?

Answer:
Make a copy of the JBuilder-generated server.xml file while your Web app
is running, modify the line which says the file was generated by JBuilder,
make you mods, and then AFTER you quit the Web app you were just running,
save your modified copy back to server.xml. After that, JBuilder won't
modify that file.

Note: Remember that when you shut down Tomcat you'll need to recreate
the directory that the server.xml file was in before you can save it back out.
After you've made the above modifications, JBuilder will leave the directory
alone.
 
三,如何修改jbuilderx的字体
#1: 安装JBX
#2: 改变一下,Editor|Display 里面的字体,主要是让jbx搜索系统字体
#3: 关闭JBX
#4: 用户主目录下(我的是:C:\Documents and Settings\Administrator\)
.primetimeX/user_zh.properties

添加一行:
editor.display;fixed_fonts.3=\u5b8b\u4f53

就可以啦!
同样也可以添加其它字体,只要在
editor.display;known_fonts
列表中有的,都可以添加,顺序编号就行了

#5: 重起JBX
posted @ 2006-05-16 19:42 wqwqwqwqwq 阅读(468) | 评论 (0)编辑 收藏
这是一篇关于怎样使用JBuilder开发j2me程序的例子。本人使用JBuilder2005,2005自带WTK2.1,自己下载2.2版 本,2.2那个默认的模拟器很好用。另外,Jbuilder X下的WTK也是2.0的版本好象。Jbuilder 9的WTK是1.04。

首先开启Jbuilder.建立一个Project。





然后填写名字和路径。继续:


然后选择JDK路径,本身已有WTK2.1,你可以选择。但是你也可以自己选择其他的WTK版本。



点击jdk后面的路径按钮,继续:


然后ok,next.工程建立完毕.
接着点击file->New:



然后在对话框左边选择Micro,你就能看到右边出现MIDlet,Displayable.

接上面的:如图示




点击MIDlet or Displayable,则让你输入MIDlet的名字.如图:



继续下一步,让你输入一个Displayable的名字,包括类型(form,canvas等),是否自动加载Command

等等



然后Jbuilder自动生成所需代码,以及Jbuilder自加的一些东西.你可以添加或修改之.

这里我将本站一篇关于介绍Gamecanvas的文章的代码拿过来,做少量修改,作为本文章的一个演示;
TestMIDlet.java文件:


package temps;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

/**
* Title:
*
* Description:
*
* Copyright: Copyright (c) 2005
*
* Company:
*
* @author not attributable
* @version 1.0
*/

public class TestMIDlet extends MIDlet
{
private Display display;

public void startApp()
{
try
{
display = Display.getDisplay(this);
Displayable1 gameCanvas = new Displayable1();
gameCanvas.start();
display.setCurrent(gameCanvas);
}
catch (Exception ex)
{
System.out.println(ex);
}
}

public Display getDisplay()
{
return display;
}

public void pauseApp()
{
}

public void destroyApp(boolean unconditional)
{
exit();
}

public void exit()
{
System.gc();
destroyApp(false);
notifyDestroyed();
}
}


Displayable1.java内容:

package temps;

import javax.microedition.lcdui.*;
import java.util.Random;
import javax.microedition.lcdui.game.*;
/**
* Title:
*
* Description:
*
* Copyright: Copyright (c) 2005
*
* Company:
*
* @author not attributable
* @version 1.0
*/

public class Displayable1 extends GameCanvas implements Runnable
{
private boolean isPlay; // Game Loop runs when isPlay is true
private long delay; // To give thread consistency
private int currentX, currentY; // To hold current position of the 'X'
private int width; // To hold screen width
private int height; // To hold screen height
private Random random=new Random(System.currentTimeMillis());
private final int[] sequence={0,1,2,1,0,1,2,1,0,1,2,1,1,1,1,1,1};
private int counter=0;
private int enemyX,enemyY;
private int enemyDirect=0;
private boolean isdown=false;

private boolean isalive=true;

// Sprites to be used
private Sprite playerSprite;
private Sprite backgroundSprite;
private Sprite enemySprite;

// Layer Manager
private LayerManager layerManager;

// Constructor and initialization
public Displayable1() throws Exception
{
super(true);
width = getWidth();
height = getHeight();

currentX = width / 2;
currentY = height / 2;
enemyX=width/4;
enemyY=height/4;
delay = 100;

Image playerImage=null;
Image backgroundImage=null;
Image enemy=null;
// Load Images to Sprites
try
{
playerImage = Image.createImage("/transparent.png");
backgroundImage = Image.createImage("/background.png");
enemy=Image.createImage("/frames.png");
}
catch(Exception e)
{
System.out.println("get Image error!"+e.getMessage());
}

playerSprite = new Sprite(playerImage, 32, 32);
System.out.println(playerSprite.getRawFrameCount());
enemySprite=new Sprite(enemy,50,21);
backgroundSprite = new Sprite(backgroundImage);
layerManager = new LayerManager();
layerManager.append(playerSprite);
layerManager.append(enemySprite);
layerManager.append(backgroundSprite);

}

// Automatically start thread for game loop
public void start()
{
isPlay = true;
Thread t = new Thread(this);
t.start();
}

public void stop()
{
isPlay = false;
}

// Main Game Loop
public void run()
{
Graphics g = getGraphics();
while (isPlay == true)
{
input();
drawScreen(g);
try
{
Thread.sleep(delay);
}
catch (InterruptedException ie)
{

}
}
}

// Method to Handle User Inputs
private void input()
{
int keyStates = getKeyStates();

playerSprite.setFrame(0);
if(isalive)
{
if(counter==0)
{
enemyDirect=Math.abs(random.nextInt()%4);
}
counter++;
switch(enemyDirect)
{
case 0:
enemyY=Math.max(0,--enemyY);
break;
case 1:
enemyY=Math.min(++enemyY,height-enemySprite.getHeight());
break;
case 2:
enemyX=Math.max(0,--enemyX);
break;
case 3:
enemyX=Math.min(++enemyX,width-enemySprite.getWidth());
break;
}
counter=(counter++)%(sequence.length());
enemySprite.setFrame(sequence[counter]);
}
else
{
enemyY+=counter;
enemyY=Math.min(enemyY,height-enemySprite.getHeight());

if(enemyY
counter++;
enemySprite.setFrame(3);
}

// Left
if ((keyStates & LEFT_PRESSED) != 0)
{
currentX = Math.max(0, currentX - 1);
playerSprite.setFrame(1);
}

// Right
if ((keyStates & RIGHT_PRESSED) != 0)
if (currentX + 5 < width)
{
currentX = Math.min(width, currentX + 1);
playerSprite.setFrame(3);
}

// Up
if ((keyStates & UP_PRESSED) != 0)
{
currentY = Math.max(0, currentY - 1);
playerSprite.setFrame(2);
}

// Down
if ((keyStates & DOWN_PRESSED) != 0)
{
isdown=true;
}

if ((keyStates & DOWN_PRESSED) != 0)
{
if(isdown)
{
if (currentY + 10 < height)
{
currentY = Math.min(height, currentY + 1);
playerSprite.setFrame(4);
}
}
}

if((keyStates & FIRE_PRESSED)!=0)
{
isalive=!isalive;
counter=0;
}

if(!(enemyX+enemySprite.getWidth()currentX+playerSprite.getWidth() || enemyY>currentY+playerSprite.getHeight()) && isalive)
{
counter=0;
isalive=false;
}
}

// Method to Display Graphics
private void drawScreen(Graphics g)
{
g.setColor(0xffffff);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(0x0000ff);

// updating player sprite position
playerSprite.setPosition(currentX, currentY);
enemySprite.setPosition(enemyX,enemyY);

layerManager.setViewWindow(0, 0, width, height);
layerManager.paint(g, 0,0);

g.setColor(0xffffff);
flushGraphics();
}

}


  此程序里敌人随机向4个方向移动,而玩家控制的角色可任意移动, 如果两者发生碰撞,则敌人死亡.

  另外按fire键可直接让敌人生或死
关于运行,Jbuilder里有个运行配置:




一般不用修改,如果多个Midlet,你可以在这里添加.

关于用Jbuilder打包.

一样file->new:




这个在2005和9,x里有所不同,选择Archive,右边选择MIDlet,然后ok.




这里选择要打包文件的目录,当前默认是所有的class文件和资源文件,你也可以删除掉,自己选择一部分.

然后next,直到最后. 然后运行,在运行配置中默认重新rebuild,打包等等.然后你能看到左上框里有jar文件和jad文件.




运行结果:




呵呵,用你控制的主角去碰撞这只大飞虫试试:

posted @ 2006-05-09 18:31 wqwqwqwqwq 阅读(530) | 评论 (0)编辑 收藏
在无线通信领域有两项重大的技术应用,一个是宽带CDMA技术,一个是IP技术。前者使无线通信获得更多带宽,3G的目标是静态速率达到2Mbps,而现 在的2.5G技术(如国内正在建设的GPRS和CDMA2000 1X)都可达到115kbps的速率;后者使无线通信和因特网融合起来,实际上当前WAP2.0技术就采用已经很成熟的TCP、TLS和HTTP协议,而 移动IP和IPv6技术将促使更多设备接入互联网,如各种设备、家电等。

  就是在这样的环境下J2ME技术得以快速发展,J2ME用来为接入和即将接入互联网的设备提供应用开发平台和执行环境,本文则主要论述如何利用JBuilder进行快速的J2ME应用开发。

  1. J2ME分层结构及MIDP简表

J2ME是SUN的JAVA2平台微型版(JAVA2平台3个版本之一,另两个是标准版J2SE和企业版J2EE),采用3层结构设计。最低层为配置层 (Configuration),包括虚拟机(VM)和类库两部分,这一层与设备层(硬件及操作系统)关系紧密,由SUN提供参考规范和源代码,设备厂商 根据设备特征进行相应的移植。当前J2ME提供有两个配置:连接设备配置(CDC)和有限连接设备配置(CLDC)。前者主要面向有较大内存和处理能力而 只需有限功能的设备,如电视置顶盒、冰箱、汽车导航设备等,这些设备都有连接网络和相互交互的需求,其内存在2M以上;后者主要面向对内存和处理能力有较 大限制的手持设备,如现在使用的手机、PDA等,现在及将来大多数这些设备都已经能够接入互联网,其内存范围160Kb(其中128Kb用于虚拟机及类 库,至少32Kb用于CLDC规范所要求的应用程序堆栈空间)到2M。二者主要区别在于能提供给VM及应用程序的存储空间,CDC所用VM及类库实际是参 考J2SE标准,去除了不需要的功能如AWT。CLDC所用VM(称作KVM)则有较大区别,包括类验证机制。对于下一代移动终端设备如智能电话、高端 PDA,则是CDC所应用对象,因为它们将有超过2M的内存。

  设备层之上是简表层(Profile),再之上则是应用层 (Application)。简表层扩展了配置层功能为上层应用提供API,如果说配置层面向设备,简表层则面向应用。可以根据需要在CDC或CLDC基 础之上提供多种简表,一个配置层之上也可以有多个简表。当前CDC之上有基础简表(Foundation Profile)和基于FP的Personal Profile和RMI Profile。CLDC之上则主要提供有移动信息设备简表(MIDP),即用于手机、PDA等移动终端的设备简表,提供API以支持无线应用的开发。

  CLDC类库一部分来自J2SE,这部分类库是经过裁减的,去除了不必要的功能,主要包括java.lang包中的系统类、数据类型 类、异常处理类,java.util包的集合类、时间类和附加工具类,java.io包的I/O处理类。CLDC专有类则主要是"通用连接框架(GCF) ",为CLDC提供网络连接功能,这些网络接口都是Connection类的子类,由类Connector所提供的方法调用,这些接口或类位于包 javax.microedition.io。

  CDC类库则是CLDC的超集,因此为CLDC开发的应用程序可以移植到CDC平 台,由于CDC采用标准的J2SE VM,因此其开发与标准的J2SE开发一致,只是在用javac工具编译源代码时需要使用CDC的类库,即使用-bootclasspath参数指向 CDC类库。

  MIDP扩展了CLDC的功能,它继承了GCF并在此基础上增加了类HttpConnection,用以提供 HTTP连接功能(尽管从理论上CLDC/MIDP可以提供socket、数据报、文件、NFS等多种连接类型,但现在标准的CLDC/MIDP仅支持 HTTP协议,一些设备实现则提供了socket和HTTPS协议的支持),MIDP类库

  总结如下:

  java.io、java.lang、java.util,属于MIDP的核心包,分别用来提供系统I/O、语言支持和工具支持。包中的类来自CLDC并稍有增加,但都来自J2SE。

  javax.microedition.midlet,定义了MIDP应用程序,以及应用程序和它所运行于环境之间的交互。

  javax.microedition.lcdui,为MIDP应用程序提供用户界面API。

  javax.microedition.rms,用来为MIDlet提供持久存储的机制,应用程序可以存储数据,在以后需要的时候获取这些数据。

  javax.microedition.io,提供了基于CLDC通用连接框架的网络支持。


2. MIDP应用程序开发

  这里讨论的J2ME无线应用开发主要是基于CLDC/MIDP的开发,其应用程序可运行于移植有KVM的手机、PDA等,这类设备由MIDP定义,即移动信息设备(MID),可看作一垂直应用市场。

  可在PC(Windows、UNIX或Linux平台)上开发MIDP应用程序,编译成类文件形式,下载到目标设备上,经过类文件的验证(验证是否有不符合KVM规范的方法调用等)后即可解释执行。

  生成的.java文件至少有一个是扩展了javax.microedition.midlet.MIDlet类的子类,并且实现几个规定的接口,比如下面的一个MIDlet程序 :


import javax.microedition.midlet.*; //应用程序生命周期,和J2SE一样,包java.lang.*是默认加载的
import javax.microedition.lcdui.*; //MIDP用户界面
public class FirstMIDlet extends MIDlet implements CommandListener {
private Display display; // 引用MIDlet的Display 对象
private TextBox textBox; // Textbox 显示一条消息
private Command cmdExit; // 设定按钮用于退出MIDlet
public FirstMIDlet() { // MIDlet构造程序
display = Display.getDisplay(this);
cmdExit = new Command("Exit", Command.SCREEN, 1);
textBox = new TextBox("My First MIDlet", "Hello, J2ME!", 50, 0);
textBox.addCommand(cmdExit);
textBox.setCommandListener(this);
}
public void startApp() { // 必须要实现的接口,被应用管理软件调用来启动MIDlet
display.setCurrent(textBox);
}
public void pauseApp() { } // 必须要实现的接口
public void destroyApp(boolean unconditional) { } //必须要实现的接口
public void commandAction(Command c, Displayable d) { //检查一下是否选择了退出命令
if (c == cmdExit) {
destroyApp(false);
notifyDestroyed();
}
}
}

这是最简单且功能完整的MIDlet应用程序,其中接口startApp、pauseApp、destroyApp是必须要实现的,应用程序管理器 (JAM)通过这些接口调用和控制应用程序,与Applet类似。除这个主类外还可以有其它辅助类,其要求和J2SE一致。

然后使用 javac工具编译,javac工具来自J2SE,至少JDK 1.3版,编译时应该使用参数-bootclasspath并指向MIDP类库。之后使用preverify工具预验证,以保证生成的.class文件符 合CLDC要求,这一步为每个类文件添加堆栈映射(stackmap,此属性为CLDC新定义)属性,增加类文件大小约5%。

  此时可以用midp工具(来自MIDP实现的可执行文件)模拟运行,之后即可打包,需要编写一清单文件(清单文件参考CLDC/MIDP规范),用jar工具(来自J2SE)把预验证后的类文件、资源文件、清单文件打包。

要发布应用程序还需要编写一描述文件(JAD),JAD的要求同清单文件一致,可以自定义参数供应用程序调用。其中一个参数MIDlet-Jar- URL以URL方式指向JAR文件,移动终端设备通过JAM连接网络获取JAD,下载MIDlet-Jar-URL指向的JAR到设备中,通常JAM要先 判断JAD与清单文件是否一致,应用程序是否有效,然后才决定下载。

  运行时执行环境、JAR包、JAD文件和应用程序生命周期,这些要素构成MIDlet套件,由JAM管理,每个MIDlet套件可包含一个或多个MIDlet。

  上面是一个MIDP应用程序开发的关键点,具体的开发方法及开发工具大致分为如下几种:

  Ⅰ. 基本开发工具

最基本的开发方式是下载SUN提供的CLDC/MIDP参考实现及源代码,可根据需求编译生成一个CLDC/MIDP实现,并移植到设备上。配置好开发 环境(CLDC/MIDP实现、JDK1.3)后即可采用上述方法和工具进行开发,多采用命令行方式,这是最原始的方法。

  Ⅱ. J2MEWTK开发工具

这是SUN提供的便捷开发工具,用于Windows环境,同样需要先安装JDK1.3。源程序仍需要使用常规的文本编辑器,把编辑好的源文件及资源文件 按一定要求放在规定目录下,J2MEWTK所提供的是菜单或按钮方式的命令。J2MEWTK中有相应的编译(和预验证一个步骤)、打包、模拟运行的菜单 (或按钮),以及其它辅助工具。

  Ⅲ. IDE工具

  可以使用Forte For Java、JBuilder等IDE工具和J2MEWTK集成使用,它们除了有J2MEWTK的功能外,就是提供有可视化的开发工具。

3. 使用JBuilder MobileSet

JBuilder是Java程序员常用工具之一,在于它强大的可视化编程工具,集成的编译、运行和调试环境。要为JBuilder提供J2ME无线应用 开发支持,需要在JBuilder基础之上安装MobileSet,建议安装2.0版,当前支持CLDC/MIDP的1.0.3版本,而JBuilder 的版本应该是6。JBuilder MobileSet 2可从下面网址免费下载:

  http: //www.borland.com/jbuilder/mobileset/ 同时还要下载相应的MobileSet序列号和许可密钥(免费),根据提示安装MobileSet并注册后,运行JBuilder会找到 "Help|MobileSet Guilde"菜单项。使用菜单"File->New..."打开"Object Gallery"对话框,会出现一个新的页面标签"Micro",此时图标"MIDlet"和"MIDP Displayable"是灰色的,只有生成一个MIDP项目后才能使用这两个图标。

  3.1 JBuilder MobileSet的特征

  JBuilder MobileSet是一个开放工具,能够与其它供应商提供的J2ME开发工具包集成在一起,当前提供了对下列厂商工具包的支持:

  Sun提供的J2ME无线开发工具包1.0.3版(J2MEWTK)

  诺基亚的J2ME开发套件(http://forum.nokia.com/)

  西门子的SMTK开发工具包(http://www.siemens-mobile.de/)

  其中J2MEWTK已经包含在MobileSet 2的安装文件中,如果要使用J2MEWTK提供的开发类库,并且还没有安装J2MEWTK,可以在安装MobileSet 2时选择完全安装。MobileSet 2提供了下列辅助开发的工具:
 
  用于CLDC/MIDP类的CodeInsight工具

  类/包浏览器

  JDK转换工具

  动态适配到任何J2ME简表,包括MIDP

和开发其它Java应用程序一样,JBuilder通过MobileSet提供了快速开发模板,包括MIDP项目模板,MIDP Displayable模板,MIDlet模板。它提供了RAD(快速应用开发)的可视设计器,支持MIDP UI元素。通过MobileSet还支持MIDP应用程序打包和OTA配置(Over the Air,上载和下载文件和MIDlet套件,用来配置应用程序到设备上)。

  MobileSet能够用在JBuilder的个人版、专家版和企业版,但是一些功能不能用在个人版如JDK设置切换,打包器等。

  3.2 配置JDK

前面已提到编译MIDP应用程序时需要设置特定的CLDC/MIDP类库,以避免使用默认的J2SE类库,在JBuilder中同样要进行类似设置。这 是通过JDK配置选项实现的,JBuilder的设计独立于JDK,尽管每个JBuilder版本发布时会默认安装一个当时较新的JDK(类库),但还可 以通过它的配置机制设置其它JDK,包括旧版本、更新版本或者OEM版的JDK,从而实现了JBulder的扩展性。

  专家版和企 业版的JBuilder可同时配置多个JDK,根据需要设置其中一个为默认即可,而个人版的却要在需要时重新配置每个JDK。安装MobileSet后可 选择安装J2MEWTK、诺基亚和西门子的JDK,然后为设置的每个JDK自定义一个名称,并把其主目录指向这个JDK中\bin的父目录,需要注意的是 JDK目录中不能有空格如c:\Program Files\ J2mewtk。

  3.3 MIDP项目

JBuilder开发都以项目概念为中心,项目文件包含一个(属于这个项目的)文件列表以及项目属性,其中项目属性包括项目模板、缺省路径、类库和连接配 置等,JBuilder使用这些信息加载、保存、编译和运行项目。使用Jbuilder开发环境添加、移除文件,或者设置、更改项目属性都会更改项目文 件。可以在项目面板中看到项目文件作为主节点显示。

  生成项目的便捷方式是使用项目模板工具,可用来设置项目名称、类型和模板,以及JDK、工作目录、备份路径和编译输出路径等。其中项目类型可选择.jpx或者.jpr,二者内容一样,区别是前者使用XML格式文件,因此适合于共享的项目。

而JDK则是前面所设置中的一个,并且只有选择CLDC/MIDP的JDK才能使用Object Gallery中的Micro选项。每个项目至少一个MIDlet主类,所以首先应使用MIDlet模板生成一个MIDlet主类。通过模板可以设置这个 主类的类名、标题、屏幕类型和命令处理方式,其中屏幕类型有4个选择:

  (javax.microedition.lcdui.)Canvas、Form、List、TextBox,只有Form的扩展类才能添加其它的组件(Item的子类)。命令处理方式也有4个选择:

  Ⅰ. -- 通过其它的类设置commandListener,比如MIDlet类。

  Ⅱ. Interface implementation -- 生成一个类并在类中实现commandListener接口,这种方式生成的类的大小会比适配器方式生成的小。

  Ⅲ. Standard adapter -- 这种方式生成的代码采用标准适配器的形式:


class Foo {
private void jbInit() {
addListener(new Adapter(this));
}
}
class Adapter {
...
}

  Ⅳ. Anonymous adapter -- 这种方式生成的代码采用匿名适配器的形式:


class Foo {
private void jbInit() {
addListener(new Listener() {
...
});
}
}

  后两种适配器形式可以通过项目属性"Code Style"设置。如果要在这个MIDP应用程序中添加更多的屏幕,可以使用Displayable模板添加,或者通过MIDlet模板添加更多的MIDP应用程序到项目中。

  生成应用程序框架后,就可根据本文第2部分要求添加所需代码,并使用JBuilder提供的便捷方式进行编译(预验证)、打包、模拟运行和发布,JBuilder提供有内置web服务器和ftp服务器,以方便开发者测试应用程序的发布。

如果使用MIDlet或Displayable模板生成一个Form类型的Displayable对象,则可以使用JBuilder的"MIDP设计器 "定制用户界面,即从组件板上以拖拉方式生成UI元素,可用鼠标调整这些元素的位置或者进行复制、删除等操作,这就是JBuilder强大功能之所在。

  如果是使用模板生成Displayable类,会自动生成jbInit()方法,当在Form中添加UI元素时,设计器会把代码添加 进jbInit()方法。如果希望打开一个现有Displayable类到设计器,它已经有UI元素,但是没有jbInit()方法,首先需要生成一个 jbInit()方法,然后把所有的UI元素转移进去。
posted @ 2006-05-09 18:17 wqwqwqwqwq 阅读(296) | 评论 (0)编辑 收藏
     摘要: Java中一些关于日期、日期格式、日期的解析和日期的计算 (转) 跑系统时,难免遇到了数据量大的情况,只好让爱机彻夜工作了,自己闪人。毕竟对它不放心,这时得用到日志,日志里的时间肯定是要的啦。至少得知道他什么时候罢工吧(今天一来,我电脑就在昨天不明时间罢工了!)。下面是转自一位网友的: Java中一些关于日期、日期格式、日期的解析和日期的计算 Java 语言的Calendar...  阅读全文
posted @ 2006-05-09 17:53 wqwqwqwqwq 阅读(4581) | 评论 (0)编辑 收藏
   其实无论什么东西,我们都不能否认它能带来的好处,但也决不能因此就忽视了不好的地方,甚至盲目的追崇和信赖.
   java的IDE 开发环境也是一样,它们让我们的程序开发变得简单等等很多好处,但是我们真的就完全的对它推崇吗? 答案当然是否定的.对于我们,尤其是初探java 的朋友们,如果过于追求IDE的使用,可能会使我们忽略java 本身的精髓,而只是学会如何的去使用IDE.
    同时在大型程序的开发过程中,如果IDE本身的错误或不兼容现象的产生,会让我们很难办.程序的优化问题一直是一个很值得研究的问题,尤其是在我们这个有限资源的社会当中.
   今天由于时间限制,我仅写到这里,IDE还有很多值得我们关注的地方,但是即便如此,我们也并不能排斥它,因为它确实为我们实际地工作和学习带来了很多方便之处.相反,我们要有想法有对策的更好的利用IDE.
  
posted @ 2006-05-08 22:50 wqwqwqwqwq 阅读(236) | 评论 (0)编辑 收藏
<2006年5月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910




常用链接

留言簿(10)

随笔分类(95)

随笔档案(97)

文章档案(10)

相册

J2ME技术网站

java技术相关

mess

搜索

  •  

最新评论

阅读排行榜

校园梦网网络电话,中国最优秀的网络电话