将某些字符/键的输入重新映射到JTextComponent的最佳方法是什么?

时间:2013-04-03 10:38:51

标签: java swing input keylistener jtextcomponent

我正在研究一个JTextPane,它几​​乎与stackoverflow上的标签输入字段一样工作。为此,我会在用户点击输入,制表符或空格时立即将文本转换为组件。当然,我不希望任何这些字符实际输入到文本窗格。我找到了这个解决方案,SSCCE:

import java.awt.Color;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.StyledDocument;

@SuppressWarnings("serial")
public class TagTextPane extends JTextPane {

    public TagTextPane() {
        this.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "finalizeTag");
        this.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), "finalizeTag");
        this.getInputMap().put(KeyStroke.getKeyStroke("TAB"), "focusNext");
        this.getActionMap().put("focusNext", new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                finalizeTag();
                transferFocus();
            }
        });
        this.getActionMap().put("finalizeTag", new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent e) {
                finalizeTag();
            }
        });
    }

    private void finalizeTag() {
        StyledDocument doc = (StyledDocument) getDocument();
        Element element = doc.getCharacterElement(getCaretPosition() - 1);
        int start = element.getStartOffset();
        int len = element.getEndOffset() - start;
        String tag = "";
        try {
            tag = this.getDocument().getText(start, len);
        } catch (BadLocationException e) {
        }
        this.setSelectionStart(start);
        this.setSelectionEnd(start + len);
        JLabel label = new JLabel(tag);
        label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        this.insertComponent(label);        
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("TagTextPaneTest");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        TagTextPane tPane = new TagTextPane();
        frame.setSize(400, 100);
        frame.getContentPane().add(tPane);
        frame.setVisible(true);
    }
}

点击" tab"通常会导致插入标签字符并点击"输入"通常会导致换行,以及击中"空间"导致输入空格。奇怪的是,我的代码阻止了换行符和标签输入,但仍然允许在执行预期操作时正常输入空格。

  1. 为什么这种方法对这些键的行为有所不同?

  2. 如何阻止空间进入? (也许我想稍后将此行为扩展到逗号等。)

  3. 如何以JTextComponent最佳方式控制某些字符和击键的行为?我看过this,建议使用KeyListener,但我也看到this,Rob Camick指出,为什么KeyListener不应该使用。那么我应该使用DocumentFilter,还是在轮子上打破蝴蝶呢?

  4. 这是构建此类标记输入字段的最佳方法吗?

1 个答案:

答案 0 :(得分:2)

this.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "finalizeTag");

这是处理空格字符的keyPressed事件。

您想要处理空格字符的keyTyped事件:

this.getInputMap().put(KeyStroke.getKeyStroke(' '), "finalizeTag");