Catch a “double” hotkey

2019-02-27 07:40发布

问题:

I have to catch a hotkey of Ctrl+Alt+C, C (meaning, press Ctrl+Alt+C, release only C and press it again). Here is what I'm trying to do:

import com.tulskiy.keymaster.common._
import java.awt.event._
import javax.swing.KeyStroke

class KeysCatcher {

  val provider = Provider.getCurrentProvider(true)
  val ctrlC = KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK + ActionEvent.ALT_MASK)

  val listener = new HotKeyListener() {
    def onHotKey(hotKey: HotKey): Unit = {
      hotKey.keyStroke match {
        case `ctrlC` =>
          println("Ctrl+Alt+C 1 was pressed")

          val listener2 = new HotKeyListener() {
            def onHotKey(hotKey: HotKey): Unit = {
              hotKey.keyStroke match {
                case `ctrlC` => println("Ctrl+Alt+C 2 was pressed")
              }
            }
          }

          provider.register(ctrlC, listener2)
      }
    }
  }

  provider.register(ctrlC, listener)
}

I had the idea that once Ctrl+Alt+C is pressed I have to register the same hotkey again and catch it. I was going to involve a timer since the second press of C should be pretty quick. But I think I took the wrong way since it would make pretty complicated.

Your thoughts? P.S. There is no window there, it catches a global hotkey. I've also tried much stuff from the Internet and it didn't work as I wanted, so before providing me any code please test it.

Although this example is Scala, Java would be ok also.

Dependency:

https://github.com/tulskiy/jkeymaster

//build.scala
val jkeymaster = "com.github.tulskiy" % "jkeymaster" % "1.1" 

回答1:

You can register a global hotkey only once, but you can receive its events in the handler many times. So the basic idea is to save the last time your saw this key and if two are coming between certain delay, you have a double click:

    var last = 0l
    val listener = new HotKeyListener() {
      def onHotKey(hotKey: HotKey): Unit = {
        hotKey.keyStroke match {
          case `ctrlC` =>
            if (System.currentTimeMillis() - last < 700) // arbitrary delay of 700 ms
              println("We have a double click!")
            else last = System.currentTimeMillis()
        }
      }
    }

if you want something without var, I guess you can wrap it in a Promise or something.