posts - 36, comments - 30, trackbacks - 0, articles - 3

2008年1月16日

这部分介绍如何分视图显示前面讲的表格内容,Backbone中视图可以嵌套显示,例如前面例子中整个页面可以用一个视图来渲染,table表格可以用一个视图来渲染,表格中的一行可以用一个视图来渲染,这样就用三层视图,只要在以前的例子上稍作修改就可以实现这效果。

 
首先定义最里层的视图,表格中的行。通过tagName成员变量指定该视图对应的html元素,render方法中指定tr元素中显示的内容。当然也可以指定成员变量className的值,来指定tr元素显示的式样。

     var StudentView = Backbone.View.extend({
         
         tagName: 'tr',
         
         render: function() {
             $(this.el).html(_.map([
                 this.model.get('id'),
                this.model.get('name'),
                this.model.get('age')
             ],function(val, key){
                 return '<td>' + val + '</td>';
             }))
            
            return this;
         }
     })

其次显示表格的视图。
     var StudnetCollectionView = Backbone.View.extend({
         
         tagName: 'table',
         
         render: function() {
            $(this.el).empty();
            
              $(this.el).append($('<tr></tr>')).html(_.map([
                  '学号','姓名','年龄'
              ],function(val, key){
                  return '<th>' + val + '</th>';
              }));
            
              $(this.el).append(_.map(this.collection.models,
                function(model, key){
                      return new StudentView({
                          model: model
                      }).render().el;
              }));
            
            return this;
         }
     });

最后显示整个页面的视图。
     var StudnetPageView = Backbone.View.extend({
         render: function() {
             $(this.el).html(new StudnetCollectionView({
                 collection: this.collection
             }).render().el);
         }
     })

同时修改一下显示部分的代码。

    var studentPageView = new StudnetPageView({
             collection: studentCollection,
             el: 'body'
         });
 
         studentPageView.render();

整个main.js的代码如下:

  (function($){
      $(document).ready(function(){
          
          var student1 = new Student({
              id: 10000,
              name: '王小二',
              age: 30
          });
          
         var student2 = new Student({
             id: 20000,
             name: '姚敏',
             age: 26
         });
         
         var student3 = new Student({
             id: 30000,
             name: '科比',
             age: 24
         });
         
         var studentCollection = new StudentCollection([
             student1,
             student2,
             student3
         ]);
         
         var studentPageView = new StudnetPageView({
             collection: studentCollection,
             el: 'body'
         });
 
         studentPageView.render();
         
     });
     
     //set model
     var Student = Backbone.Model.extend({
         //set default values.
         defaults: {
             id: 0,
             name: '',
             age: 0
         }
     });
     
     var StudentCollection = Backbone.Collection.extend({
         model: Student
     });
     
     var StudentView = Backbone.View.extend({
         
         tagName: 'tr',
         
         render: function() {
             $(this.el).html(_.map([
                 this.model.get('id'),
                this.model.get('name'),
                this.model.get('age')
             ],function(val, key){
                 return '<td>' + val + '</td>';
             }))
            
            return this;
         }
     })

     //set view
     var StudnetCollectionView = Backbone.View.extend({
         
         tagName: 'table',
         
         render: function() {
            $(this.el).empty();
            
              $(this.el).append($('<tr></tr>')).html(_.map([
                  '学号','姓名','年龄'
              ],function(val, key){
                  return '<th>' + val + '</th>';
              }));
            
              $(this.el).append(_.map(this.collection.models,
                function(model, key){
                      return new StudentView({
                          model: model
                      }).render().el;
              }));
            
            return this;
         }
     });
     
     var StudnetPageView = Backbone.View.extend({
         render: function() {
             $(this.el).html(new StudnetCollectionView({
                 collection: this.collection
             }).render().el);
         }
     })
     
 })(jQuery);

posted @ 2016-04-04 17:40 笑看人生 阅读(148) | 评论 (0)编辑 收藏

@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); 在学习笔记一中,一个视图渲染一个Sudent对象,如果存在多个Student对象怎么办,
在java中可以通过ArrayList来保存,比如List<Student> students = new ArrayList<>();
在Backbone中,也有类似于ArrayList的实现,只需要新建一个类,继承Collection就可以了,实现代码如下:
成员变量model指定集合中存放对象的类型,类似于java中范型。

1     var StudentCollection = Backbone.Collection.extend({
2         model: Student
3     });

对学习笔记一种代码稍加修改,修改代码如下:
新建三个Student对象,把这三个对象加入studentCollection对象中。

 1         var student1 = new Student({
 2             id: 10000,
 3             name: '王小二',
 4             age: 30
 5         });
 6         
 7         var student2 = new Student({
 8             id: 20000,
 9             name: '姚敏',
10             age: 26
11         });
12         
13         var student3 = new Student({
14             id: 30000,
15             name: '科比',
16             age: 24
17         });
18         
19         var studentCollection = new StudentCollection([
20             student1,
21             student2,
22             student3
23         ]);

至此集合模型已经新建完毕,那么如何通过视图来显示这个集合模型。

学习笔记一中新建的StudentView类的render方法做修改,同时在构建这个类对象时,稍作修改,修改如下:
把原来绑定model的代码改成绑定collection。

1 var studentCollectionView = new StudnetCollectionView ({
2             collection: studentCollection
3  });

 1     var StudnetCollectionView = Backbone.View.extend({
 2         
 3         el: 'body',
 4         
 5         render:function(){
 6             var html = '';
 7             _.each(this.collection.models,function(model,index,obj){
 8                 var tmp = '学号: ' + model.get('id') + '.' +
 9                           '姓名: ' + model.get('name') + '.' +
10                           '年龄: ' + model.get('age');
11                 
12                 html = html + '<li>' + tmp + '</li>'; 
13             });
14             
15             html = '<ul>' + html + '</ul>';
16             $(this.el).html(html);
17         }
18     });

完整的main.js内容如下:
 1 (function($){
 2     $(document).ready(function(){
 3         
 4         var student1 = new Student({
 5             id: 10000,
 6             name: '王小二',
 7             age: 30
 8         });
 9         
10         var student2 = new Student({
11             id: 20000,
12             name: '姚敏',
13             age: 26
14         });
15         
16         var student3 = new Student({
17             id: 30000,
18             name: '科比',
19             age: 24
20         });
21         
22         var studentCollection = new StudentCollection([
23             student1,
24             student2,
25             student3
26         ]);
27         
28         var studentCollectionView = new StudnetCollectionView({
29             collection: studentCollection
30         });
31 
32         studentCollectionView.render();
33         
34     });
35     
36     //set model
37     var Student = Backbone.Model.extend({
38         //set default values.
39         defaults: {
40             id: 0,
41             name: '',
42             age: 0
43         }
44     });
45     
46     var StudentCollection = Backbone.Collection.extend({
47         model: Student
48     });
49     
50     //set view
51     var StudnetCollectionView = Backbone.View.extend({
52         
53         el: 'body',
54         
55         render:function(){
56             var html = "<table border='1'><tr><th>学号</th><th>姓名</th><th>年龄</th></tr>";
57             _.each(this.collection.models, function(model,index,obj){
58                 var tmp = '<tr><td>' + model.get('id') + '</td>' +
59                           '<td>' + model.get('name') + '</td>' +
60                           '<td> ' + model.get('age') + '</td></tr>';
61                           
62                           
63                 html = html = html + tmp;
64             });
65             
66             html = html + '</table>';
67             $(this.el).html(html);
68         }
69     });
70     
71 })(jQuery);
72 


posted @ 2016-04-02 12:06 笑看人生 阅读(821) | 评论 (0)编辑 收藏

项目里用到Backbone+marionet框架,由于以前没有接触过这些技术,经过一段时间的学习,觉得这技术还是很强大的,现把
学习体会总结一下,以便后面查询。

Backbone是一个基于MVC模式的前端JavaScript框架,用于前端页面开发。
可以从http://backbone.js上下载对应的版本。

使用Backbone,需要依赖其他一些js库。
jQuery  http://jquery.com
Underscore http://underscorejs.org

页面的head元素内容大体如下:
1 <script src="lib/jquery-2.2.2.js"></script>
2 <script src="lib/underscore-2.js"></script>
3 <script src="lib/backbone.js"></script>

Backbone是一个MVC框架,通过V来展示M的内容,C接受用户的请求,更新模型,然后刷新V。

下面以一个例子,来说明怎么建立一个简单的Backbone应用。

首先定义一个Model类Student, 需要继承Backbone.Model,这个类有三个成员变量,id,name,age,套用java中的叫法,其实可能
不应该这么称呼。

1     var Student = Backbone.Model.extend({
2         //set default values.
3         defaults: {
4             id: 0,
5             name: '',
6             age: 0
7         }
8     });


然后定义一个View类StudentView,需要继承Backbone.View, 给这个类的成员变量el赋值 body,指明在页面的body元素中渲染视图,
同时重写了渲染方法render,指明如何渲染,以下代码应用jQuery的语法,在el指定的元素内,显示指定的内容。
每个视图绑定一个Model,在View的所有方法中可以直接调用this.model获取当前View绑定的Model对象,如下例子
this.model.get('id'),注意获取model属性值时,不能直接使用thi.model.id

 1     var StudnetView = Backbone.View.extend({
 2         
 3         el: 'body',
 4         
 5         render:function(){
 6             var html = '学号: ' + this.model.get('id') + '.' +
 7                        '姓名: ' + this.model.get('name') + '.' +
 8                        '年龄: ' + this.model.get('age');
 9     
10             $(this.el).html(html);
11         }
12     });

定义完模型和视图类之类,接下来就是创建模型类和视图类对象,创建方法类似于java中创建对象。
新建一个model对象student,给对象属性指定值。
新建一个view对象,并且指定该view绑定的model对象。
调用view的渲染方法。

 1     var student = new Student({
 2             id: 10000,
 3             name: '王小二',
 4             age: 30
 5      });
 6         
 7         
 8     var studnetView = new StudnetView({
 9             model: student
10     });
11 
12     studnetView.render();

至此Backbone的代码就全部写完了,只要把这些新建Model和View的代码放到自定义的js文件中,
在页面加载时调用即可,这里自定义js文件名为main.js,内容如下:

 1 (function($){
 2     $(document).ready(function(){
 3         
 4         var student = new Student({
 5             id: 10000,
 6             name: '王小二',
 7             age: 30
 8         });
 9         
10         
11         var studnetView = new StudnetView({
12             model: student
13         });
14 
15         studnetView.render();
16         
17     });
18     
19     //set model
20     var Student = Backbone.Model.extend({
21         //set default values.
22         defaults: {
23             id: 0,
24             name: '',
25             age: 0
26         }
27     });
28     
29     //set view
30     var StudnetView = Backbone.View.extend({
31         
32         el: 'body',
33         
34         render:function(){
35             var html = '学号: ' + this.model.id + '.'
36                        '姓名: ' + this.model.name + '.'
37                        '年龄: ' + this.model.age;
38     
39             $(this.el).html(html);
40         }
41     });
42     
43 })(jQuery);

