SWT 模拟键盘事件
SWT 模拟键盘事件
导言
在GUI设计中,我们往往要模拟鼠标和键盘事件,在java 的awt 中的java.awt.Robot; 类就可以进行模拟。但是在SWT中,我尝试了一下,会抛出空指针异常,或许是我写得有问题,或许是SWT不能用Robot类来模拟,这个我没有进一步去验证,感兴趣的同志们可以去尝试一下。
下面来说说怎么在SWT中模拟键盘按键的按下。
思路
实现一个Runnable接口SimulateButtonDown去生成一个KeyEevnet,然后发送出去给KeyAdapeter进行捕获处理。
验证
为了验证上述方案是否可行,我写了一个只有两个按钮的简单GUI窗口。
SimulateButtonDown类:
package com.lks.test;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
public class SimulateButtonDown implements Runnable {
private char ch;
private Display display;
public SimulateButtonDown(char ch, Display display) {
this.ch = ch;
this.display = display;
}
/* * (非 Javadoc) * * @see java.lang.Runnable#run() */
@Override
public void run() {
Event e = new Event();
System.out.println("before run : " + this.ch);//查看修改字符
e.type = SWT.KeyDown;//修改事件类型
e.character = this.ch;//修改相应的字符
System.out.println("After run : " + e.character);//查看是否被正确赋值
display.post(e);
}
}
Windows类:
package com.lks.test;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class Windows {
protected Shell shlTest;
private Button btnLeft;
private Button btnRight;
private Display display;
/** * Launch the application. * @param args */
public static void main(String[] args) {
try {
Windows window = new Windows();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
/** * Open the window. */
public void open() {
display = Display.getDefault();
createContents();
shlTest.open();
shlTest.layout();
while (!shlTest.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
/** * Create contents of the window. */
protected void createContents() {
shlTest = new Shell();
shlTest.setSize(231, 297);
shlTest.setText("Test");
btnLeft = new Button(shlTest, SWT.NONE);
btnLeft.setBounds(10, 41, 80, 27);
btnLeft.setText("+");
btnLeft.addSelectionListener(new ButtonClickListener("+"));
btnLeft.addKeyListener(new KeyListener());
btnRight = new Button(shlTest, SWT.NONE);
btnRight.setText("-");
btnRight.setBounds(96, 41, 80, 27);
btnRight.addSelectionListener(new ButtonClickListener("-"));
btnRight.addKeyListener(new KeyListener());
}
private final class ButtonClickListener extends SelectionAdapter {
private String btnName;
public ButtonClickListener(String btnName) {
this.btnName = btnName;
}
@Override
public void widgetSelected(SelectionEvent e) {
if ("+".equals(btnName)) {
new Thread(new SimulateButtonDown('+', display)).start();
}
else if ("-".equals(btnName)) {
new Thread(new SimulateButtonDown('-', display)).start();
}
}
}
private final class KeyListener extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
System.out.println("keyListener: " + e.character);
}
}
}
窗口如下:
点击按钮-,运行结果如下:
before run : -
After run : -
keyListener: -
可见Keylistner可以成功监听到我们生成的事件,我们继续点按钮+,看看会发生什么
我们传进去“+”号,出来的是“=”号!!!What?惊不惊喜?意不意外?刺不刺激?!
我们在SimulateButtonDown接口类中将run方法修改成下面这样子,看看我们生成的keyCode是什么情况
@Override
public void run() {
Event e = new Event();
System.out.println("before run : " + this.ch + " " + e.keyCode);
e.type = SWT.KeyDown;
e.character = this.ch;
System.out.println("run : " + this.ch + " " + e.keyCode);
System.out.println("After run : " + e.character + " " + e.keyCode);
display.post(e);
}
在内部类KeyListener中修改一下keyPressed方法:
@Override
public void keyPressed(KeyEvent e) {
System.out.println("keyListener: " + e.character + " " + e.keyCode);
}
再次运行程序:
before run : - 0
run : - 0
After run : - 0
keyListener: - 45
before run : + 0
run : + 0
After run : + 0
keyListener: = 61
然后直接按键盘的+和-看看keyCode:
keyListener: + 16777259
keyListener: - 16777261
由此可见,我们的keyCode并没有被改变,可是明明character已经变了,可为什么还不行呢?这个我也不清楚原因,知道原因的朋友可以给我留个言,非常感谢。
那我们试试直接修改keyCode能不能正常工作呢?实践是检验真理的唯一标准~
将SimulateButtonDown接口类修改成:
package com.lks.test;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
public class SimulateButtonDown implements Runnable {
private int keyCode;
private Display display;
public SimulateButtonDown(int keyCode, Display display) {
this.keyCode = keyCode;
this.display = display;
}
/* * (非 Javadoc) * * @see java.lang.Runnable#run() */
@Override
public void run() {
Event e = new Event();
System.out.println("before run : " + e.keyCode);
e.type = SWT.KeyDown;
e.keyCode = this.keyCode;
System.out.println("After run : " + e.keyCode);
display.post(e);
}
}
在ButtonClickListener内部类中修改相应的代码:
@Override
public void widgetSelected(SelectionEvent e) {
if ("+".equals(btnName)) {
new Thread(new SimulateButtonDown(SWT.KEYPAD_ADD, display)).start();
}
else if ("-".equals(btnName)) {
new Thread(new SimulateButtonDown(SWT.KEYPAD_SUBTRACT, display)).start();
}
}
运行结果如下:
before run : 0
After run : 16777261
keyListener: - 16777261
before run : 0
After run : 16777259
keyListener: + 16777259
由此可见,只修改character不能实现想要的按键模拟,而修改keyCode可以正常工作。