Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何检测按键_Java_Keyboard_Key_User Input - Fatal编程技术网

Java 如何检测按键

Java 如何检测按键,java,keyboard,key,user-input,Java,Keyboard,Key,User Input,我正在使用java并试图编写一个简单的sudo鼠标记录器,当按下空格键时,它将存储鼠标位置。我需要检测的唯一一个键是空格键,不过如果另一个键更容易,那就行了 我需要整个鼠标记录器是用java编写的,但如果按键功能是用另一种语言编写的,那就可以了。我将在Windows7中运行这个 做上述事情最简单的方法是什么?我发现的所有方法至少需要20行代码。这没关系,只是我不知道如何实现它们。我有一个例子来源如下: import java.awt.MouseInfo; import javax.swing.J

我正在使用java并试图编写一个简单的sudo鼠标记录器,当按下空格键时,它将存储鼠标位置。我需要检测的唯一一个键是空格键,不过如果另一个键更容易,那就行了

我需要整个鼠标记录器是用java编写的,但如果按键功能是用另一种语言编写的,那就可以了。我将在Windows7中运行这个

做上述事情最简单的方法是什么?我发现的所有方法至少需要20行代码。这没关系,只是我不知道如何实现它们。我有一个例子来源如下:

import java.awt.MouseInfo;
import javax.swing.JOptionPane;


public class MouseRecorder {
    public static void main (String[] args)
    {
        int slot = 0;
        int xLoc[10];
        int yLoc[10];

        while (slot <= 10)
        {
            if (keyPressed(KEY_SPACE)) //<<<<This obviously won't work, but I'm looking for the simplest way to code this
            {
                xLoc[slot] = MouseInfo.getPointerInfo().getLocation().x;
                yLoc[slot] = MouseInfo.getPointerInfo().getLocation().y;
                slot++;
            }
        }

        //The mouse information can now be utilized
    }
}

你的问题也不清楚,因为你没有回答我的评论:


在我看来,您可能需要一个只对一次按键做出响应的系统范围的键盘记录器,而不需要GUI。如果是这样的话,那么最好的解决方案就是不要使用Java来创建应用程序,而是使用一种可以更接近操作系统的工具。如果这是一个Windows项目,我会想到它。请更好地定义您的需求

这迫使我们猜测问题的答案

如果您对创建Swing GUI感兴趣,让它聚焦,并让它监听关键事件,那么解决方案是:

创建并显示Swing GUI,在应用程序运行时将其作为活动窗口应用程序。 使用键绑定让它监听空格键的按下 然后在按下空格键时记录鼠标位置。 如前所述,这在5行代码中是不可能实现的,所以把这个想法放在一边。 另一方面,如果您不希望拥有GUI,而是希望在任何和所有应用程序运行时听到热键按下,那么

可能使用的平台至关重要,因为您的解决方案将需要特定于操作系统的代码,因为创建热键意味着必须创建键盘处理程序例程(通常使用C),并为每个平台创建该例程,然后使用JNI或JNA将其链接到Java。 或者,如前所述,另一种方法是将Java程序与操作系统特定的实用程序或脚本(如AutoIt)链接。 如果您需要更具体的帮助,请澄清您的问题

编辑 你说:


谢谢你的回答,但正如我上面所描述的:改变语言是不可能的,尽管这看起来可能更容易。如果可以避免的话,我不想要gui

那么我的第二个答案就是你要找的。您对C/C++、JNI或JNA的熟练程度如何?您对操作系统库的了解如何?如果你想要一个java的解决方案,我会考虑你的需求远远超过初学者或中级java,进入高级领域,或者至少超出我目前的能力,尽管我确信我可以在几天到一两周的学习之后想出一些解决方案。 。。。或者考虑删除您的更改语言需求,而至少允许java与脚本工具(如AutoIt)一起啮合。这可以在更短的时间内创造解决方案,至少对我来说是这样。不过,一个限制是,这些都是特定于平台的解决方案。你做这一切的目的是什么?这可能是一个伪装的XY问题吗

编辑2

我决定尝试用一个与Java相结合的小型AutoIt实用程序来解决这个问题,这就是我想到的

我的AutoIt程序名为CaptureHotKey.au3,在使用前编译为exe:

$key = $CmdLine[1]

HotKeySet($key, "hotKeyFunction")

While 1
    Sleep(100)
WEnd

Func hotKeyFunction()
    ConsoleWrite(@CRLF)
EndFunc
没什么大不了的。它所做的只是从第一个命令行参数设置一个热键,提供一个无休止的while循环,以便继续运行,以及一个非常简单的热键函数,它只向控制台发送一个回车/换行,这将是标准输出

然后是一个Java类来帮助与此交互。它使用SwingPropertyLanguageSupport来允许添加PropertyChangeListeners,以便在我希望将其用于GUI时在Swing线程上响应

import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.swing.event.SwingPropertyChangeSupport;

public class CaptureHotKey implements Runnable {
   public static final String HOT_KEY = "hot key";
   private String hotKey;
   private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(
         this);
   private Scanner scanner;
   private CaptureHotKeyFromAutoIt capture;