然后再新建一个index.html,内容如下:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8">
 5         <title>Backbone.js 1</title>
 6         <script src="lib/jquery-2.2.2.js"></script>
 7         <script src="lib/underscore-2.js"></script>
 8         <script src="lib/backbone.js"></script>
 9         <script src="js/main.js"></script>
10     </head>
11     <body>
12         
13     </body>
14 </html>

最后,在浏览器中打开这个文件,就可以看到效果了。

posted @ 2016-04-02 10:06 笑看人生 阅读(2532) | 评论 (0)编辑 收藏

@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); @import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);

参照以下网址,在CentOS上安装Nginx
http://www.blogjava.net/jacky9881/archive/2016/02/19/429375.html

1.首先新建以下两个目录,用于存放缓存文件;
   [root@localhost nginx]# mkdir -p /data/nginx/proxy_temp_path
   [root@localhost nginx]# mkdir -p /data/nginx/proxy_cache_path

2.编辑nginx.conf文件
  在http模块增加如下内容,指定缓存文件的存放路径:
  proxy_temp_path /data/nginx/proxy_temp_path;
  proxy_cache_path /data/nginx/proxy_cache_path levels=1:2 keys_zone=cache_one:20m inactive=1d max_size=3g ;  

注:通过keys_zone来指定缓存区的名字,在接下来的location模块配置中需要用到;
      20m是指定用于缓存的内存大小(由于本人虚拟机内存原因,设置了20M,生产环境中可以设置大一些,比如1G);
      inactive=1d,代表缓存的数据如果超过一天没有被访问的话,则自动清除;
      max_size=3g是指定用于缓存的硬盘大小(由于本人虚拟机内存原因,设置了3g,生产环境中可以设置大一些,比如50G);
      levels=1:2 指定该缓存目录中有两层hash目录,第一层目录为1个字母,第二层为2个字母,其中第一层目录名为缓存数据MD5编码的倒数第一个
     字母,第二层目录名为缓存数据MD5编码的倒数2,3两个字母;

 upstream local_tomcats {
       server 192.168.8.132:8080;
       server 192.168.8.130:8080;
}

 修改location模块
  location ~ \.(jsp|do)$ {
            proxy_pass http://local_tomcats;
 }        
        
  location / {

            proxy_cache cache_one;
            #定义http返回值为200和304,缓存时间12小时,如果12小时后,没有被访问,则自动被删除;
            #200表示 服务器已成功处理了请求,304表示 自从上次请求后,请求的网页未修改过
            proxy_cache_valid 200 304 12h ;
            proxy_cache_valid 301 302 1m ;
            proxy_cache_valid any 10m ;
            proxy_cache_key $host$uri$is_args$args;

            proxy_ignore_headers X-Accel-Expires Expires  Set-Cookie Cache-Control;
            proxy_hide_header Cache-Control;
            proxy_hide_header Set-Cookie;               
            proxy_pass http://local_tomcats; #这个要设定,否则好像生成不了缓存文件

    }
#用于清除缓存
 location ~ /purge(/.*) {
            allow 127.0.0.1;
            allow 192.168.8.132;
            deny all ;
            proxy_cache_purge cache_one $host$1$is_args$args ;
   }  

在浏览器地址栏输入:http://www.hw.com/tomcat.png
查看缓存目录
[root@localhost nginx]# ls /data/nginx/proxy_cache_path/7/8a
b12ee1366ed4307aa6408a16286658a7

可以看到,缓存文件已经生成,注意缓存文件名最后三位和缓存文件夹的关系。

在浏览器地址栏输入:http://www.hw.com/purge/tomcat.png
页面显示如下信息,提示缓存文件已经被清除。

Successful purge

Key : www.hw.com/tomcat.png
Path: /data/nginx/proxy_cache_path/7/8a/b12ee1366ed4307aa6408a16286658a7 

注意这里的Key,就是配置文件中定义 proxy_cache_key 

查看缓存命中率
location / 模块,增加如下代码
add_header  Nginx-Cache "$upstream_cache_status"

同时在http模块打开ngnix的日志功能,默认是关闭状态。

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"'
                       '"$upstream_cache_status"';
    access_log  logs/access.log  main;
 

[root@localhost nginx]# ./sbin/nginx -s reload

在浏览器地址栏输入:http://www.hw.com/tomcat.png
重复刷新几次,打开日志文件 logs/access.log,可以看到HIT的字样,意味着缓存命中。

192.168.8.132 - - [08/Mar/2016:20:48:38 +0800] "GET /tomcat.png HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0" "-""HIT"
192.168.8.132 - - [08/Mar/2016:20:48:40 +0800] "GET /tomcat.png HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0" "-""HIT"
192.168.8.132 - - [08/Mar/2016:20:48:42 +0800] "GET /tomcat.png HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0" "-""HIT"


posted @ 2016-03-08 20:29 笑看人生 阅读(2894) | 评论 (1)编辑 收藏

     摘要: 不讲原理,直接上步骤: 1.下载MyCat,Mycat-server-1.4-release-20151019230038-linux.tar 2. 解压到/usr/mycat目录下:     [root@localhost mycat]# tar -xvf  Mycat-server-1.4-release-20151019230038-linux.t...  阅读全文

posted @ 2016-02-27 15:28 笑看人生 阅读(3942) | 评论 (1)编辑 收藏

@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); @import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); @import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); @import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); @import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); @import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
 主服务器  OS:CentOS   IP:192.168.8.130
 从服务器  OS:CentOS   IP:192.168.8.131

在主,从服务器上安装MySQL,安装方法如下:
[root@localhost Desktop]$ rpm -qa | grep mysql
   mysql-libs-5.1.73-5.el6_6.x86_64
[root@localhost Desktop]# rpm -e mysql-libs-5.1.73-5.el6_6.x86_64 --nodeps
[root@localhost Desktop]# yum -y install mysql-server mysql mysql-devel

启动MySQL
[root@localhost Desktop]# service mysqld start

#可以设置MySQL开机启动,运行命令chkconfig mysqld on

#给root账号设置密码
[root@localhost Desktop]# mysqladmin -u root password 'root'
[root@localhost Desktopps]# mysql -u root -p
给从服务器(192.168.8.131)授权,并且给从服务器创建访问主服务器的账号和密码 admin
mysql> grant replication slave on *.* to 'admin'@'192.168.8.131' identified by 'admin';
创建数据库contract
mysql> create database contract;
mysql>quit;

复制MySQL数据库配置模版覆盖/etc/my.cnf
[root@localhost Desktopps]# cp /usr/share/mysql/my-medium.cnf /etc/my.cnf   
[root@localhost Desktopps]#vi /etc/my.cnf
设置以下三个值

log-bin=mysql-bin   #指定从服务器读取的日志文件
server-id = 1        #主服务器必须设定为1,从服务器的值>1
binlog-do-db=contract #对contract数据库的操作日志会记录到mysql-bin

#原理:MySQL主从复制的原理是主服务器把对指定数据库操作的日志写到指定的日志文件中,从服务器
            读取这个日志文件,写到从服务器的指定日志文件中,然后在从服务器重新执行日志文件。

配置完之后,重启MySQL
[root@localhost Desktopps]#service mysqld restart
Stopping mysqld:                                          [  OK  ]
Starting mysqld:                                           [  OK  ]

[root@localhost Desktopps]# mysql -u root -p
查看主服务器的状态
mysql> show master status\G;
*************************** 1. row ***************************
                    File: mysql-bin.000005
              Position: 106
     Binlog_Do_DB: contract
Binlog_Ignore_DB: 
1 row in set (0.00 sec)

这里记好File和Position的值,配置从服务器的时候需要用到。File就是从服务器需要读取的日志文件,Position表示从日志文件的什么位置开始读起。

 下面开始配置从服务器
[root@localhost Desktop]# mysqladmin -u root password 'root'
[root@localhost Desktopps]# mysql -u root -p
创建数据库contract
mysql> create database contract;
mysql>quit;
[root@localhost Desktopps]# cp /usr/share/mysql/my-medium.cnf /etc/my.cnf   
[root@localhost Desktopps]#vi /etc/my.cnf
设置以下两个值

log-bin=mysql-bin   #指定主服务器读取的日志文件
server-id = 2       #主服务器必须设定为1,从服务器的值>1

[root@localhost Desktopps]# mysql -u root -p
mysql> CHANGE MASTER TO MASTER_HOST='192.168.8.130', MASTER_PORT=3306,
            MASTER_USER='admin', MASTER_PASSWORD='admin',
            MASTER_LOG_FILE='mysql-bin.000005'MASTER_LOG_POS=106; 
启动从服务器同步
mysql>start slave;
mysql>show slave status\G;

Slave_IO_Running: YES
Slave_SQL_Running: YES

如果输出以上内容,则表示MySQL主从复制配置成功。

验证
在主服务器上运行 
[root@localhost Desktopps]# mysql -u root -p
mysql> use contract;
Database changed
mysql> show tables;
Empty set (0.04 sec)

在从服务器上运行
[root@localhost Desktopps]# mysql -u root -p
mysql> use contract;
Database changed
mysql> show tables;
Empty set (0.04 sec)

确定主从服务器的数据库contract的下面都没有表。
在主服务器上运行建表命令,并往表里插入一条记录:
 mysql> create table `user` (`id` int not null auto_increment,`name` varchar (60),`password` varchar (20),`role` int not null,`email` varchar (30),`alertday` int,primary key (`id`));
Query OK, 0 rows affected (0.36 sec)
 mysql> insert into `user` (`name`,`password`,`role`,`email`,`alertday`) values('admin','admin',0,'xxxx@xxx.com',30);
Query OK, 1 row affected (0.08 sec)

在从服务器上运行查询语句。
mysql> select * from user;
+----+-------+----------+------+--------------+----------+
| id | name  | password | role | email        | alertday |
+----+-------+----------+------+--------------+----------+
|  1 | admin | admin    | 0    | xxxx@xxx.com |       30 |
+----+-------+----------+------+--------------+----------+
1 row in set (0.01 sec)

从输出结果可以看出,主服务器上的数据被同步到从服务器上了。

通过搭建MySQL主从复制结构,可以提高数据的安全性,同时可以实现读写分离,让写操作在主服务器上进行,
读操作在从服务器上进行,可以分担主服务器的负担。但是如果当主服务器宕机之后,数据库就只能提供
读操作了,不能做到故障转移,这时候,主主复制就应运而生了,有时间整理一下主主复制的配置。




@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);

posted @ 2016-02-23 20:41 笑看人生 阅读(342) | 评论 (0)编辑 收藏

@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
在CentOS上安装JDK7,Tomcat7和Nginx1.9手顺

