Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将某些字符/键的输入重新映射到JTextComponent的最佳方法?_Java_Swing_Input_Keylistener_Jtextcomponent - Fatal编程技术网

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

Java 将某些字符/键的输入重新映射到JTextComponent的最佳方法?,java,swing,input,keylistener,jtextcomponent,Java,Swing,Input,Keylistener,Jtextcomponent,我正在开发一个JTextPane,它的工作原理(几乎)与stackoverflow上的标签输入字段完全相同。为此,我将在用户点击enter、tab或space时将文本转换为组件。当然,我不希望这些字符中的任何一个真正被输入到文本窗格中。我找到了这个解决方案,SSCCE: import java.awt.Color; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.B

我正在开发一个
JTextPane
,它的工作原理(几乎)与stackoverflow上的标签输入字段完全相同。为此,我将在用户点击enter、tab或space时将文本转换为组件。当然,我不希望这些字符中的任何一个真正被输入到文本窗格中。我找到了这个解决方案,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);
    }
}
点击“制表符”通常会导致插入制表符,点击“回车”通常会导致输入换行符,点击“空格”也会导致输入空格。奇怪的是,我的代码阻止了换行符和制表符的输入,但仍然允许在执行预期操作时正常输入空格

  • 为什么这些键的这种方法表现不同

  • 如何阻止空间被进入?(以后我可能想将此行为扩展到逗号等。)

  • 如何以最佳方式控制
    JTextComponent
    中某些字符和按键的行为?我已经看到了建议使用
    keystener
    ,但我也看到了Rob Camick指出的为什么不应该使用
    keystener
    。那么,我应该使用
    文档过滤器
    ,还是用它来打破轮子上的蝴蝶

  • 这是构建这种标记输入字段的最佳方法吗

  • 这将处理空格字符的按键事件

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

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

    看看这个特别行动的名字“无”。@trashgood我读过,但我的意思是,如果我不想让钥匙引起任何其他行为(这就是我想要的),那么我就不能使用“无”行动。但关键是我没有使用“none”操作,我已经使用了一个正确命名的操作。也许可以使用
    文档监听器
    ?@trashgod。为此,我需要更好地理解这一点。你能给我指一个教程或什么的吗?在那里我可以理解在用户点击一个键和以编程方式开始的预期动作之间展开的事件的确切链条?请参阅和其他Aha,“如果未指定
    键入的
    按下的
    释放的
    ,则假定
    按下的
    。”这回答了我的第二和第三个问题,但它是否回答了第一个问题?关键是,我以相同的方式注册所有三个键的事件(假设按下了
    ),但它们的行为不同,因为实际上没有键入制表符或换行符。我可以理解,如果新行的工作方式不同,因为它在不同的系统上不是同一个字符,但是选项卡应该是,对吗?@SheridanVespo,所有键的行为都是相同的,也就是说,您的finalizeTag操作被调用。当您按下空格键时,还会生成一个keyTyped事件,该事件实际上是在finalizeTag操作执行后将“”添加到文档中的事件。Tab键和Enter键不会生成keyTyped事件,因此不会向文档中添加任何内容。
    this.getInputMap().put(KeyStroke.getKeyStroke(' '), "finalizeTag");