`
想入非非~~
  • 浏览: 4174 次
  • 性别: Icon_minigender_1
  • 来自: 现九江读书
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

JIntellitype使用总结

阅读更多

简单介绍:

    因为要在java项目中注册全局热键(程序失去焦点,依然可以响应按键),而且自己本身对c的了解并不是特别深,所以无法用jni调用c程序,只好使用了JIntellitype第三方包。
    JIntellitype包很小,下载的zip文件不到200kb,其中源文件即使包括c和c++代码才58kb,如果只算java代码,就只有28kb,所以JIntellitype使用起来非常轻便。

    它只专注于在java项目中注册全局热键,而不考虑其它的东西。本身是对c和c++代码的封装,为我们提供了一个注册全局热键的java接口,免去了我们用jni调用c方法的麻烦。

    它只适用于windows操作系统,如果想在linux系统上注册全局热键可以用JXGrabKey,网址:http://sourceforge.net/projects/jxgrabkey/(JIntellitype推荐)
 
 使用感受:
    (1) 虽然功能不是很全,但核心功能都有,推荐使用。
    (2) 网上有关它的教程可能很少,但是因为它很简洁,所以基本上自学即可(官网介绍,官网上那仅有的一个例子,api文档,源代码,以及下载zip包中的readme.txt文件,这些东西全看一遍,基本上可以完全掌握它)
    (3) 官网上关于它使用时应注意的要点很不详细,包括它的API讲解,源代码注释都太简单了(这个就是下面我要总结的,我想即使你看过并全部消化上面的东西也会在这些地方产生迷惑)


 小插曲:
    前天才开始接触JIntellitype,因为注册全局热键的需要。到官网上转了一圈,四处看了看,最后下了个包,满意而归,觉得自己在java项目中注册全局热键的想法终于可以实现了。我又在网上找了个小例子,按着它的方法试了一下,成功,原来它是如此 easy!
    有了这个成功的前奏,也更加的有信心,因为它的实用以及简洁,我决定好好的研究一下它,所以又来到官网(www.melloware.com),把有关它的介绍,还有那仅有的一个小例子,api文档,源代码,以及下载的zip包中的readme.txt,从头到尾看了一遍,觉得自己已完全掌握了如何使用它,后来才知道,自己想的太简单
 
 问题及回答:  
    1. 问:JIntellitype的完整的运转流程是怎样的?
    

    答:我先说一下我推荐的有关JIntellitype代码书写顺序的大概方式吧(为什么这么写,你看到下面的问题就应该有点了解了,当然,你完全可以有自己的风格)。
   
   首先我们有个A.java负责测试:
   
   public class A {
   
    public A()
    {
  GlobalHotkeyResourceManagement.initResources();
     GlobalHotkeyResourceManagement.addListener();
     
     B.register();
     C.register();
     
     try
     {
      Thread.sleep(3000);
     }
     catch (InterruptedException e)
     {
      e.printStackTrace();
     }
     
     //B.unregister();  //这里的两行可以要也可以不要,下面会说
     //C.unregister();
     
     GlobalHotkeyResourceManagement.releaseResources();
    }
    
    public static void main(String[] args)
    {
     new A();
    }
   }

    下面分别是"全局热键资源管理类"(GlobalHotkeyResourceManagement.java),"负责某类热键的注册,解除注册,及监听的类"(B.java),"同B.java类等价的类"(C.java),负责真正的功能:
   
   public class GlobalHotkeyResourceManagement {

    public static void initResources()
    {
     JIntellitype.getInstance();
     System.out.println("init resources...");
    }
    
    public static void addListener()
    {
     B.addListener();
     C.addListener();
    }
    
    public static void releaseResources()
    {
     JIntellitype.getInstance().cleanUp();
     System.out.println("release resources...");
    }
   }
   
   public class B {
   
    public static void register()
    {
     JIntellitype.getInstance().registerHotKey(88, JIntellitype.MOD_CONTROL, (int)'B');
     System.out.println("register...");
    }
    
    public static void unregister()
    {
     JIntellitype.getInstance().unregisterHotKey(88);
     System.out.println("unregister...");
    }
    
    public static void addListener()
    {
     JIntellitype.getInstance().addHotKeyListener(new HotkeyListener(){

      @Override
      public void onHotKey(int key)
      { 
       if(key == 88)
       {
        //你要做的事
       }
      }
     });
    }
   
   }
 
   public class C {
   
    public static void register()
    {
     JIntellitype.getInstance().registerHotKey(89, JIntellitype.MOD_CONTROL, (int)'N');
     System.out.println("register...");
    }
 
    public static void unregister()
    {
     JIntellitype.getInstance().unregisterHotKey(89);
     System.out.println("unregister..."); 
    }
 
    public static void addListener()
    {
     JIntellitype.getInstance().addHotKeyListener(new HotkeyListener(){
      
      public void onHotKey(int key)
      { 
       if(key == 89)
       {
        //你要做的事   
       }
      }
     });
    }
   }
 
       好,那我们开始结合上面的代码深入讲解它的运行流程(包括我们看不到的):
   
    (1) 在A.java中,我们首先初始化JIntellitype所需资源,执行的真正代码是“JIntellitype.getInstance()”,它的作用是加载JIntellitype.dll文件,建立与操作系统联系的通道。
    
    (2) 然后为JIntellitype加上我们想要的各种监听(GlobalHotkeyResourceManagement.addListener()),这样,当我们按下了我们后面注册的热键,操作系统会告诉JIntellitype,然后JIntellitype又调用“自己”的onHotKey()方法,在这个方法中又调用你给JIntellitype添加的监听类中的onHotKey()方法(就是上面我们添加“//你要做的事”这个注释的代码块), 至于为什么,你可以去看一下源码,写的非常清楚。
    
    我还是简单的说一下吧。
    
        “JIntellitype中有个List型变量存放的是我们向JIntellitype中添加的我们自己写的监听(List<HotkeyListener> hotkeyListeners)当我们按下了我们注册的热键后,操作系统告诉JIntellitype,JIntellitype调用自己的onHotKey()方法在这个方法中有这么一句:hotkeyListener.onHotKey(identifier)。hotkeyListener是hotkeyListeners中的某个元素的引用,JIntellitype是通过for循环方式,把hotkeyListeners中的各个元素赋给hotkeyListener,然后开启一个线程,在该线程中调用hotkeyListener.onHotKey(identifier)。
    通过这样的方式,JIntellitype把按下了注册的热键这个事件告诉所有我们注册的监听(其实就是分别调用我们注册的监听类中的onHotkey()方法)”
   

    (3) 我们通过JIntellitype为我们搭建的连接操作系统的通道,向操作系统中注册我们想要的热键(B.register(); C.register();),现在我们就可以正常使用了。
    
    (4) 至于回收资源的操作分为两种:一种是调用unregister()方法(A.java中的“B.unregister(); C.unregiste();”),另一种是cleanUp()方法(A.java中调用的releaseResources()方法,真正执行的是JIntellitype.getInstance().cleanUp())
        

    这两种方法有很大的区别,要注意:
      
        unregister()方法是只是把你以前注册的热键取消掉。
        cleanUp()方法是完全释放我们通过JIntellitype.getInstance()方法加载的JIntellitype.dll文件占有的资源(其实就是关闭连向操作系统的通道)
     

   注:有个情况我们要注意一下,这也是我在实践中证实的,虽然我并不懂它的原因,而且我觉得它这样的结果也并不合理,但这是事实。
    还拿上面的代码来说,如果我们在A.java的最后再加上一些代码,使它在释放掉JIntellitype的资源后,我们再重新分配资源(JIntellitype.getInstance()),再加监听,再注册,再释放资源。
    如果你运行一下,你会发现有异常,异常是发生在你第二次试图向操作系统注册热键的时候,它的原因是没有JIntellitype资源。这么说来,如果我们在一个运行的程序中(应该说是在一个jvm中,下面再说)释放过一次JIntellitype资源,我们不可以再分配

   哦,对,我还要说一点,开始我写JIntellitype程序时,在经过unregister过程后,如果我还想注册,那么我会在调用register()后,我还会再重新添加一次监听,我以为unregister的过程会把我添加的监听也会除去。结果这个监听类的onHotKey()方法总是调用两次,当时很不解,现在终于也明白了,我想你不会像我一样吧。
   
    2. 问:官网资料说“JIntellitype.getInstance()”方法用同步方法,保证了在全局中只有一个JIntellitype实例,那这个全局究竟是指什么?
  
       答:全局是指在一个jvm中。做项目中,我们可能会用一个类调用其它的各个类,而其它各个类中也有相互间的调用。我们会注意到一点:其它各个类的实例化及运行终归都要归结于最开始的那个类的运行,它是我们这个项目的“树根”,其它的都是这个项目的“树根”分出来的“树枝”,所有的类相互联系构成了一棵“树”,这棵“树”就是一个jvm。
       由上可知,不管我们是在“树根”处掉用“JIntellitype.getInstance()”方法,还是在“树叶”处调用这个方法,还是在其它的什么地方,它们返回都是同一个JIntellitype实例,这个是要注意的,所以在一个项目中千万不要乱用JIntellitype的cleanUp方法,一般来说只要项目程序还要运行,我们应用unregister()方法,只有在项目关闭之前我们才用cleanUp方法

0
2
分享到:
评论
3 楼 人不萝卜 2011-04-19  
还是表示感谢  这个弄明白了     不好意思
2 楼 人不萝卜 2011-03-31  

楼主能告诉一下怎么不关闭程序重新registerHotKey()么



或者更改快捷键

比如
JIntellitype.getInstance().registerHotKey(89, JIntellitype.MOD_CONTROL, (int)'N');
之后  我想把快捷键改成 ctrl+s 


先unregisterHotKey 再registerHotKey 的话   就会调用两次了


看帖子里说的  不过实在是太笨 没整明白怎么解决
1 楼 yanji94521 2011-03-09  
说的很详细! 谢谢

我研究这个也有一段时间了,发现只要监听了的键,只能是同步,无法实现异步监听。

同步:及按监听的键只触发了监听,实质本键并没有执行。

我想达到的效果,监听开始后 在文本中按键依然能够打出字

可惜啊  估计需要改DLL代码了  试验了好多常用软件的热键 都是一个德行,不能打字

相关推荐

Global site tag (gtag.js) - Google Analytics