1.下载 jdk-7u79-linux-x64.rpm,下载地址如下:
  http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk7-downloads-1880260.html

  [root@localhost java]#rpm -qa | grep jdk
  [root@localhost java]#cp /home/huangwei/Downloads/jdk-7u79-linux-x64.rpm .
  [root@localhost java]# chmod 755 jdk-7u79-linux-x64.rpm 
  [root@localhost java]# rpm -ivh jdk-7u79-linux-x64.rpm 
  [root@localhost java]# vi /etc/profile

       #set java enviromet
       JAVA_HOME=/usr/java/jdk1.7.0_79
       PATH=$PATH:$JAVA_HOME/bin
       CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
       export JAVA_HOME PATH CLASSPATH
  [root@localhost java]# source /etc/profile
  [root@localhost java]# java -version
       java version "1.7.0_79"
       Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
       Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)
  [root@localhost lib]# rpm -qa | grep jdk
       jdk-1.7.0_79-fcs.x86_64



2.下载 apache-tomcat-7.0.68.zip,下载地址如下:
  http://tomcat.apache.org/download-70.cgi
  unzip apache-tomcat-7.0.68.zip to /usr/
  [root@localhost bin]# cd /usr/apache-tomcat-7.0.68/bin
  [root@localhost bin]# chmod +x *.sh
  [root@localhost bin]# ./startup.sh 
Using CATALINA_BASE:   /usr/apache-tomcat-7.0.68
Using CATALINA_HOME:   /usr/apache-tomcat-7.0.68
Using CATALINA_TMPDIR: /usr/apache-tomcat-7.0.68/temp
Using JRE_HOME:        /usr/java/jdk1.7.0_79
Using CLASSPATH:       /usr/apache-tomcat-7.0.68/bin/bootstrap.jar:/usr/apache-tomcat-7.0.68/bin/tomcat-juli.jar
Tomcat started.

  在浏览器中输入http://localhost:8080/ ,如果能正常打开Tomcat的主页,说明Tomcat安装成功。

3.下载 nginx-1.9.11.tar.gz,下载地址如下:
  http://nginx.org/en/download.html
  [root@localhost usr]# rpm -qa | grep gcc
gcc-4.4.7-16.el6.x86_64
libgcc-4.4.7-16.el6.x86_64
  [root@localhost usr]# rpm -qa | grep openssl
openssl-1.0.1e-42.el6.x86_64
  [root@localhost usr]# rpm -qa | grep zlib
zlib-1.2.3-29.el6.x86_64
  [root@localhost usr]# rpm -qa | grep pcre
pcre-7.8-7.el6.x86_64
  [root@localhost usr]# tar -zxvf nginx-1.9.11.tar.gz 
  [root@localhost usr]# cd nginx-1.9.11/
  [root@localhost nginx-1.9.11]# yum -y install pcre-devel
  [root@localhost nginx-1.9.11]# yum -y install zlib-devel
  [root@localhost nginx-1.9.11]# ./configure --prefix=/usr/nginx
  [root@localhost nginx-1.9.11]# make && make install
  [root@localhost nginx-1.9.11]# cd /usr/nginx/sbin/
  [root@localhost sbin]# ./nginx -t
nginx: the configuration file /usr/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/nginx/conf/nginx.conf test is successful
  [root@localhost sbin]# ./nginx

  
在浏览器中输入http://localhost/ ,如果能正常打开Nginx的主页,说明Nginx安装成功。
@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);

posted @ 2016-02-19 19:43 笑看人生 阅读(276) | 评论 (0)编辑 收藏

     摘要: @import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); Normal 0 10 pt 0 2 false ...  阅读全文

posted @ 2016-01-31 13:10 笑看人生 阅读(4571) | 评论 (0)编辑 收藏

     摘要: @import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); 参照一下地址,搭建nginx tomcat的负载均衡环境 Nor...  阅读全文

posted @ 2016-01-28 20:13 笑看人生 阅读(3263) | 评论 (0)编辑 收藏

     摘要: 搭建nginx和 tomcat环境,实现负载均衡  阅读全文

posted @ 2016-01-28 19:45 笑看人生 阅读(3253) | 评论 (0)编辑 收藏

扩展点:
org.eclipse.ui.ide.resourceFilters
org.eclipse.jdt.ui.javaElementFilters

org.eclipse.ui.ide.resourceFilters扩展点可以给Naivgator视图的过滤器列表增加过滤项,要使用该扩展点需要在插件依赖项中追加
对插件项目org.eclipse.ui.ide的依赖。

扩展清单如下:

<extension
           
point="org.eclipse.ui.ide.resourceFilters">
        
<filter
              
pattern="*.classpath"
              selected
="true">
        
</filter>
</extension>
上述代码的作用就是给Navigator视图,增加过滤器,过滤后缀名为classpath的文件,该过滤项默认为选中状态。

org.eclipse.jdt.ui.javaElementFilters扩展点可以给Java透视图中相应视图的过滤器列表增加过滤项,要使用该扩展点需要在插件依赖项中追加
对插件项目org.eclipse.jdt.ui的依赖。

扩展清单如下:

<extension
           
point="org.eclipse.jdt.ui.javaElementFilters">
        
<filter
              
description="TestFilter Des"
              enabled
="true"
              id
="aaaa"
              name
="TestFilter"
              pattern
="*.properties"
              targetId
="org.eclipse.jdt.ui.PackageExplorer">
        
</filter>
 
</extension>

上述代码的作用就是给Package视图,增加过滤器,过滤点后缀名为properties的文件,该过滤项默认为选中状态。

posted @ 2010-07-09 20:59 笑看人生 阅读(2273) | 评论 (0)编辑 收藏

扩展点:
org.eclipse.ui.bindings
org.eclipse.ui.contexts

扩展点org.eclipse.ui.bindings是给command增加快捷键,结合(介绍二),给命令com.xxxx.test.command1增加快捷键,
示例代码如下:

<extension
         
point="org.eclipse.ui.bindings">
      
<key
            
commandId="com.xxxx.test.command1"
            contextId
="org.eclipse.ui.contexts.window"
            schemeId
="org.eclipse.ui.defaultAcceleratorConfiguration"
            sequence
="M2+F7">
      
</key>  
</extension>

这样快捷键Shift+F7在Eclipse工作台上都会起作用,但是如果想让命令的快捷键只对特定的视图或者编辑器起作用,那么可以通过org.eclipse.ui.contexts扩展点来自定义上下文。

<extension
           
point="org.eclipse.ui.contexts">
        
<context
              
id="viewmenu.testcontext"
              name
="ViewContext"
              parentId
="org.eclipse.ui.contexts.window">
        
</context>
</extension>

扩展之后,需要修改org.eclipse.ui.bindings扩展中的contextId属性为viewmenu.testcontext。

另外还需要在需要增加该快捷键的编辑器或者视图对应类中增加如下代码(视图类在代码的createControl方法,编辑器类在代码的init方法):

IContextService contextService = 
(IContextService) getSite().getService(IContextService.
class);
contextService.activateContext(
"viewmenu.testcontext");

posted @ 2010-07-09 20:52 笑看人生 阅读(2705) | 评论 (0)编辑 收藏

原文地址:http://www.fengfly.com/plus/view-179398-1.html

菜单是各种软件及开发平台会提供的必备功能,Eclipse 也不例外,提供了丰富的菜单,包括主菜单(Main Menu),视图 / 编辑器菜单(ViewPart/Editor Menu)和上下文菜单(Context Menu)。在 Eclipse 中,几乎所有的 Workbench Part 提供了人性化的菜单,大大方便了用户的操作。因此,如何扩展 Eclipse 的菜单功能,并实现特定于我们自己插件的菜单,是插件开发者必须掌握的重要技能,同时,Eclipse 提供了丰富的扩展点供开发人员使用。本文将首先介绍 Eclipse 中的菜单,然后详细说明如何进行扩展,最后以一个实例的形式引导读者深入理解 Eclipse 的菜单功能。

  引言

  Eclipse 具有丰富的菜单功能,给开发人员提供了很好的用户体验。总体而言,Eclipse 菜单种类包括视图 / 编辑器菜单,主菜单(Main Menu),视图 / 编辑器菜单(ViewPart/EditorPart Menu)和上下文菜单(Context Menu)。插件开发人员通过灵活应用这些菜单,可以给用户提供很好的体验。由于视图和编辑器菜单功能类似,因此本文重点讲述视图菜单(视图下拉菜单及其工具栏菜单),除此之外,还将讲述主菜单和上下文菜单。

  如图 1 所示为 Project Explorer 视图的菜单,包括视图下拉菜单和工具栏菜单(折叠树节点)。通常而言,出现在视图工具栏的菜单都会出现在视图的下拉菜单,也就是说,比较常用的视图菜单放在视图的工具栏。

图 1. Project Explorer 视图的菜单

 

 

  如图 2 所示为 Project Explorer 视图中的上下文菜单,只有当我们右键点击时才会出现。通常而言,出现频率较高的菜单项才会出现在菜单中。上下文菜单具有很强的灵活项,它可以随着我们点击的对象不同,弹出的菜单也会有相应的变化。

图 2. Project Explorer 视图中的上下文菜单


  如图 3 所示为 Eclipse 的主菜单,包括最上面的主菜单项(不可移动)及其下面的工具栏菜单(可以移动,并且 Eclipse 提供了显示 / 不显示这些菜单的功能),Eclipse 并不建议我们为每一个插件都添加新的主菜单,这样容易造成冗余,而且不方便用户操作。通常,我们可以把菜单项添加到 Eclipse 已有的菜单,如插件的查找功能可以添加一个查找菜单项到 Eclipse 的 Search 主菜单上。

