- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 Swing 的使用并不陌生,但我用它做了很多工作,并且我正在设计一个新的应用程序。这是一个绘图应用程序。它将允许用户单击空白的白色“查看器”窗口中的某些位置,使用键盘键入字母和符号,从而编辑查看器窗口上某处的文本。
由于我没有使用 JComponent
来显示此文本,因此我需要一种可靠的方式让我的应用程序接受输入。我选择使用 KeyBindings。但我的特殊查看器组件以空的输入映射和空的操作映射开始。
我的问题。将我可以使用键盘输入的所有字母和符号映射到使用 ActionMap 和 InputMap 的 AbstractAction
的最简单方法是什么?操作映射需要使用WHEN_IN_FOCUSED_WINDOW
来捕获界面的所有输入。
编辑:我曾经使用按键监听器来做到这一点,但我未能获得模块化我想要的方式
我把代码弄丢了。把它彻底扔掉。我相信 SSCCE 中是这么说的:
import java.awt.event.KeyEvent;
import static java.awt.event.KeyEvent.*;
public class MyKeysHandler extends KeyListener {
//blah blah blah
//blah blah blah
public void keyPressed(KeyEvent ke)
{
// please excuse if the boolean logic of my use of masks is off
// their proper use doesn't come to me easily
// I hope you can get the jist
if((ke.getModifiersEx() & KeyEvent.SHIFT_DOWN_MASK) != 0) {
switch(ke.getKeyCode()) {
// handle capital letters
case VK_DELETE : editor.handleThisSpecialKey(ke.getKeyCode);
case VK_BACK_SLASH : // handle back slash
case VK_7 : // handle the ampersand
case VK_8 : // handle the asterisk character
default : // if just a normal letter...
editor.handleThisNormalKeyPlease(KeyEvent.getKeyText(ke.getKeyCode()).toUpperCase());
}
}
else {
switch(ke.getKeyCode()) {
case VK_DELETE : // handle the shift-delete command
case VK_BACK_SLASH : // handle the question mark
case VK_7 : // handle the 7
case VK_8 : // handle the 8
defualt :
if(ke.getKeyCode() == VK_C && ke.getModifiersEX() & KeyEvent.CTRL_DOWN_MASK) != 0) {
editor.handleTheCopyCommandPlease();
}
else
editor.handleThisKeyPlease(KeyEvent.getKeyText(ke.getKeyCode).toLowerCase());
}
}
}
}
但这真的很麻烦。每次添加一个键时,您都必须确保它不会与同一方法中的其他一些键代码冲突,并且对于您必须为任何应用程序制作的每个键监听器,您都必须包含这个细致的“VK”开关代码。
我的应用程序还将有菜单,当我有时间时,我也想为这些安装新的按键绑定(bind)或加速器(或者它们的名称 - 助记符?)。为了移动文本和删除它们,最好有几个特殊的组合键来执行此操作。至于你在上面看到的关键组合?你可以想象这对我来说是多么的一场噩梦。
我向您保证,无需发布更多代码,我会尝试遵循良好的可重用计算机编程实践的良好模型。我有一个在下面运行并实际处理编辑的模型,以及一个在上面运行并处理菜单按钮代码的 View 。
不幸的是,我希望 Java 不必像上面所示的那么麻烦。并非键盘上的所有键(但大多数键)都需要不同的响应,具体取决于您按下的键,并且 KeyBindings 支持 ctrl 和 Shift 等组合。
我希望有一个循环解决方案。那么也许有一个使用 WHEN-IN-ANCESTOR 的解决方案也可以工作。我使用的输入映射是组件根 Pane ,但我也愿意深入查看器组件本身(JPanel)并获取其 InputMap
实例,但我还没有'还没有这样做,因为我正在尝试。
我目前访问项目的方式是这样的:这对我来说效果很好。但它不处理符号。也许如果我增加 for 循环中的字符跨度?还是手动添加几个?我不知道。
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;
public void initKeyBindingsTheEasyWay() {
JRootPane rootPane = mainPane.getRootPane();
InputMap theWIMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap theAMap = rootPane.getActionMap();
for(char c = 'A'; c <= 'Z'; c++) {
// lower case
KeyStroke little = KeyStroke.getKeyStroke("pressed " + c);
theWIMap.put(little, ""+Character.toLowerCase(c));
theAMap.put(""+Character.toLowerCase(c), new LetterAction(Character.toLowerCase(c)));
}
}
public static class LetterAction extends AbstractAction
{
char theLetter;
public LetterAction(char letter)
{
theLetter = letter;
}
public void actionPerformed(ActionEvent ae)
{
System.out.print(theLetter);
}
}
最佳答案
我试了又试,终于找到了解决办法。对于有兴趣的人来说,有两种方法可以解决这个问题。我不会深入研究通过 TextComponent 的 API 进行搜索来发现它是如何完成的。这对于我自己来说是非常困难的,最终我不得不走另一条路。
我将字符和虚拟键映射到操作。
这就是我一直在寻找的:一种循环遍历感兴趣的字符的简单方法,从而通过简单地将击键映射到操作来节省代码和复杂性:如果您不关心捕获我在下面列出的某些键只需从正确的数组中删除字符或虚拟键即可。您甚至可以添加新字符
首先实例化一个 JComponent(在本例中我使用了一个名为 mainPane 的 JFrame)。我想捕获输入到框架中的所有击键,因此我使用了 JComponent.WHEN_IN_FOCUSED_WINDOW。
请注意下面代码中 KeyEvent 常量的静态导入。
import static java.awt.event.KeyEvent.*;
mainPane.setFocusTraversalKeysEnabled(false);
JRootPane rootPane = mainPane.getRootPane();
InputMap theWIMap = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap theAMap = rootPane.getActionMap();
然后您可以添加捕获字母击键的代码...
for(char c = 'A'; c <= 'Z'; c++) {
// upper case
KeyStroke capital = KeyStroke.getKeyStroke("typed " + c);
theWIMap.put(capital, Character.toString(c));
theAMap.put(Character.toString(c), new KeyAction(c));
// lower case
KeyStroke little = KeyStroke.getKeyStroke("typed " + Character.toLowerCase(c));
theWIMap.put(little, Character.toString(Character.toLowerCase(c)));
theAMap.put(Character.toString(Character.toLowerCase(c)), new KeyAction(Character.toLowerCase(c)));
}
...然后编写代码来捕获许多键盘上常见符号的输入(通过低头查看键盘按键上的字体可以看到这些符号。我将它们列在此处按照 Java API SE 7: Constant Field Values 中指定的“VK 常量值”顺序。(?、%、~ 和 | 没有 VK 常量)。
int[][] characters = new int[][] {
{'?', '%', '~', '|'},
{' ', ',', '-', '.', '/'},
{';', '=', '[', '\\', ']'},
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'},
{'*', '+', ',', '-', '.', '/', '&', '*', '\"', '<', '>', '{', '}', '`', '\''},
{'@', ':', '^', '$', '!', '(', '#', '+', ')', '_'}
// if you're so inclined: add even more rows to the bottom
,{'¡', '€', '\u02ff'}
};
for(int[] range : characters)
for(int i = 0; i < range.length; i++) {
char charForKey = (char)range[i];
KeyStroke keyboardKey = KeyStroke.getKeyStroke(charForKey);
theWIMap.put(keyboardKey, charForKey);
theAMap.put(charForKey, new KeyAction(charForKey));
}
...最后是处理许多键盘上常见的命令键输入的代码。
int[][] commands = new int[][] {
{VK_BACK_SPACE, VK_ENTER, VK_ESCAPE},
{VK_PAGE_UP, VK_PAGE_DOWN, VK_END, VK_HOME},
{VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_DELETE},
{VK_KP_UP, VK_KP_DOWN, VK_KP_LEFT, VK_KP_RIGHT},
};
for(int[] range : commands)
for(int i = 0; i < range.length; i++) {
KeyStroke keyboardKey = KeyStroke.getKeyStroke(range[i], 0);
String commandForKey = KeyEvent.getKeyText(range[i]).toLowerCase();
theWIMap.put(keyboardKey, commandForKey);
theAMap.put(commandForKey, new KeyAction(commandForKey));
}
theWIMap.put(KeyStroke.getKeyStroke("pressed " + "TAB"), "tab");
theAMap.put("tab", new KeyAction("tab"));
theWIMap.put(KeyStroke.getKeyStroke("shift pressed " + "TAB"), "shift tab");
theAMap.put("shift tab", new KeyAction("shift tab"));
现在在此处添加此操作代码(忽略有关编辑器的部分:这是调用我的 Controller 的部分):
public class KeyAction extends AbstractAction
{
private static final long serialVersionUID = 1L;
public char theLetter;
public String theCommand;
public enum KeyType {CHARACTER_ENTRY, KEYSTROKE_COMMAND};
public final KeyType actionType;
public KeyAction(char letter)
{
theLetter = letter;
actionType = KeyType.CHARACTER_ENTRY;
}
public KeyAction(String command)
{
theCommand = command;
actionType = KeyType.KEYSTROKE_COMMAND;
}
public void actionPerformed(ActionEvent ae)
{
if(actionType == KeyType.CHARACTER_ENTRY) {
System.out.print(theLetter);
editor.receiveKey(theLetter);
}
else {
System.out.println("\n" + theCommand);
editor.receiveCommand(theCommand);
}
}
}
打开应用程序的 GUI 窗口后,输入如下内容:“我喜欢土 bean 沙拉。[ENTER] 立即捐赠 10.00 美元![TAB][SHIFT TAB]”您应该在终端中看到与此类似的内容。
I love potato salad.
enter
Donate $10.00 now!
tab
shift tab
关于java - 使用 KeyBindings 将所有字符映射到操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24470164/
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!