   public CaptureHotKey(final String hotKey) throws IOException {
      this.hotKey = hotKey;     
      capture = new CaptureHotKeyFromAutoIt(hotKey);
      scanner = new Scanner(capture.getReadable());
   }

   public void startCapturing() {
      new Thread(this).start();
   }

   public void exit() {
      if (capture != null) {
         capture.exit();  
      }
      if (scanner != null) {
         scanner.close();
      }
   }

   public void addPropertyChangeListener(PropertyChangeListener listener) {
      pcSupport.addPropertyChangeListener(listener);
   }

   public void removePropertyChangeListener(PropertyChangeListener listener) {
      pcSupport.removePropertyChangeListener(listener);
   }

   public String getHotKey() {
      return hotKey;
   }

   @Override
   public void run() {
      while (scanner != null && scanner.hasNextLine()) {
         scanner.nextLine();
         pcSupport.firePropertyChange(HOT_KEY, true, false);
      }
   }

   private static class CaptureHotKeyFromAutoIt {
      public static final String AUTO_IT_APP_PATH = "CaptureHotKey.exe";

      private Process process = null;
      private ProcessBuilder pb;

      public CaptureHotKeyFromAutoIt(String hotKey) throws IOException {
         List<String> cmdList = new ArrayList<>();
         cmdList.add(AUTO_IT_APP_PATH);
         cmdList.add(hotKey);
         pb = new ProcessBuilder(cmdList);
         pb.redirectErrorStream(true);
         process = pb.start();
      }

      public void exit() {
         if (process != null) {
            process.destroy();
         }
      }

      public Readable getReadable() {
         if (process != null) {
            return new InputStreamReader(process.getInputStream());
         }
         return null;
      }
   }
}

您应该使用KeyListener:
它可以与Swing配合使用

我发现的所有方法都至少需要20行代码。-20行代码有什么不好?压缩代码的目的是什么?您需要一个Swing GUI,并且该GUI必须具有Swing在这种情况下工作的焦点。如何使用键绑定?在我看来,您可能需要一个只对一次按键做出响应的系统范围的键盘记录器,而不需要GUI。如果是这样的话,那么最好的解决方案就是不要使用Java来创建应用程序,而是使用一种可以更接近操作系统的工具。如果这是一个Windows项目,我会想到它。请更好地定义您的需求。@Hovercraft Full Of EEL:20行代码的缺点是,它使事情变得更加复杂,如果可能的话,一到五行代码的可读性会更好。是的,你是对的,如果我可以避免的话,我不想要gui。@RandomPerson323:因为它是imp
如果您试图用5行Swing代码实现这一点,那么这是可能的。时期我也想养一匹小马,但这是不可能的。根据我在上面的评论,为了得到更好的帮助,你必须更好地定义你的问题空间。谢谢你的回答,但正如我在上面所描述的:改变语言是不可能的,尽管这看起来可能更容易。我不想要gui,如果我可以避免它,仔细想想,我可以更具体一些。我编辑了关于语言要求的主要帖子。@RandomPerson323:祝你好运。我最终可能会了解一些东西,尽管它是Windows特有的,我相信:@RandomPerson323:是的,这可能会奏效。如您所见,解决方案需要JNI合并到CPP代码中。再说一次,你打算用这个程序做什么?是的,它绝对是特定于Windows的。据我所知,没有解决方案是不可知操作系统的。请阅读整个问题和所有评论。这不适用于原始海报的目的。此外,在您将从Swing应用程序中使用KeyListener的情况下,使用键绑定几乎总是更好的,正如在本网站上多次讨论的那样。
import java.awt.MouseInfo;
import java.awt.PointerInfo;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.Scanner;

public class CaptureHotKeyTest {
   public static final String CTRL_R = "^r"; // "{SPACE}" works for spacebar
   private static final String EXIT = "exit";
   private CaptureHotKey capture;

   public CaptureHotKeyTest() {
      try {
         capture = new CaptureHotKey(CTRL_R);
         capture.addPropertyChangeListener(new HotKeyPropertyChngListener());
         capture.startCapturing();

         Scanner scan = new Scanner(System.in);
         System.out.println("Press control-r to get mouse position.");
         System.out.println("Type \"exit\" to exit program");
         while (scan.hasNextLine()) {
            String line = scan.nextLine();
            if (line.equalsIgnoreCase(EXIT)) {
               scan.close();
               capture.exit();
               break;
            }
         }
      } catch (IOException e) {
         e.printStackTrace();
      }      
   }

   private class HotKeyPropertyChngListener implements PropertyChangeListener {
      @Override
      public void propertyChange(PropertyChangeEvent evt) {
         if (evt.getPropertyName().equals(CaptureHotKey.HOT_KEY)) {
            System.out.println("hot key pressed");

            PointerInfo pointerInfo = MouseInfo.getPointerInfo();
            System.out.println("Mouse: " + pointerInfo.getLocation());
         }
      }
   }

   public static void main(String[] args) {
      new CaptureHotKeyTest();
   }

}