图 3. Eclipse 的主菜单


  前面讲到 Eclipse 的各种菜单,那么,如何在开发插件或 RCP 应用程序的时候添加这些菜单?本文下面的篇幅将详细介绍如何扩展 Eclipse 的菜单功能,使读者深入了解 Eclipse 的菜单功能,并能够开发具有这些菜单的应用程序。因此,必须掌握三方面的内容:菜单种类,菜单的扩展点,菜单控制(显示 / 隐藏或启用 / 禁用菜单项)。下面从概念上介绍这三方面内容,下一小节将会进行详细介绍。

  菜单种类

  正如前面所讲到的,Eclipse 的菜单包括视图菜单,主菜单及上下文菜单三个种类。

  菜单项的扩展点

  Eclipse 提供了两种扩展点供用户添加菜单项到相应的位置。这两种扩展点为 org.eclipse.ui.commands(本文简称为 Commands 方式)和 org.eclipse.ui.actionSets(本文简称为 Actions 方式)。Actions 方式为界面上不同区域的表现方式提供了相应的扩展点,并且没有分离其界面表现和内在实现。恰恰相反,Commands 方式通过三步有效的达到界面表现和内部实现的分离:首先,通过 org.eclipse.ui.commands 扩展点创建命令和类别(Category),并且可以把某些命令放在一个类别(Category)中;然后,通过 org.eclipse.ui.menus 指定命令出现在界面的哪个区域(视图菜单 / 主菜单 / 上下文菜单);最后通过 org.eclipse.ui.handlers 指定命令的实现。因此,Eclipse 推荐新开发的插件使用 Commands 来创建您的界面菜单。当然,由于 Actions 在现有的插件中用得比较多,如果我们需要扩展或基于之前的插件开发,也需要对其进行了解。除此之外,针对上下文菜单,虽然 Commands 和 Actions 方式均可以创建上下文菜单,但是 Eclipse 还提供了另外一种创建上下文菜单的扩展点 org.eclipse.ui.popupMenus(本文简称为 popupMenus 方式),本文将就这三种扩展点做详细的介绍。

  菜单控制

  菜单控制是一个非常常见的功能,例如,随着选定的内容或当前窗口的不同,菜单中的菜单项会有相应的变化(显示 / 隐藏或启用 / 禁用菜单项),因此,如何控制菜单是插件开发人员必须掌握的知识。Eclipse 为菜单控制提供了两种方法,一种是通过扩展点;另一种是通过 API 的方式编写程序控制。

  Eclipse 菜单功能及其扩展点

  至此,我们对 Eclipse 菜单有了感观的认识。由上一节我们可知,要深入理解 Eclipse 菜单功能,我们需要从三个方面去掌握:菜单种类,菜单的扩展点和菜单控制。下面将进行详细讲述。

  菜单种类

  针对各种菜单,Eclipse 提供了相应的扩展点,因此,开发人员可以通过这些扩展点把菜单放到界面的不同区域,详细内容请参考 2.2 小节。

  菜单的扩展点

  视图菜单的扩展点

  采用 Commands 方式创建视图菜单,需要引入 org.eclipse.ui.menus 扩展点;而 Actions 方式需要引入 org.eclipse.ui.actionSets.

  1、视图菜单(Commands 方式):

  MenuContribution locationURI = “[Scheme]:[id]?[argument-list]”

  其中,Scheme 为该菜单项出现的区域,menu 为视图的下拉菜单,toolbar 为视图的工具栏菜单;id 为菜单区域 ID;argument-list 为该菜单项出现在指定菜单的位置。

  例如:在 ProbelmView 的下拉菜单加一个菜单项,其 MenuContribution 的 locationURI 应为:menu:org.eclipse.ui.views.ProblemView?after=additions;在 ProblemView 的工具栏菜单中加入一个菜单项,其 locationURI 应为:toolbar:org.eclipse.ui.views.ProblemView?after=additions。

  2、视图菜单(Actions 方式):

  采用 Actions 方式创建菜单,需要引入 org.eclipse.ui.actionSets 扩展点,并通过设定 action 的 menubarPath 指定下拉菜单 / 菜单项出现的位置;通过设定 action 的 toolbarPath 设定工具栏菜单 / 菜单项出现的位置。

  例如,添加一个下拉菜单项到 Problems 视图中,其 menubarPath 应为:

  org.eclipse.ui.views.ProblemView/additions

  主菜单的扩展点

  1、主菜单(Commands 方式)

  通过 Commands 方式把菜单项添加到主菜单及其工具栏上,和视图菜单一样,也是通过扩展点 org.eclipse.ui.menus 实现,需要设定其 menuContribution 的 locationURI。

  例如,添加一个菜单(菜单可以包含若干个菜单项)到主菜单一栏中,其 locationURI 为:

  menu:org.eclipse.ui.main.menu?after=additions

  添加一个菜单到工具栏之中,其 locationURI 为:

  toolbar:org.eclipse.ui.main.toolbar?after=additions

  当然,我们也可以把菜单项添加到已经存在的菜单当中,例如添加一个菜单项到 Eclipse 的 Search 主菜单当中,其 locationURI 为:

  menu:org.eclipse.search.menu?dialogGroup

  2、主菜单(Actions 方式)

  通过 Actions 方式把菜单项添加到主菜单及其工具栏上,和视图菜单一样,也是通过扩展点 org.eclipse.ui.actionSets 实现,需要设定 action 的 menubarPath 和 toolbarPath 实现。

  例如,添加一个菜单项到 Eclipse 的 Search 主菜单中,其 menubarPath 应为:

  org.eclipse.search.menu/dialogGroup

  注意:如果采用上述方式添加一个菜单项到 Search 主菜单,当我们运行时并没有出现添加的菜单项,这时候需要换一个 workspace,其原因是 Eclipse 缓存了与其相关的某些信息在 workspace 当中。

  上下文菜单的扩展点

  上下文菜单除了通过 Commands 和 Actions 方式添加,还可以使用扩展点 org.eclipse.ui.popupMenus 方式添加,下面分别进行介绍。

  1、上下文菜单(Commands 方式)

  Commands 方式与添加视图菜单和主菜单的方式一样,通过设定其 menuContribution 的 locationURI 来实现。

  例如,添加一个上下文菜单到 Problems 视图中,其 locationURI 为:

  popup:org.eclipse.ui.views.ProblemView?after=additions。

  如果我们想让某个上下文菜单项出现在任何区域,则可以使用下面的 locationURI:

  popup:org.eclipse.ui.popup.any?after=additions

  2、上下文菜单(Actions 方式)

  Actions 方式没有直接提供扩展点添加上下文菜单,但是我们可以通过编程的方式实现,如下代码清单 1 为 TreeViewer 添加上下文菜单,通过 IMenuManager 的 add 方法添加 actions。

