gpt4 book ai didi

java - 自定义按键事件

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:21:32 27 4
gpt4 key购买 nike

我如何发送自定义 SWT 键事件,以便在不进行任何转换的情况下键入准确的文字字符?

我们正在制作一个允许多种可能布局的自定义屏幕图形键盘——QWERTY 是主要布局,但其他几种布局也在计划中,包括视觉上模拟 iPhone 键盘布局的布局或其他相对于电脑。

我希望能够将我选择的任意字符作为事件发送,这样它就会导致键入该确切字符。但是,每当我发送带有给定字符的事件时,SWT 似乎会根据系统的键盘设置和状态自动解释和转换它,将其更改为大写/小写或使用移位符号,具体取决于是否按下了 shift 键(例如实际键盘上的真实键)。例如,通过键事件传递字符“T”将导致“t”或“T”,具体取决于 shift 键。它与“4”字符的执行方式类似,根据 shift 执行“4”或“$”。

这是有问题的,因为我希望手动执行字符的转换,而且在任何给定情况下确实可能不希望使用与标准 QWERTY 键盘相同的转换字符(例如,我希望 '$'是更小的类似手机键盘上的“R”的移位(或“功能”键)版本)。我如何使用这些事件,使其不假定使用 QWERTY 键?

SWT 事件中“字符”字段的文档说明如下:

the character represented by the key that was typed. This is the final character that results after all modifiers have been applied. For example, when the user types Ctrl+A, the character value is 0x01. It is important that applications do not attempt to modify the character value based on a stateMask (such as SWT.CTRL) or the resulting character will not be correct.

这让我相信它不应该像现在这样转换我的角色,因为我命令它使用我的“最终”结果。

我已经创建了一个简单的独立示例来演示我的问题(请注意,这不是我处理实际键盘的方式,只是为了突出关键事件问题):

screenshot

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Button;

public class KeyboardIssueExample extends Shell {
private Text txtTextArea;
private Composite cmpButtons;
private Button btnBigA;
private Button btnBigS;
private Button btnLittleD;
private Button btnSix;
private Button btnSeven;
private Button btnDollah;
private Button btnStar;

private SelectionListener mainListener = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent selE) {
Button b = (Button)selE.widget;
char c = b.getText().charAt(0);
sendKey(c);
}
};

/**
* Launch the application.
* @param args
*/
public static void main(String args[]) {
try {
Display display = Display.getDefault();
KeyboardIssueExample shell = new KeyboardIssueExample(display);
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* Create the shell.
* @param display
*/
public KeyboardIssueExample(Display display) {
super(display, SWT.SHELL_TRIM);
createContents();
}

/**
* Create contents of the shell.
*/
protected void createContents() {
setText("SWT Application");
setSize(450, 300);
setLayout(new GridLayout());

txtTextArea = new Text(this, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.CANCEL | SWT.MULTI);
txtTextArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

cmpButtons = new Composite(this, SWT.NONE);
cmpButtons.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
GridLayout gl_cmpButtons = new GridLayout(7, false);
gl_cmpButtons.marginWidth = 0;
gl_cmpButtons.marginHeight = 0;
cmpButtons.setLayout(gl_cmpButtons);

btnBigA = new Button(cmpButtons, SWT.NONE);
btnBigA.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
btnBigA.setText("A");

btnBigS = new Button(cmpButtons, SWT.NONE);
btnBigS.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
btnBigS.setText("S");

btnLittleD = new Button(cmpButtons, SWT.NONE);
btnLittleD.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
btnLittleD.setText("d");

btnSix = new Button(cmpButtons, SWT.NONE);
btnSix.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
btnSix.setText("6");

btnSeven = new Button(cmpButtons, SWT.NONE);
btnSeven.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
btnSeven.setText("7");

btnDollah = new Button(cmpButtons, SWT.NONE);
btnDollah.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
btnDollah.setText("$");

btnStar = new Button(cmpButtons, SWT.NONE);
btnStar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
btnStar.setText("*");

init();
}

private void init() {
btnBigA.addSelectionListener(mainListener);
btnBigS.addSelectionListener(mainListener);
btnLittleD.addSelectionListener(mainListener);
btnSix.addSelectionListener(mainListener);
btnSeven.addSelectionListener(mainListener);
btnDollah.addSelectionListener(mainListener);
btnStar.addSelectionListener(mainListener);
}

@Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}


private void sendKey(char c) {
sendKeyEvent(c, SWT.KeyDown);
sendKeyEvent(c, SWT.KeyUp);
}

private void sendKeyEvent(char c, int eventType) {
txtTextArea.forceFocus();
Event event = new Event();
event.type = eventType;
event.character = c;
getDisplay().post(event);
}

}

您会发现,关键事件不遵守我自己习惯的大写用法,而是使用它自己的。多麻烦。

最佳答案

查看适用于 Mac 和 Windows 的 Display.post 的源代码,其中有很多特定于按键上/下事件的代码。这包括调用特定于操作系统的 API,以将您指定的字符和键码转换为用于生成击键事件的特定于操作系统的方法所需的参数。

对于 Windows,此代码调用 VkKeyScan,根据 Microsoft 文档,它会查看当前键盘状态。

Display 确实有一个 postEvent(Event) 方法,它添加到事件队列而不改变任何东西,但这不是公开的,所以你必须使用反射来访问它.由于它不是官方 API 的一部分,因此可能会发生变化。

编辑:实际上有一个 Eclipse 错误报告 here为了这。它已经开放了 10 年,所以可能不会修复!

更新:还有一个 Widget.notifyListeners(eventType, Event) 方法,可用于将按键事件发送到特定控件。您必须创建 Event 并设置必填字段。

关于java - 自定义按键事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21531333/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com