【问题标题】:Adding a Key Listener to a JtextArea向 JtextArea 添加关键侦听器
【发布时间】:2017-04-06 20:33:12
【问题描述】:

我有一个名为 input 的 JTextArea,当我按下向上箭头键时,我试图将字符串 inputValue 加载到其中。到目前为止,这段代码似乎不起作用,我不确定为什么。请帮忙。

    input.addKeyListener(new KeyListener() {            
        public void keyTyped(KeyEvent e) {
            System.out.println("test");
            if(e.getKeyCode() == KeyEvent.VK_UP) {
                input.setText(inputValue);
                System.out.println("up is pressed");
            }       
        }

        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub  
        }

        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub      
        }
    });

【问题讨论】:

  • 不要将 KeyListener 与 Swing 文本组件一起使用,因为它们会破坏组件的本机功能。有更好的方法来捕获这些组件中的按键,包括使用 DocumentListeners、DocumentFilters 和 Key Bindings。

标签: java swing keylistener


【解决方案1】:

在 JTextAreas 之类的 Swing 文本组件上使用 KeyListeners 之类的低级侦听器时应该小心,因为弄乱这些侦听器会导致文本组件行为异常。

如果您要查找对文档的更改,最好使用 DocumentListener;如果您想在发生之前侦听并阻止或更改文本条目,则使用 DocumentFilter。

如果您只想收到向上箭头等键的通知,我会使用键绑定——JTextArea 使用自己来通知按键并对按键做出反应,并将键绑定替换为新的一。如果您小心地执行此操作,您甚至可以在新操作中调用与按键相关的原始操作。例如:

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class TextAreaTrapUp extends JPanel {
    private JTextArea textArea = new JTextArea(20, 40);

    public TextAreaTrapUp() {
        // get JTextArea's InputMap and ActionMap
        int condition = JComponent.WHEN_FOCUSED;
        InputMap inputMap = textArea.getInputMap(condition);
        ActionMap actionMap = textArea.getActionMap();

        // get the up keystroke
        KeyStroke upKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
        String upKey = (String) inputMap.get(upKeyStroke); // get the input map's key for this keystorke
        Action originalUpAction = actionMap.get(upKey); // and get the action map's original action for this key

        Action newUpAction = new NewUpAction(originalUpAction); // create our new up action passing in the old one
        actionMap.put(upKey, newUpAction); // and set this into our ActionMap

        textArea.setWrapStyleWord(true);
        textArea.setLineWrap(true);
        add(new JScrollPane(textArea));
    }

    // Action called when up-arrow pressed
    private class NewUpAction extends AbstractAction {
        private Action originalUpAction; // the original action

        public NewUpAction(Action originalUpAction) {
            this.originalUpAction = originalUpAction;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Up Arrow Pressed");

            // if you want to move the caret up, then call the original action
            // as well
            if (originalUpAction != null) {
                originalUpAction.actionPerformed(e);
            }
        }
    }

    private static void createAndShowGui() {
        TextAreaTrapUp mainPanel = new TextAreaTrapUp();

        JFrame frame = new JFrame("TextAreaTrapUp");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

【讨论】:

  • 我之前在 Swing 组件上使用动作监听器时遇到了这个问题。我最终使用线程锁定来解决故障,但我认为从长远来看这可能会更好。哦,好吧。
  • @CNorlander:我不确定我是否理解您的最后评论。但是有一个问题:为什么要将向上箭头按钮困在 JTextArea 中,因为这有点不寻常的要求?您是否希望向上箭头也能正常工作——向上移动插入符号?还有一个小问题:考虑对所有努力帮助您的答案进行投票。
  • 文本区域用于文本冒险游戏中的输入,并且在不需要用户输入时被禁用。我不希望用户在未启用该字段时能够使用此向上箭头命令。向上箭头键不需要执行其正常功能。
【解决方案2】:

你应该覆盖 void keypressed 而不是 keytyped

@Override
        public void keyPressed(KeyEvent e) {
            System.out.println("test");
            if(e.getKeyCode() == KeyEvent.VK_UP) {
                input.setText(inputValue);
                System.out.println("up is pressed");

        }

因为它不是角色

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    • 2011-12-18
    • 2013-06-29
    • 2010-11-26
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多