清单 1. 通过 Actions 方式编程实现添加上下文菜单

 private void hookContextMenu() { 
  IMenuManager fMenuMgr = new MenuManager(“#PopupMenu”); 
  fMenuMgr.setRemoveAllWhenShown(true); 
  // 添加 Actions 
  fMenuMgr.add(action … ) 
  fMenuMgr.createContextMenu(treeViewer.getControl()); 
  treeViewer.getControl().setMenu(fMenu); 
  getSite().registerContextMenu(fMenuMgr, treeViewer); 
 } 

  3、上下文菜单(popupMenus 方式)

  通过 popupMenus 扩展点实现上下文菜单,需要设定 objectContribution 的 objectClass 属性把上下文菜单添加到相应的区域。

  例如,如果我们想当用户点击 Eclipse 中的资源时,弹出的上下文菜单包括某个菜单项,我们可以设定 objectClass 属性为:

  org.eclipse.core.resources.IResource

  通过 Commands 方式创建菜单项

  通过 Commands 方式创建菜单项,首先需要创建 Command,通过扩展点 org.eclipse.ui.commands,然后我们可以把这个 Command 放到任何区域,上一小节已经讲到,通过 org.eclipse.ui.menus 扩展点确定菜单创建的区域,最后通过扩展点 org.eclipse.ui.handlers 定义这个 command 的具体行为。

  在创建 Command 时,我们可以先创建一个 Category,并把相关的一些命令放到这个 Category 中,这样有利于管理。代码清单 2 创建一个 Command(“Show in Glossary Explorer”),并放到一个 Category 中,然后把该 Command 放到 BGSearchResultView 视图的上下文菜单中,最后通过扩展 org.eclipse.ui.handlers 定义该 Command 的实现类。

清单 2. 通过 Commands 方式添加菜单项

 <!-- 添加 command --> 
 <extension 
   point="org.eclipse.ui.commands"> 
  <category 
   description="Business Glossary" 
   id="com.ibm.bg.ui.commands.category" 
   name="%category.BusinessGlossary.name"> 
  </category> 
  <command 
   categoryId="com.ibm.bg.ui.commands.category" 
   description="Show in Glossary Explorer" 
   id="com.ibm.bg.ui.commands.BGShowInBrowser" 
   name="%command.ShowInGE.name"> 
  </command> 
 </extension> 
 <!-- 把 Command 放到界面的对应区域 --> 
 <extension 
    point="org.eclipse.ui.menus"> 
  <menuContribution locationURI= 
  "popup:com.ibm.bg.internal.ui.search.BGSearchResultView?after=additions"> 
   <command 
      commandId="com.ibm.bg.ui.commands.BGShowInBrowser" 
      style="push" 
      tooltip="%command.ShowInGE.tooltip"> 
   </command> 
  </menuContribution> 
 </extension> 
 <!-- 定义 command 的实现类 --> 
 <extension 
   point="org.eclipse.ui.handlers"> 
  <handler 
     class="com.ibm.bg.internal.ui.handlers.BGShowInBrowser" 
     commandId="com.ibm.bg.ui.commands.BGShowInBrowser"> 
  </handler> 
 </extension> 

  通过 Actions 方式创建菜单项

  正如前面讲到,Actions 方式没有分离界面的表现和内部实现,因此,所有这些均通过 action 来完成。如下代码清单 3 为添加一个 Search 菜单项到 Eclipse 的 Search 主菜单(通过 action 的 menubarPath 指定)中,其中 class 对应的值为该 Action 的实现类,该类需要实现接口 IWorkbenchWindowActionDelegate。

清单 3. 通过 Actions 方式添加菜单项

 <extension 
   point="org.eclipse.ui.actionSets"> 
  <actionSet 
     id="com.ibm.bg.ui.workbenchActionSet" 
     label="%category.name.0" 
     visible="true"> 
   <action 
      class="com.ibm.bg.internal.ui.handlers.BGSearchHandler" 
      definitionId="com.ibm.bg.ui.commands.BGSearch" 
      icon="icons/search.png" 
      id="com.ibm.bg.ui.commands.BGSearch" 
      label="%action.searchGlossayInMainMenu.label" 
      menubarPath="org.eclipse.search.menu/dialogGroup" 
      style="push"> 
   </action> 
  </actionSet> 
 </extension> 

  通过 popupMenus 方式创建菜单项

  popupMenus 方式创建上下文菜单项也是通过 action 来实现,下面例子为添加一个菜单项到用户右击 IGraphicalEditPart 对象时弹出的上下文菜单,通过 menubarPath 指定该 Action 出现的区域,通过 class 指定该 action 的实现类,该类需要实现接口 IObjectActionDelegate。

清单 4. 通过 popupMenus 方式添加菜单项

 <extension 
   point="org.eclipse.ui.popupMenus"> 
  <objectContribution 
     adaptable="false" 
     id="com.ibm.bg.uml.objectContributions.BGAssignToGlossary" 
     objectClass="org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart"> 
   <action 
      class="com.ibm.bg.internal.uml.actions.BGAssignToGlossary" 
      enablesFor="+" 
      icon="icons/assign.png" 
      id="com.ibm.bg.internal.uml.actions.BGAssignToGlossary" 
      label="%BGAssignToGlossary.item" 
      menubarPath="com.ibm.bg.uml.popupMenuGroup"> 
   </action> 
  </objectContribution> 
 </extension> 

  菜单控制

  视图菜单的控制主要包括启用 / 禁用,显示 / 隐藏菜单。

  通过 Command 方式创建的菜单,可以通过 org.eclipse.ui.commands 的 visibleWhen 属性控制菜单的隐藏和显示,通过 org.eclipse.ui.handlers 的 activewhen 或 enabledWhen 控制菜单的启用或禁用。

  通过 Actions 方式创建的菜单,可以通过 action 的 enablement 属性控制菜单的启用 / 禁用。

  通过 popupMenus 方式创建的菜单,可以通过 objectContribution 的 visibility 和 enablement 来设置该 objectContribution 下的 action 的显示 / 隐藏和启用 / 禁用,我们也可以设置 action 的 enablement 来控制该菜单的启用 / 禁用。

  这里不详细讲述 enablement,visibleWhen 和 enabledWhen 的参数及如何设置,读者可以参考第三节的例子和本文的参考文献。

  编程实践

  本文将结合前两节讲到的知识,以例子的形式说明如何创建并且控制菜单。首先创建一个视图(Menu Example),然后分别通过 Commands,Actions 和 popupMenus 方式创建若干个菜单,并添加相应的菜单控制点。

  创建 Menu Example 视图

  扩展 org.eclipse.views 创建“Menu Example”视图,如下代码清单 5 为创建视图的 xml 代码。

清单 5. 扩展 org.eclipse.ui.views 创建视图

 <extension 
   point="org.eclipse.ui.views"> 
  <category 
     id="com.free.menu.category" 
     name="Menu Example View"> 
  </category> 
  <view 
     category="com.free.menu.category" 
     class="com.free.menu.view.MenuExplorer" 
     id="com.free.menu.view.MenuExplorer" 
     name="Menu Explorer" 
     restorable="true"> 
  </view> 
 </extension> 

  创建 Commands

  采用 Command 方式创建“Menu Example”主菜单(包含 AngryCommand 和 JokeCommand 两个菜单项),并且基于这两个菜单项创建了 Menu Example 视图的下拉菜单和工具栏菜单,及其 TreeViewer 的上下文菜单。

  如下代码清单 6 为扩展 org.eclipse.ui.commands 创建 Menu Example 命令和类别,并且包含两个命令:Joke Command 和 Angry Command。

清单 6. 扩展 org.eclipse.ui.commands 创建命令

 <extension 
   point="org.eclipse.ui.commands"> 
  <category 
     id="com.free.menu.category" 
     name="Menu Example"> 
  </category> 
  <command 
     categoryId="com.free.menu.category" 
     id="com.free.menu.commands.jokeCommand" 
     name="Joke Command"> 
  </command> 
  <command 
     categoryId="com.free.menu.category" 
     id="com.free.menu.commands.angryCommand" 
     name="Angry Command"> 
  </command> 
 </extension> 

  关联 Commands 到主菜单

  如下代码清单 7 为扩展 org.eclipse.ui.menus,并基于前面创建的 Comands,添加一个主菜单 Menu Example,并且包含 Joke Command 和 Angry Command 菜单项。

清单 7. 创建 Menu Example 主菜单

 <menuContribution 
   locationURI="menu:org.eclipse.ui.main.menu?after=additions"> 
  <menu 
   id="com.free.menu.MenuExample" 
     label="Menu Example"> 
   <command 
      commandId="com.free.menu.commands.jokeCommand" 
      style="push"> 
   </command> 
   <command 
      commandId="com.free.menu.commands.angryCommand" 
      style="push"> 
   </command> 
  </menu> 
 </menuContribution> 

  Commands 的实现类

  如下代码清单 9 所示扩展 org.eclipse.ui.handlers 为 Joke Command 和 Angry Command 创建事件处理类,其中 Joke Command 通过 enabledWhen 属性控制该菜单项是否启用,当我们同时选择了两个对象时 Joke Command 处于启用状态,否则为禁用。

清单 9. 扩展 org.eclipse.ui.handlers 为 Commands 创建实现类

 <extension 
   point="org.eclipse.ui.handlers"> 
  <handler 
     class="com.free.menu.actions.JokeCommand" 
     commandId="com.free.menu.commands.jokeCommand"> 
   <enabledWhen> 
     <count 
        value="2"> 
     </count> 
   </enabledWhen> 
  </handler> 
  <handler 
     class="com.free.menu.actions.AngryCommand" 
     commandId="com.free.menu.commands.angryCommand"> 
  </handler> 
 </extension> 

  创建 Action 并关联到 Eclipse 的 Search 主菜单

  采用 Actions 方式在 Eclipse 的主菜单 Search 中添加创建菜单项 SmileAction。扩展 org.eclipse.ui.actionSets 在 Eclipse 的主菜单 Search 中添加一个菜单项 Smile Action。如下代码清单 10 所示创建该 action 并添加到 search 主菜单,只有当我们选择至少一个对象时(设置 enablesFor 属性为“+”),该菜单项才处于启用状态。

清单 10. 通过 Actions 方式创建菜单项

 <extension 
   point="org.eclipse.ui.actionSets"> 
  <actionSet 
     id="com.free.menu.actionSet.MenuExample" 
     label="Menu Example" 
     visible="true"> 
   <action 
      class="com.free.menu.actions.SmileAction" 
      enablesFor="+" 
      icon="icons/searchres.gif" 
      id="com.free.menu.actions.smileAction" 
      label="Smile Action" 
      menubarPath="org.eclipse.search.menu/dialogGroup" 
      style="push"> 
   </action> 
  </actionSet> 
 </extension> 

  pupupMenus 方式创建 Action 并关联到 IResource 资源的上下文菜单

  扩展 org.eclipse.ui.popupMenus 创建菜单“Menu Example”,该菜单包含一个菜单项 HelloAction。当我们在 Eclipse 任何区域右击 org.eclipse.core.resources.IResource 资源时弹出的上下文菜单中会出现“Menu Example”菜单。如下代码清单 11 为创建该上下文菜单的 xml 代码。

清单 11. popupMenus 方式创建上下文菜单

 <extension 
   point="org.eclipse.ui.popupMenus"> 
  <objectContribution 
     adaptable="true" 
     id="com.free.menu.popupMenu" 
     objectClass="org.eclipse.core.resources.IResource"> 
   <menu 
      label="Menu Example" 
      path="additions" 
      id="com.free.menu.popupSubMenu"> 
     <separator 
        name="additions"> 
     </separator> 
   </menu> 
   <action 
      label="Hello Action" 
      class="com.free.menu.popup.actions.HelloAction" 
      menubarPath="com.free.menu.popupSubMenu/additions" 
      enablesFor="1" 
      id="com.free.menu.newAction"> 
   </action> 
  </objectContribution> 
 </extension> 

  pupupMenus 方式创建 Action 并关联到 IResource 资源的上下文菜单

  扩展 org.eclipse.ui.popupMenus 创建菜单项 GreetAction 和 CryAction,当我们右击 Menu Example 视图中的 TreeViewer 节点时弹出。如下代码清单 12 所示扩展 org.eclipse.ui.popupMenus 为 Menu Example 视图创建 GreetAction 和 CryAction 上下文菜单项。使用 visiblity 的 objectState 属性控制菜单项的可见状态,使用该属性要求其选择的对象实现了 org.eclipse.ui.IActionFilter 接口,具体可参见 Person 类的实现。

清单 12. 扩展 org.eclipse.ui.popupMenus 创建菜单

 <extension 
   point="org.eclipse.ui.popupMenus"> 
  <objectContribution 
     adaptable="false" 
     id="com.free.menu.views.popupMenu" 
     objectClass="com.free.menu.model.Person"> 
   <action 
      class="com.free.menu.actions.GreetAction" 
      enablesFor="+" 
      id="com.free.menu.actions.greetAction" 
      label="Greet Action" 
      menubarPath="additions"> 
   </action> 
   <visibility> 
     <objectState 
        name="firstName" 
        value="Dan"> 
     </objectState> 
   </visibility> 
  </objectContribution> 
 </extension> 
 <extension 
   point="org.eclipse.ui.popupMenus"> 
  <objectContribution 
     adaptable="false" 
     id="com.free.menu.views.popupMenu2" 
     objectClass="com.free.menu.model.Person"> 
   <action 
      class="com.free.menu.actions.CryAction" 
      enablesFor="+" 
      id="com.free.menu.actions.cryAction" 
      label="Cry Action" 
      menubarPath="additions"> 
     <enablement> 
      <objectState 
         name="firstName" 
         value="David"> 
      </objectState> 
     </enablement> 
   </action> 
   <visibility> 
     <objectState 
        name="lastName" 
        value="Rubel"> 
    </objectState> 
   </visibility> 
  </objectContribution> 
 </extension> 

  Menu Example 视图的代码实现类

  如下代码清单 13 所示为 Menu Example 视图的代码,该视图中有一个 TreeViewer,并通过函数 hookContextMenu 把上下文菜单关联到 TreeViewer。其中函数 viewMenuAction 用于更新菜单的状态,它首先获取视图菜单,然后调用 IMenuManager 的 update 方法更新对应菜单项的状态,从而达到控制菜单的目的。

清单 13. Menu Example 视图代码

 public class MenuExplorer extends ViewPart { 
  private TreeViewer treeViewer; 
  private MenuManager fMenuMgr; 
  private Menu fMenu; 
  private static MenuExplorer fInstance = null; 
  public MenuExplorer() { 
    fInstance = this; 
  } 
  public static MenuExplorer getInstance(){ 
    return fInstance; 
  } 
  public void createPartControl(Composite parent) { 
    treeViewer = new TreeViewer (parent, SWT.MULTI); 
    treeViewer.setLabelProvider(new PersonListLabelProvider()); 
    treeViewer.setContentProvider(new PersonTreeContentProvider()); 
    treeViewer.setInput(Person.example()); 
    this.getSite().setSelectionProvider(treeViewer); 
    hookContextMenu(); 
    fInstance = this; 
     
  } 
  public void setViewMenuActionState(boolean state){     
    JokeCommand.setState(state); 
    viewMenuAction(); 
  } 
  private void viewMenuAction() { 
    IActionBars bars= getViewSite().getActionBars(); 
    final IMenuManager menu= bars.getMenuManager();   
     
    UIOperation.asyncExecCommand(new Runnable(){ 
      public void run() { 
        menu.update("com.free.menu.commands.jokeAction"); 
      }       
    });     
  } 
  private void hookContextMenu() { 
    fMenuMgr = new MenuManager("#PopupMenu"); 
    fMenuMgr.setRemoveAllWhenShown(true); 
    fMenuMgr.addMenuListener(new IMenuListener() { 
      public void menuAboutToShow(IMenuManager manager) {         
      } 
    }); 
    fMenu = fMenuMgr.createContextMenu(treeViewer.getControl()); 
 
    treeViewer.getControl().setMenu(fMenu); 
    getSite().registerContextMenu(fMenuMgr, treeViewer);        
  }   
  public void setFocus() { 
    treeViewer.getTree().setFocus(); 
 
  } 
 } 

  Person 类的实现

  如下代码清单 14 为 Person 类的实现,用于表示 MenuExample 视图中 TreeViewer 的一个节点,它实现了 IActionFilter 接口,通过 testAttribute 来确定是否显示 / 隐藏菜单(其中 target 表示用户选择的对象,name/value 对应于 plugin.xml 文件中 objectState 的 name/value).

清单 14. Person 类实现

 public class Person implements IActionFilter { 
 
  private String firstName = "John"; 
  private String lastName = "Doe"; 
  protected int age = 37; 
  public Person[] children = new Person[0]; 
  public Person parent = null; 
  public Person(String firstName, String lastName, int age) { 
    this.firstName = firstName; 
    this.lastName = lastName; 
    this.age = age; 
  } 
  public Person(String firstName, String lastName, int age, Person[] children) { 
    this(firstName, lastName, age); 
    this.children = children; 
    for (int i = 0; i < children.length; i++) { 
      children[i].parent = this; 
    } 
  } 
  public String getFirstName() { 
    return this.firstName; 
  } 
  public String getLastName() { 
    return this.lastName; 
  } 
  public static Person[] example() { 
    return new Person[] { 
        new Person("Dan", "Rubel", 38, new Person[] { 
            new Person("Beth", "Rubel", 8), 
            new Person("David", "Rubel", 3) }), 
        new Person("Eric", "Clayberg", 39, new Person[] { 
            new Person("Lauren", "Clayberg", 6), 
            new Person("Lee", "Clayberg", 4) }), 
        new Person("Mike", "Taylor", 52) }; 
  } 
  public String toString() { 
    return firstName + " " + lastName; 
  } 
  public boolean testAttribute(Object target, String name, String value) { 
 
    if (target instanceof Person) { 
      Person person = (Person) target; 
      if (name.equals("firstName") && value.equals(person.getFirstName())) { 
        return true; 
      } 
 
      if (name.equals("lastName") && value.equals(person.getLastName())) { 
        return true; 
      } 
    } 
    return false; 
  } 
 } 

  总结

  至此为止,已经把 Eclipse 菜单功能及其扩展点涉及到的类 / 接口 /API 进行了详细的说明,相信读者已经有清晰的认识了。对于前面提到 popupMenus 方式创建上下文菜单,要求选择的对象实现 IActionFilter 接口,但是,如果开发人员正在使用 gmf 进行开发,那么我们可以不必要求选择的对象实现 IActionFilter,我们可以通过扩展 org.eclipse.gmf.runtime.common.ui.services.action.actionFilterProviders 对菜单项进行控制,如下代码清单 15 为扩展该 extension point 的 xml 代码,我们可以定义多个属性(<Attribute> … </Attribute),其中 Attribute 的 name 和 value 对应于 visibility 的 objectState 中的 name 和 value。

清单 15. 通过 actionFilterProviders 扩展点实现对菜单的控制

 <extension 
 point="org.eclipse.gmf.runtime.common.ui.services.action.actionFilterProviders"> 
   <ActionFilterProvider 
      class="com.free.menu.PopupActionFilterProvider"> 
    <Priority 
       name="Medium"> 
    </Priority> 
    <Attribute 
       name="com.ibm.bg.uml.search.isSupportedType" 
       value="supported"> 
    </Attribute> 
   </ActionFilterProvider> 
 </extension> 

  如下代码清单 16 所示 PopupActionFilterProvider 的实现,它继承 AbstractActionFilterProvider,只需要实现其中的 testAttribute 和 provides 方法,当 testAttribute 返回 true 时,那么该菜单项被启用,否则禁用。其中 target 对应于我们选择的对象,name 和 value 参数对应于 visiblity 中 objectState 的 name 和 value 的指定值 ( 与前面提到的 Person 类中的 testAttribute 方法类似 )。


清单 16. actionFilterProviders 扩展点实现类

 public class PopupActionFilterProvider extends AbstractActionFilterProvider { 
 
 
  public PopupActionFilterProvider() { 
  } 
 
  public boolean testAttribute(Object target, String name, String value) { 
       
  } 
 
  public boolean provides(IOperation operation) { 
    return false; 
  } 
 
 }

 

 

 

posted @ 2010-07-03 16:00 笑看人生 阅读(1823) | 评论 (0)编辑 收藏

扩展点:
org.eclipse.ui.menus(确定菜单创建的区域)
org.eclipse.ui.commands
org.eclipse.ui.handlers(command的具体行为)
org.eclipse.ui.commandImages(comand的图片)

扩展点org.eclipse.ui.menus用来对菜单进行扩展,可以对主菜单,工具栏,上下文菜单进行扩展。

示例代码如下:
<extension
         
point="org.eclipse.ui.menus">
      
<menuContribution
            
allPopups="false"
            locationURI
="menu:org.eclipse.ui.main.menu?after=additions">
         
<command
               
commandId="com.xxxx.test.command1"
               style
="push">
         
</command>
      
</menuContribution>
</extension>

其中locationURI属性指定菜单扩展的位置,上述代码是对主菜单进行扩展,如果要对工具栏和上下文菜单进行扩展,书写格式如下:

toolbar:org.eclipse.ui.main.toolbar?after=additions
popup:org.eclipse.ui.popup.any?after=additions(上下文菜单在任何位置出现)
popup:org.eclipse.ui.views.ProblemView?after=additions(上下文菜单在问题视图中出现)

commandId属性指定该menu对应的command,一个menu可以对应多个command。

command可以通过扩展点org.eclipse.ui.commands扩展,示例代码如下:

<extension
         
point="org.eclipse.ui.commands">
<category
            
id="com.xxxx.test.category1"
            name
="MenuTest">
      
</category>

      
<command
categoryId="="com.xxxx.test.category1"
            id
="com.xxxx.test.command1"
            name
="CommandA">
      
</command>
 
</extension>

至于Command具体要做什么,需要通过扩展点org.eclipse.ui.handlers来指定,示例代码如下:

<extension
         
point="org.eclipse.ui.handlers">
      
<handler
            
class="com.xxxx.test.SampleHandler"
            commandId
="com.xxxx.test.command1">
      
</handler>
 
</extension>

还有扩展点org.eclipse.ui.commandImages,可以指定Command对应的图标。

 <extension
         
point="org.eclipse.ui.commandImages">
      
<image
            
commandId="com.xxxx.test.command1"
            icon
="icons/sample.gif">
      
</image>
  
</extension>

posted @ 2010-07-03 15:55 笑看人生 阅读(2745) | 评论 (0)编辑 收藏

扩展点:org.eclipse.core.runtime.preferences
功能:该扩展点主要用来设置首选项的初始值;

扩展点示例:

<extension
         
point="org.eclipse.core.runtime.preferences">
      
<initializer
            
class="com.xxxx.test.AbstractPreferenceInitializer1">
      
</initializer>
</extension>

initializer指定设置首选项初始值的类,示例代码如下:

public class AbstractPreferenceInitializer1 extends
        AbstractPreferenceInitializer 
{    
    @Override
    
public void initializeDefaultPreferences() {
        IPreferenceStore prefs 
= Activator.getDefault().getPreferenceStore();
        prefs.setDefault(
"MAX"1000);
    }

}


上述代码设置属性MAX的初始值为1000,这个属性就可以被首选项使用了。

使用扩展点org.eclipse.ui.preferencePages扩展首选项

扩展点示例:

<extension
         
point="org.eclipse.ui.preferencePages">
      
<page
            
class="com.xxxx.test.WorkbenchPreferencePage1"
            id
="com.xxxx.test.page1"
            name
="testName">
      
</page>
</extension>

这样就可以在WorkbenchPreferencePage1类中使用刚才定义的属性MAX了,示例代码如下:

public class WorkbenchPreferencePage1 extends FieldEditorPreferencePage implements
        IWorkbenchPreferencePage 
{

    
public void init(IWorkbench workbench) {
        setPreferenceStore(Activator.getDefault().getPreferenceStore());        
    }

    @Override
    
protected void createFieldEditors() {
        
int max = getPreferenceStore().getDefaultInt("MAX");    
        System.out.println(
""+max);
    }
    
}


posted @ 2010-07-03 15:22 笑看人生 阅读(2588) | 评论 (0)编辑 收藏

原址地址:http://hi.baidu.com/dangjun625/blog/item/a0732c0845181ddc63d98666.html

MyEclipse has detected that less than 5% of the 64MB of Perm
Gen (Non-heap memory) space remains. It is strongly recommended
that you exit and restart MyEclipse with new virtual machine memory
paramters to increase this memory.   Failure to do so can result in
data loss. The recommended Eclipse memory parameters are:
eclipse.exe -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M

eclipse根目录下面的 eclipse.ini 配置 从网上搜了些资料

-vmargs:说明后面是VM的参数
-Xms128m:虚拟机占用系统的最小内存
-Xmx512m:虚拟机占用系统的最大内存的5%为25.6M,理论上要求-Xmx的数值与-XX:MaxPermSize必须大于25.6M
-XX:PermSize:最小堆大小。一般报内存不足时,都是说这个太小, 堆空间剩余小于5%就会警告,建议把这个稍微设大一点,不过要视自己机器内存大小来设置
-XX:MaxPermSize:最大堆大小。这个也适当大些

把里面的参数改为
-vmargs  
-Xms128M  
-Xmx512M  
-XX:PermSize=128M  
-XX:MaxPermSize=256M
问题解决!

从网上的资料看PermSize大一点肯定更好,而且最好是设置PermSize和MaxPermSize一样大。理由如下:
PermSize 和MaxPermSize如果设置为相同还可以在一定程度上提高性能,因为,PermSize在不断的变化中会需要转移其中的数据。如果固定了以后,则可以减少每次扩大PermSize带来的性能损失。

1、PermGen space简介
  
  PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space从表面上看就是内存益出,解决方法也一定是加大内存。
  
  说说为什么会内存益出:
  (1)这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同。
  (2) GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS 的话,就很可能出现PermGen space错误。这种错误常见在web服务器对JSP进行pre compile的时候。
  
  如果你的WEB APP下都用了大量的第三方jar,其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。

解决方法: 手动设置MaxPermSize大小
  
  修改TOMCAT_HOME/bin/catalina.bat,在echo "Using CATALINA_BASE: $CATALINA_BASE"上面加入以下行:
   JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m
  建议:将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以减少jar 文档重复占用内存

1。参数的含义

-vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M

参数中-vmargs的意思是设置JVM参数,所以后面的其实都是JVM的参数了,我们首先了解一下JVM内存管理的机制,然后再解释每个参数代表的含义。
堆(Heap)和非堆(Non-heap)内存
按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。
堆内存分配
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。
非堆内存分配
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。
JVM内存限制(最大值)
首先JVM内存限制于实际的最大物理内存,假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。

2. 为什么有的机器我将-Xmx和-XX:MaxPermSize都设置为512M之后Eclipse可以启动,而有些机器无法启动?

通过上面对JVM内存管理的介绍我们已经了解到JVM内存包含两种:堆内存和非堆内存,另外JVM最大内存首先取决于实际的物理内存和操作系统。所以说设置VM参数导致程序无法启动主要有以下几种原因:
1) 参数中-Xms的值大于-Xmx,或者-XX:PermSize的值大于-XX:MaxPermSize;
2) -Xmx的值和-XX:MaxPermSize的总和超过了JVM内存的最大限制,比如当前操作系统最大内存限制,或者实际的物理内存等等。说到实际物理内存这里需要说明一点的是,如果你的内存是1024MB,但实际系统中用到的并不可能是1024MB,因为有一部分被硬件占用了。

