如何编写密钥监听器来跟踪Java中的所有键击?

我想用Java编写一个关键的监听器。 无论Java应用程序是否具有焦点,它都应跟踪所有按键操作。 这可能吗?

这是可能的,但需要利用JNI的实现,而JNI并不总是可移植的。

Java System Hook是一个可以与Windows 32和64位一起使用的库。

我刚才用过类似的东西。 看看Java System Hook 。

它通过JNI跟踪全局按键(不仅仅是您的Java应用程序)。 它对我来说非常快速而且完美


KeyListener作为守护程序线程启动,它不会使应用程序保持活动状态。 您必须在程序中有另一个正在运行的非守护程序线程

例如:

GlobalKeyListener globalKeyListener = new GlobalKeyListener(); globalKeyListener.addKeyListener(listener); while (true) { Thread.sleep(1000); } 

不,Java无法访问其活动窗口之外的键击。

要实现这一点,您必须使用Java和本机代码的组合,使用JNI来调用本机代码。 在Microsoft Windows中,您应该查看GetAsyncKeyState(key)

这很有可能,但是不使用标准Java,您必须在本机级别与操作系统进行交互。

以下是Windows的一个主题,它使用JNA访问Windows User32 API中的SetWindowsHookEx函数。

不,如果它不是活动(聚焦)窗口,Java不会听密钥,所以你不能这样做。

试试这个http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/javax/swing/KeyStroke.java

该链接包含Java swing应用程序所需的源代码。

 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ /* * keylogger.java * * Created on Mar 8, 2012, 8:12:20 AM */ package main; import javax.swing.JOptionPane; /** * * @author Lab-Admin */ public class keylogger extends javax.swing.JFrame { /** Creates new form keylogger */ public keylogger() { initComponents(); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { jPanel1 = new javax.swing.JPanel(); jLabel1 = new javax.swing.JLabel(); jPanel2 = new javax.swing.JPanel(); jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); userfield = new javax.swing.JTextField(); jLabel4 = new javax.swing.JLabel(); passfield = new javax.swing.JPasswordField(); btnlogin = new javax.swing.JButton(); btncancel = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle("Punk Academy PRoject"); setBackground(new java.awt.Color(255, 0, 0)); setFont(new java.awt.Font("Algerian", 1, 14)); // NOI18N setForeground(new java.awt.Color(255, 153, 0)); jPanel1.setBackground(new java.awt.Color(255, 204, 0)); jLabel1.setBackground(new java.awt.Color(255, 0, 0)); jLabel1.setFont(new java.awt.Font("Algerian", 1, 24)); // NOI18N jLabel1.setText("Punk Academy"); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(102, 102, 102) .addComponent(jLabel1) .addContainerGap(108, Short.MAX_VALUE)) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(20, 20, 20) .addComponent(jLabel1) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); jPanel2.setBackground(new java.awt.Color(255, 255, 255)); jLabel2.setIcon(new javax.swing.ImageIcon("D:\\COPRO OLAER\\enrollment system\\umbrellalast.gif")); // NOI18N jLabel3.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N jLabel3.setText("username"); jLabel4.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N jLabel4.setText("password"); btnlogin.setIcon(new javax.swing.ImageIcon("D:\\COPRO OLAER\\enrollment system\\Keys.gif")); // NOI18N btnlogin.setText("Log in"); btnlogin.setDisabledIcon(new javax.swing.ImageIcon("D:\\COPRO OLAER\\enrollment system\\Keys.gif")); // NOI18N btnlogin.setDisabledSelectedIcon(new javax.swing.ImageIcon("D:\\COPRO OLAER\\enrollment system\\Keys.gif")); // NOI18N btnlogin.setIconTextGap(2); btnlogin.setPressedIcon(new javax.swing.ImageIcon("D:\\COPRO OLAER\\enrollment system\\Keys.gif")); // NOI18N btnlogin.setRolloverIcon(new javax.swing.ImageIcon("D:\\COPRO OLAER\\enrollment system\\Keys.gif")); // NOI18N btnlogin.setRolloverSelectedIcon(new javax.swing.ImageIcon("D:\\COPRO OLAER\\enrollment system\\Keys.gif")); // NOI18N btnlogin.setSelectedIcon(new javax.swing.ImageIcon("D:\\COPRO OLAER\\enrollment system\\Keys.gif")); // NOI18N btnlogin.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnloginActionPerformed(evt); } }); btncancel.setIcon(new javax.swing.ImageIcon("D:\\COPRO OLAER\\enrollment system\\exit.png")); // NOI18N btncancel.setText("Cancel"); btncancel.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btncancelActionPerformed(evt); } }); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel2)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() .addContainerGap(82, Short.MAX_VALUE) .addComponent(btnlogin, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED))) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addGap(16, 16, 16) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel3) .addComponent(jLabel4)) .addGap(18, 18, 18) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(passfield, javax.swing.GroupLayout.DEFAULT_SIZE, 111, Short.MAX_VALUE) .addComponent(userfield, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 111, Short.MAX_VALUE))) .addGroup(jPanel2Layout.createSequentialGroup() .addGap(43, 43, 43) .addComponent(btncancel, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap()) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addGap(46, 46, 46) .addComponent(jLabel2)) .addGroup(jPanel2Layout.createSequentialGroup() .addGap(64, 64, 64) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(userfield, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel3)) .addGap(18, 18, 18) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(passfield, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel4)))) .addGap(49, 49, 49) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(btnlogin) .addComponent(btncancel, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap()) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) ); pack(); }// //GEN-END:initComponents private void btnloginActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnloginActionPerformed if(evt.getSource()==btnlogin) { String user = btnlogin.getText(); String pass = btncancel.getText(); if(user.equals(user)&&pass.equals(pass)) { this.hide(); JOptionPane.showMessageDialog(null,"ACCESS GRANTED"); welcome s2 = new welcome(); s2.show(); } else { JOptionPane.showMessageDialog(null,"ACCESS DENIED"); } } }//GEN-LAST:event_btnloginActionPerformed private void btncancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btncancelActionPerformed if(evt.getSource()==btncancel) { JOptionPane.showMessageDialog(null,"BYE! BYE!"); System.exit(0); } }//GEN-LAST:event_btncancelActionPerformed /** * @param args the command line arguments */ public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { new keylogger().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btncancel; private javax.swing.JButton btnlogin; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JPasswordField passfield; private javax.swing.JTextField userfield; // End of variables declaration//GEN-END:variables }