JButton按下时是否有任何功能?

时间:2014-10-23 05:55:18

标签: java awt jbutton jtextarea keylistener

我正在聊天程序中为JTextArea创建KeyListener

如果按ENTER键,JTextArea将获得新行

但是,我想让ENTER键作为“SEND”功能运行

这是我的代码

public void keyPressed(KeyEvent ke) {
            if(ke.getKeyCode() == KeyEvent.VK_ENTER)
                sendButton.???
            else if(ke.getKeyCode() == KeyEvent.VK_ALT + KeyEvent.VK_ENTER)
                inputTextArea.setText(inputTextArea.getText() + "\n");
        }

我应该怎么做 - > ???

是否有任何有用的建议,教我,让我的程序发展:)

1 个答案:

答案 0 :(得分:2)

不要将KeyListener与文本组件一起使用,这通常是不好的做法,相反,您希望控制KeyEvent.VK_ENTER键绑定操作并在那里插入自定义功能......

现在,诀窍是,让现有的Action仍然有用,因为你不需要再做任何工作......

这可以通过获取与Action ...

相关联的KeyEvent.VK_ENTER来实现
InputMap im = ta.getInputMap(JTextArea.WHEN_FOCUSED);
ActionMap am = ta.getActionMap();

Object key = im.get(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
Action insertBreak = am.get(key);

然后,您可以将自己的动作设置为在其位置触发,将之前的动作传递给它,以便在您希望它时可以调用...

am.put(key, new MyNewOnEnterAction(insertBreak));

//...

public class MyNewOnEnterAction extends AbstractAction {

    private Action proxy;

    public MyNewOnEnterAction(Action proxy) {
        this.proxy = proxy;
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        // Your custom functionality here...
        proxy.actionPerformed(e);
    }

}

例如......

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    private JLabel status;

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JTextArea ta = new JTextArea(10, 10);
                InputMap im = ta.getInputMap(JTextArea.WHEN_FOCUSED);
                ActionMap am = ta.getActionMap();

                Object key = im.get(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
                Action insertBreak = am.get(key);

                am.put(key, new MyNewOnEnterAction(insertBreak));

                status = new JLabel("...");

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(ta));
                frame.add(status, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public void sendMessage(String message) {

    }

    public class MyNewOnEnterAction extends AbstractAction {

        private Action proxy;

        public MyNewOnEnterAction(Action proxy) {
            this.proxy = proxy;
        }

        public int getLineAtCaret(JTextComponent component) {
            int caretPosition = component.getCaretPosition();
            Element root = component.getDocument().getDefaultRootElement();

            return root.getElementIndex(caretPosition) + 1;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            JTextArea ta = (JTextArea) e.getSource();
            int line = getLineAtCaret(ta);
            try {
                int startPos = ta.getLineStartOffset(line - 1);
                int endPos = ta.getLineEndOffset(line - 1);
                Document doc = ta.getDocument();

                String text = doc.getText(startPos, endPos - startPos);
                status.setText(text);
            } catch (BadLocationException ex) {
                ex.printStackTrace();
            }

            proxy.actionPerformed(e);
        }

    }

}

这将获取当前文字行并将其设置为status JLabel的{​​{1}} ...

就个人而言,我会设置一个类或方法,你的键绑定text和你的按钮都可以调用...或者你甚至可以使用相同的Action,谁知道;)

有关详细信息,请参阅How to Use Key BindingsHow to Use Actions