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 笑看人生 阅读(206) | 评论 (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 笑看人生 阅读(885) | 评论 (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 笑看人生 阅读(2623) | 评论 (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 笑看人生 阅读(2970) | 评论 (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 笑看人生 阅读(4014) | 评论 (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 笑看人生 阅读(393) | 评论 (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 笑看人生 阅读(339) | 评论 (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 笑看人生 阅读(4636) | 评论 (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 笑看人生 阅读(3329) | 评论 (0)编辑 收藏

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

posted @ 2016-01-28 19:45 笑看人生 阅读(3311) | 评论 (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 笑看人生 阅读(2339) | 评论 (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 笑看人生 阅读(2776) | 评论 (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 进行开发