getKeyStroke(char) 与 getKeyStroke(char, int) - 我不明白其中的区别
getKeyStroke(char) vs. getKeyStroke(char, int) - I don't understand the difference
此代码总是returns 0:
KeyStroke.getKeyStroke(someString.charAt(0)).getKeyCode();
而这个 returns 实际键码:
KeyStroke.getKeyStroke(someString.charAt(0), 0).getKeyCode();
但是,我不明白 getKeyStroke() 中的第二个参数有什么用。 documentation 没有解释任何东西,除了这个参数被称为 "modifier" 并且它似乎不会以任何方式影响关键代码,独立于我放在那里的数字。
我很乐意得到解释。
您需要了解 keyPressed、keyTyped 和 keyReleased 事件之间的区别。
在第一种情况下,会生成一个 keyTyped
事件。在第二种情况下,会生成一个 keyPressed
事件。
然后您需要检查 KeyEvent
API 在那里您会发现:
对于按键按下和按键释放事件,getKeyCode 方法returns 事件的keyCode。对于键类型事件,getKeyCode 方法总是 returns VK_UNDEFINED.
编辑:
其实上面的回答还不够完整。查看以下演示代码:
public class Main
{
public static void main(String[] args) throws Exception
{
KeyStroke ks1 = KeyStroke.getKeyStroke( 'a' );
System.out.println( ks1 );
KeyStroke ks2 = KeyStroke.getKeyStroke('a', 0);
System.out.println( ks2 );
}
}
我得到以下输出:
typed a
pressed NUMPAD1
来自getKeyStroke(Character keyChar, int modifiers)
API:
注意第一个参数是Character类型而不是char类型。这是为了避免与调用 getKeyStroke(int keyCode, int modifiers) 的无意冲突。
所以,我想说修饰符与问题无关。问题是 'a' 被视为 int 并映射到与您预期不同的 KeyStroke。
尝试使用机器人生成角色总是有风险的。这是您可能会使用的一个简单示例:
import java.awt.*;
import java.util.*;
import java.lang.reflect.Field;
import java.awt.event.*;
import javax.swing.*;
public class RobotCharacter
{
public static void main(String[] args)
throws Exception
{
JTextField textField = new JTextField(10);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( textField );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
Robot robot = new Robot();
typeCharacter(robot, "a");
typeCharacter(robot, "b");
typeCharacter(robot, "C");
typeCharacter(robot, "D");
}
public static void typeCharacter(Robot robot, String letter)
{
try
{
boolean upperCase =
Character.isUpperCase(letter.charAt(0) );
String variableName = "VK_" + letter.toUpperCase();
Class clazz = KeyEvent.class;
Field field = clazz.getField( variableName );
int keyCode = field.getInt(null);
robot.delay(1000);
if (upperCase)
{
robot.keyPress( KeyEvent.VK_SHIFT );
}
robot.keyPress( keyCode );
robot.keyRelease( keyCode );
if (upperCase)
{
robot.keyRelease( KeyEvent.VK_SHIFT );
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
在 letters/numbers 上工作正常,但您总是会遇到特殊字符 ($、%、&...) 的问题。我建议您寻找其他方法而不是使用机器人。
您可以尝试创建一个字符的 Hashmap 及其对应的KeyEvent.VK_???。即使这种方法也有问题,因为有些字符需要 shift 键,而有些键盘不同,因此有些可能需要 shift 键,有些则不需要。
修饰符是用于同时按下的按位掩码,例如ctrl 按钮或 shift 按钮。不要只是在其中输入任何数字。
KeyStroke.getKeyStroke('a', java.awt.event.InputEvent.SHIFT_DOWN_MASK | java.awt.event.InputEvent.CTRL_DOWN_MASK);
如果 ctrl 或 shift 按钮应该与 'a'
一起按下,则修饰符的正确用法
此代码总是returns 0:
KeyStroke.getKeyStroke(someString.charAt(0)).getKeyCode();
而这个 returns 实际键码:
KeyStroke.getKeyStroke(someString.charAt(0), 0).getKeyCode();
但是,我不明白 getKeyStroke() 中的第二个参数有什么用。 documentation 没有解释任何东西,除了这个参数被称为 "modifier" 并且它似乎不会以任何方式影响关键代码,独立于我放在那里的数字。
我很乐意得到解释。
您需要了解 keyPressed、keyTyped 和 keyReleased 事件之间的区别。
在第一种情况下,会生成一个 keyTyped
事件。在第二种情况下,会生成一个 keyPressed
事件。
然后您需要检查 KeyEvent
API 在那里您会发现:
对于按键按下和按键释放事件,getKeyCode 方法returns 事件的keyCode。对于键类型事件,getKeyCode 方法总是 returns VK_UNDEFINED.
编辑:
其实上面的回答还不够完整。查看以下演示代码:
public class Main
{
public static void main(String[] args) throws Exception
{
KeyStroke ks1 = KeyStroke.getKeyStroke( 'a' );
System.out.println( ks1 );
KeyStroke ks2 = KeyStroke.getKeyStroke('a', 0);
System.out.println( ks2 );
}
}
我得到以下输出:
typed a
pressed NUMPAD1
来自getKeyStroke(Character keyChar, int modifiers)
API:
注意第一个参数是Character类型而不是char类型。这是为了避免与调用 getKeyStroke(int keyCode, int modifiers) 的无意冲突。
所以,我想说修饰符与问题无关。问题是 'a' 被视为 int 并映射到与您预期不同的 KeyStroke。
尝试使用机器人生成角色总是有风险的。这是您可能会使用的一个简单示例:
import java.awt.*;
import java.util.*;
import java.lang.reflect.Field;
import java.awt.event.*;
import javax.swing.*;
public class RobotCharacter
{
public static void main(String[] args)
throws Exception
{
JTextField textField = new JTextField(10);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( textField );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
Robot robot = new Robot();
typeCharacter(robot, "a");
typeCharacter(robot, "b");
typeCharacter(robot, "C");
typeCharacter(robot, "D");
}
public static void typeCharacter(Robot robot, String letter)
{
try
{
boolean upperCase =
Character.isUpperCase(letter.charAt(0) );
String variableName = "VK_" + letter.toUpperCase();
Class clazz = KeyEvent.class;
Field field = clazz.getField( variableName );
int keyCode = field.getInt(null);
robot.delay(1000);
if (upperCase)
{
robot.keyPress( KeyEvent.VK_SHIFT );
}
robot.keyPress( keyCode );
robot.keyRelease( keyCode );
if (upperCase)
{
robot.keyRelease( KeyEvent.VK_SHIFT );
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
在 letters/numbers 上工作正常,但您总是会遇到特殊字符 ($、%、&...) 的问题。我建议您寻找其他方法而不是使用机器人。
您可以尝试创建一个字符的 Hashmap 及其对应的KeyEvent.VK_???。即使这种方法也有问题,因为有些字符需要 shift 键,而有些键盘不同,因此有些可能需要 shift 键,有些则不需要。
修饰符是用于同时按下的按位掩码,例如ctrl 按钮或 shift 按钮。不要只是在其中输入任何数字。
KeyStroke.getKeyStroke('a', java.awt.event.InputEvent.SHIFT_DOWN_MASK | java.awt.event.InputEvent.CTRL_DOWN_MASK);
如果 ctrl 或 shift 按钮应该与 'a'
一起按下,则修饰符的正确用法