3. 为何将上面的参数写入到eclipse.ini文件Eclipse没有执行对应的设置?
那为什么同样的参数在快捷方式或者命令行中有效而在eclipse.ini文件中是无效的呢?这是因为我们没有遵守eclipse.ini文件的设置规则:
参数形如“项 值”这种形式,中间有空格的需要换行书写,如果值中有空格的需要用双引号包括起来。比如我们使用-vm C:\Java\jre1.6.0\bin\javaw.exe参数设置虚拟机,在eclipse.ini文件中要写成这样:
-vm
C:\Java\jre1.6.0\bin\javaw.exe
按照上面所说的,最后参数在eclipse.ini中可以写成这个样子:
-vmargs
-Xms128M
-Xmx512M
-XX:PermSize=64M
-XX:MaxPermSize=128M
实际运行的结果可以通过Eclipse中“Help”-“About Eclipse SDK”窗口里面的“Configuration Details”按钮进行查看。
另外需要说明的是,Eclipse压缩包中自带的eclipse.ini文件内容是这样的:
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
-vmargs
-Xms40m
-Xmx256m
其中–launcher.XXMaxPermSize(注意最前面是两个连接线)跟-XX:MaxPermSize参数的含义基本是一样的,我觉得唯一的区别就是前者是eclipse.exe启动的时候设置的参数,而后者是eclipse所使用的JVM中的参数。其实二者设置一个就可以了,所以这里可以把–launcher.XXMaxPermSize和下一行使用#注释掉。

