SWT 模拟键盘事件

本文探讨如何在SWT环境中模拟键盘事件。由于Java AWT的Robot类在SWT中可能引发空指针异常,作者提出了一种通过实现Runnable接口生成并发送KeyEvent的解决方案。通过创建SimulateButtonDown类并配合KeyAdapter捕获处理,作者验证了该方法的有效性。在实验过程中,发现直接修改character属性无法达到预期效果,而修改keyCode则可以实现键盘事件的正确模拟。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);  
        }
    }

}

窗口如下:
GUI运行结果

点击按钮-,运行结果如下:

before run : -
After run : -
keyListener: -

可见Keylistner可以成功监听到我们生成的事件,我们继续点按钮+,看看会发生什么
BUG

我们传进去“+”号,出来的是“=”号!!!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可以正常工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值