3. 其他的启动参数。 如果你有一个双核的CPU,也许可以尝试这个参数:

-XX:+UseParallelGC

让GC可以更快的执行。(只是JDK 5里对GC新增加的参数)

 

补充:

可以在myelipse里选中相应的服务器比如tomcat5,展开里面的JDK子项页面,来增加服务器启动的JVM参数设置:

-Xms128m
-Xmx256m
-XX:PermSize=128M
-XX:MaxNewSize=256m
-XX:MaxPermSize=256m

posted @ 2010-06-26 21:37 笑看人生 阅读(511) | 评论 (0)编辑 收藏

Ajax中的XMLHttpRequest对象提供了两个属性来访问服务器端相应。

  • responseText:将相应作为一个字符串返回;(系列一中已经介绍)
  • responseXML:将相应作为一个XML对象返回;(本系列中介绍)
本节要介绍的内容,很多人应该比较熟悉,比如在网上注册时,在“省”列表框中选择不同的省份,对应的“市”列表框中出现该省的所有市,这个过程,不用刷新整个页面。

要实现这个功能,只须修改一下系列一中的index.jsp和AjaxServlet.java这两个文件。

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding
="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>

<script language="javascript">
    
var xmlHttp;
    
function refresh() {
        xmlHttp 
= createXMLHttpRequest();
        
var url = "AjaxServlet?province="
                
+ document.getElementById("province").value;
        xmlHttp.open(
"GET", url);
        xmlHttp.onreadystatechange 
= handleStateChange;
        xmlHttp.send(
null);
    }

    
function handleStateChange() {
        
if (xmlHttp.readyState == 4) {
            
if (xmlHttp.status == 200) {
                updateCity();
            }
        }
    }

    
function updateCity() {
        clearCity();
        
var city = document.getElementById("city");
        
var cities = xmlHttp.responseXML.getElementsByTagName("city");        
        
for(var i=0;i<cities.length;i++){
            option 
= document.createElement("option");
            option.appendChild(document.createTextNode(cities[i].firstChild.nodeValue));
            city.appendChild(option);                        
        }
    }

    
function clearCity() {        
        
var city = document.getElementById("city");
        
while(city.childNodes.length > 0) {
            city.removeChild(city.childNodes[
0]);
        }                    
    }
    
    
function createXMLHttpRequest() {
        
if (window.ActiveXObject) {
            xmlHttp 
= new ActiveXObject("Microsoft.XMLHTTP");
        } 
else if (window.XMLHttpRequest) {
            xmlHttp 
= new XMLHttpRequest();
        }
        
return xmlHttp;
    }
</script>

<body>
<form action="#"><select id="province" onchange="refresh()">
    
<option value="">Select One</option>
    
<option value="jiangsu">Jiang Su</option>
    
<option value="zhejiang">Zhe Jiang</option>
</select> <br>
<br>
<br>
<select id="city"></select></form>
</body>

</html>

AjaxServlet.java

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AjaxServlet extends HttpServlet {

    
private static final long serialVersionUID = 7032718233562299325L;

    @Override
    
protected void doPost(HttpServletRequest req, HttpServletResponse response)
            
throws ServletException, IOException {
        processRequest(req, response, 
"POST");
    }

    @Override
    
protected void doGet(HttpServletRequest req, HttpServletResponse response)
            
throws ServletException, IOException {
        processRequest(req, response, 
"GET");
    }

    
private void processRequest(HttpServletRequest req,
            HttpServletResponse response, String method) 
throws IOException {
        String province 
= req.getParameter("province");
        StringBuffer cities 
= new StringBuffer("<cities>");
        
        
if("jiangsu".equals(province)){
            cities.append(
"<city>Nanjing</city>");
            cities.append(
"<city>Zhenjiang</city>");
        }
else if("zhejiang".equals(province)){
            cities.append(
"<city>Hanzhou</city>");
            cities.append(
"<city>Wenzhou</city>");
        }        
        
        PrintWriter writer 
= response.getWriter();    
        cities.append(
"</cities>");
        response.setContentType(
"text/xml");
        writer.write(cities.toString());
        writer.close();
    }
}




posted @ 2009-11-15 09:28 笑看人生 阅读(231) | 评论 (0)编辑 收藏

简单介绍一下Ajax应用程序的基本流程:

  1. 创建XMLHttpRequest对象;
  2. 从页面中获取获取需要的数据;
  3. 建立要连接的URL;
  4. 打开与服务器的连接;
  5. 设置服务器相应之后要调用的函数,即回调函数;
  6. 发送请求;
下面以一个简单的例子来演示一下,该例子要完成的功能是使用Ajax技术对输入的EMail地址进行简单校验,根据校验的结果,在页面显示相应的消息。

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding
="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>

<script language="javascript">
      
var xmlHttp;  
     
function sendreq(){  
       xmlHttp 
= createXMLHttpRequest();  //步骤1
       
var url = "AjaxServlet?email=" + document.getElementById("email").value;//步骤2,3
       xmlHttp.open(
"GET", url);  //步骤4
       xmlHttp.onreadystatechange 
= handleStateChange; //步骤5
       xmlHttp.send(
null);    //步骤6
    }  
     
function handleStateChange(){       
      
if(xmlHttp.readyState == 4){  
         
if(xmlHttp.status == 200){             
             document.getElementById(
"result").innerHTML=xmlHttp.responseText;  
         }  
       }  
     }  
     
function createXMLHttpRequest(){  
         
if (window.ActiveXObject){  
             xmlHttp 
= new ActiveXObject("Microsoft.XMLHTTP");  
         }  
         
else if (window.XMLHttpRequest){  
             xmlHttp 
= new XMLHttpRequest();  
         }  
         
return xmlHttp;  
     }  
    
    
</script>
<body>
  
<label id="result">&nbsp;</label><br>
  Email:
<input type="text" id="email" onblur="sendreq()" value="" />  
  
<label id="result">&nbsp;</label>
  
</body>
</html>

AjaxServlet.java

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AjaxServlet extends HttpServlet {

    
private static final long serialVersionUID = 7032718233562299325L;

    @Override
    
protected void doPost(HttpServletRequest req, HttpServletResponse response)
            
throws ServletException, IOException {
        processRequest(req, response, 
"POST");
    }

    @Override
    
protected void doGet(HttpServletRequest req, HttpServletResponse response)
            
throws ServletException, IOException {
        processRequest(req, response, 
"GET");
    }

    
private void processRequest(HttpServletRequest req,
            HttpServletResponse response, String method) 
throws IOException {
        String email 
= req.getParameter("email");
        StringBuffer validator 
= new StringBuffer("");
        validator.append(method);
        response.setContentType(
"text/html;charset=UTF-8");
        PrintWriter writer 
= response.getWriter();
        
if (email.indexOf("@"< 0) {
            validator.append(
":FAILURE!");
        }
else{
            validator.append(
":SUCCESS!");
        }
        writer.write(validator.toString());
        writer.close();
    }
}

GET和POST请求方式区别:

  • POST方法将参数串放在请求体中发送;
  • GET方法将参数串放在URL中发送;

如果数据处理不改变数据模型的状态,建议使用GET方式,如果需要改变数据模型的状态,建议使用POST方式;

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns
="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
<display-name>ajax</display-name>
    
<welcome-file-list>
        
<welcome-file>index.jsp</welcome-file>
    
</welcome-file-list>
    
<servlet>
        
<servlet-name>AjaxServlet</servlet-name>
        
<servlet-class>servlet.AjaxServlet</servlet-class>
    
</servlet>
    
<servlet-mapping>
        
<servlet-name>AjaxServlet</servlet-name>
        
<url-pattern>/AjaxServlet</url-pattern>
    
</servlet-mapping>
</web-app>


posted @ 2009-11-01 12:31 笑看人生 阅读(313) | 评论 (0)编辑 收藏

最近在升级JDK版本后,启动Eclipse时候,遇到这样的问题:
JVM terminated.Exit code=1.
在网上找了些资料,找到了解决方法。
只要修改eclipse.ini文件即可。修改内容如下:
-startup
plugins\org.eclipse.equinox.launcher_1.0.100.v20080509-1800.jar
--launcher.library
plugins\org.eclipse.equinox.launcher.win32.win32.x86_1.0.100.v20080509-1800
-showsplash
vm
D:\Java\jdk15011\bin\javaw.exe
org.eclipse.platform
--launcher.XXMaxPermSize
256m
-vmargs
-Xms40m
-Xmx256m
其中粗体部分为新增内容。

posted @ 2008-07-27 21:22 笑看人生 阅读(11596) | 评论 (4)编辑 收藏

 

问题描述:

最近在做Eclipse插件开发的时候,在国际化的问题上遇到这样问题,比如我的plugin.xml文件中,通过%xxx来引用plugin_zh.properties中对应键xxx的信息时,在插件运行时,相应的信息显示不了,后来进过研究,发现是由于在MANIFEST.MF少配置了一项造成的

Bundle-Localization: plugin

而这一项配置我在Overview标签页上没有找到相应设置的地方,把这个在MANIFEST.MF加上,插件在运行时,就可以显示plugin_zh.properties中定义的消息了。

posted @ 2008-04-23 19:44 笑看人生 阅读(1591) | 评论 (0)编辑 收藏

  问题描述:

最近在Eclipse插件开发中遇到这样的问题,我使用如入扩展点

<extension
       
point="org.eclipse.debug.ui.launchConfigurationTabs">
    
<tab
          
class="com.example.launch.SqlDebugTab"
          group
="org.eclipse.jdt.debug.ui.launchConfigurationTabGroup.localJavaApplication"
          id
=" com.example.launchs.SqlDebugTab"
          name
="SqlDebugTab">
       
<associatedDelegate
             
delegate=" com.example.launch.SqlDebugLaunchDelegate">
       
</associatedDelegate>
    
</tab>
 
</extension>

<extension
          
point="org.eclipse.debug.core.launchDelegates">
       
<launchDelegate
             
delegate=" com.example.launch.SqlDebugLaunchDelegate"
             id
=" com.example.launch.SqlDebugLaunchDelegate"
             modes
="debug"
             type
="org.eclipse.jdt.launching.localJavaApplication">
       
</launchDelegate>
    
</extension>

 

也就是在调式Java Application的对话框中,增加一个Tab页,Tab页的名字为SqlDebugTab,在这个Tab页上增加几个复选框,复选框要显示视图的名称,如果用户选择某个复选框,点“Debug”后,将显示指定的视图,可是在com.example.launch.SqlDebugLaunchDelegate类中的launch方法中调用PlatformUI.getWorkbench().getActiveWorkbenchWindow(),得到的对象却为null,调试程序才发现,运行com.example.launch.SqlDebugLaunchDelegate类是,走的是新线程,也就是说点“Debug”按钮时,Eclipse平台启动的是新的线程(非UI线程),而在新线程中是取不到ActiveWorkbenchWindow对象,为了解决这个问题,花费了很多时间,最后终于找到解决方法,launch方法通过如下程序来显示视图,就可以解决上面遇到的问题:

PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
            
public void run() {
                IWorkbenchWindow window 
= PlatformUI.getWorkbench()
                        .getActiveWorkbenchWindow();
                
if (window != null){
                    window.getActivePage().showView(
"……");
}

}

}

posted @ 2008-04-23 19:41 笑看人生 阅读(2127) | 评论 (1)编辑 收藏

要在编辑器中支持复制,粘贴功能,首先,要在编辑器中选择活动节点,Eclipse工作台的菜单中复制,粘贴按钮处于激活状态,要实现这功能,我们还必须做些配置,因为编辑器没有单独的菜单栏,所有编辑器共享一个菜单栏,前面我们在定义编辑器扩展点时,有一个属性contributorClass没有指定值,它的值应该是一个实现IEditorActionBarContributor接口的类的全名,只有指定这个属性,菜单栏中的菜单项才能够对我们在编辑器中所做的操作进行相应;
首先,我们增加属性contributorClass对应的类:
package com.example.workflow.actions;

import org.eclipse.gef.ui.actions.ActionBarContributor;
import org.eclipse.ui.actions.ActionFactory;

public class WorkflowActionContributor extends ActionBarContributor {

    @Override
    
protected void buildActions() {
        
    }

    
    @Override
    
protected void declareGlobalActionKeys() {
        addGlobalActionKey(ActionFactory.COPY.getId());
        
    }
    

}

在declareGlobalActionKeys增加对复制命令的申明,同时把属性contributorClass指定为这个类,包含全路径。再定义复制动作CopyAction,代码如下:

package com.example.workflow.actions;

import org.eclipse.gef.ui.actions.SelectionAction;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.actions.ActionFactory;

public class CopyAction extends SelectionAction{

    
public CopyAction(IWorkbenchPart part) {
        
super(part);
        setId(ActionFactory.COPY.getId());
    }


    @Override
    
protected boolean calculateEnabled() {        
        
return true;
    }


}

 


注意构造函数中一定要把这个action的id设置为ActionFactory.COPY.getId(),和前面统一起来;

到这儿还没有结束,还必须在编辑器类中注册这个action,覆盖编辑器父类中的createActions()方法:

protected void createActions() {
    
super.createActions();

    CopyAction copyAction 
= new CopyAction((IWorkbenchPart) this);
    getActionRegistry().registerAction(copyAction);
    getSelectionActions().add(copyAction.getId());
}
但是当我们在复制按钮可用情况,点击之后,我们希望把我们选择的对象,拷贝到剪切板上,这个在其他软件中已经成功实现,但要是在我们开发的流程设计器中,要实现这个功能,我们还必须自己写代码来实现,必须重写CopyAction父类中的run方法,把我们选择的对象放到剪切板上,代码如下:
public void run() {
    Clipboard.getDefault().setContents(
super.getSelectedObjects());
}

这样当我们点复制按钮之后,流程设计器就把我们选择的内容放到剪切板上,下一步要做的就是粘贴了。

要使粘贴按钮可用,所做的修改和复制类似,在类WorkflowActionContributor 的方法declareGlobalActionKeys中增加addGlobalActionKey(ActionFactory.PASTE.getId())

增加PasteAction类,代码如下:

package com.example.workflow.actions;

import org.eclipse.gef.ui.actions.Clipboard;
import org.eclipse.gef.ui.actions.SelectionAction;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.actions.ActionFactory;

public class PasteAction extends SelectionAction{

    
public PasteAction(IWorkbenchPart part) {
        
super(part);
        setId(ActionFactory.PASTE.getId());
    }


    @Override
    
protected boolean calculateEnabled() {        
        
if(Clipboard.getDefault().getContents()!=null){
            
return true;
        }
else{
            
return false;
        }

    }


}

这里对Paste菜单的可用性作了判断,只有当剪切板中内容不为空时,粘贴按钮才可用,否则为不可用状
态。
另外还要在编辑器中对这个action进行申明,
PasteAction pasteAction = new PasteAction((IWorkbenchPart) this);
getActionRegistry().registerAction(pasteAction);
getSelectionActions().add(pasteAction.getId());
到这里,当我们在编辑器中选择活动,选择复制之后,粘贴按钮可用,但点粘贴按钮具体做什么,我们还没有定义,要实现这个做什么功能,还必须覆盖PasteAction父类中的run方法:
public void run() {
        List list 
= (List)Clipboard.getDefault().getContents();
        
for(int i=0;i<list.size();i++){
            AbstractActivityEditPart part 
= (AbstractActivityEditPart)list.get(i);
            AbstractActivity model 
= (AbstractActivity)part.getModel();
            WorkflowProcess parent 
= (WorkflowProcess)part.getParent().getModel();
            AbstractActivity clone 
= new AbstractActivity();
            clone.setName(
"CloneActivity");
            clone.setLocation(model.getLocation());
            clone.setSize(model.getSize());
            clone.setFigure(model.getFigure());
            parent.addChild(clone);
        }

    }

这里只是做了一下简单处理,更复杂的逻辑用户可以根据自己应用的需要,这里的run可以通过执行一个命令,以支持撤销,重做功能,原理就是这样的,另外剪切功能和这类似,只是在复制基础上多了个删除操作。

posted @ 2008-01-17 08:27 笑看人生 阅读(2118) | 评论 (1)编辑 收藏

这节介绍如何在SSH框架中使用Validator框架,Validator框架采用基于xml文件来配置验证规则,它主要依赖两个jar包:commons-validator-1.3.0.jar和oro-2.0.8.jar,要在SSH使用Validator框架,必须把这两个jar包引用进来,其实Struts框架已包含这两个jar包,所以我们不用再单独引入了。
       要在SSH框架中使用Validator,更确切的说是在Struts框架中使用,可以采用插件机制把Validator加入到框架,这需要修改原来的struts-config.xml文件,增加配置ValidatorPlugIn插件,代码如下:
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames" value="/org/apache/struts/validator/validator-rules.xml,
/WEB-INF/validation.xml"
 />
      
<set-property property="stopOnFirstError" value="true" />
 
</plug-in>
这样当应用启动时,Struts框架就会加载ValidatorPlugIn插件。
validator-rules.xml文件是Validator框架自带的,它定义了一些常有的校验规则,而validation.xml是我们自己定义的,它针对某个应用,内容如下:
    
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE form-validation PUBLIC
          "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.3.0//EN"
          "http://jakarta.apache.org/commons/dtds/validator_1_3_0.dtd"
>
<form-validation>   
 
<formset> 
    
<form name="registerForm">
      
<field property="register.username" depends="required">      
        
<arg key="register.username" position="0"/>      
      
</field> 
      
<field property="register.password" depends="required,minlength">      
        
<arg key="register.password" position="0"/>
        
<arg name="minlength" key="${var:minlength}" resource="false" position="1"/>
         
<var>
          
<var-name>minlength</var-name>
          
<var-value>6</var-value>
        
</var>     
      
</field>
      
<field property="register.email" depends="required,email">      
        
<arg key="register.email" position="0"/>      
      
</field>       
    
</form>   
 
</formset>
</form-validation>

 

form元素的name属性指定要进行验证的表单,field元素的property属性指定要验证属性,depends定义了验证方式,在这里,我们定义了username属性不能为空,password属性不能为空,并且最小长度不能小于6,email属性必须是合法的邮件地址。定义验证方式之后,我们还必须修改资源文件registermessages.properties,增加以下内容:

# Errors
errors.header=
<h3><fontcolor="red">ValidationError</font></h3>Youmustcorrectthefollowingerror(s)beforeproceeding:
errors.required={0}isrequired.
errors.minlength={0}cannotbelessthan{1}characters.
errors.email={0}isaninvalide-mailaddress.
这资源文件中{0}对应着<arg key="" position="0"/>,{1}对应着<arg key="" position="1"/>,以此类推,如果有验证错误产生,将用key的值替换{n}
 
此外,我们还要修改struts-config.xml文件,修改内容见粗体:

//把原来的DynaActionForm 改为DynaValidatorForm
<form-beans>
       
<form-bean name="registerForm"
           type
="org.apache.struts.validator.DynaValidatorForm">
           
<form-property name="register" type="test.register.entity.Register" />        
       
</form-bean>
    
</form-beans>
//把原来的validate="false"改为validate="true"
<action-mappings>
       
<action name="registerForm" path="/register" scope="request"
           type
="test.register.action.RegisterAction" validate="true"
           input
="/register.jsp">
           
<forward name="success" path="/registerSuccess.jsp" />
       
</action>
    
</action-mappings>

修改错误显示的样式,我们在register.jsp中,替换原来<html/errors>为
<logic:messagesPresent>
   
<bean:message key="errors.header"/>
   
<ul>
   
<html:messages id="error">
      
<li><bean:write name="error"/></li>
   
</html:messages>
   
</ul><hr />
</logic:messagesPresent>

注意在页面上加入
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>

这样,我们运行程序,校验失败的效果如图:

posted @ 2008-01-16 15:21 笑看人生 阅读(1851) | 评论 (1)编辑 收藏

     摘要:   到目前为止,一个完整的流程设计器已基本完成,为了增加系统的可扩展性,比如目前活动的类型有三种,假如以后我们要增加活动的类型,怎么办?按照目前的做法,我们只能修改代码,为了使系统的扩展性更好,即我们如果要增加活动类型,只需要修改配置文件,而无须修改现有系统的代码,为此,我们把活动类型定义一个扩展点,用户以后要增加活动类型,只需扩展这个扩展点就可以了。(代码) 在plugin.xml...  阅读全文

posted @ 2008-01-16 08:42 笑看人生 阅读(1531) | 评论 (3)编辑 收藏