尝试使用按键侦听器 [英] Trying to use key Listener

查看:269
本文介绍了尝试使用按键侦听器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个实现keyListener的程序。我试图做的是只允许数字,退格键,小数点键和后退箭头键为pressed。一切正常,除非我pressed后面箭头键它删除我input`号码

 公共无效调用keyReleased(KeyEvent的E){        尝试{
如果(Character.isDigit(e.getKeyChar())及!&放大器;!'。'e.getKeyChar()=安培;&放大器; e.getKeyChar()= e.VK_BACK_SPACE&放大器;!&放大器; e.getKeyChar() != KeyEvent.VK_LEFT){                字符串输入= inputIncome.getText();
                inputIncome.setText(input.substring(input.length() - 1));
            }        }
        赶上(例外ARG){        }`


解决方案

的KeyListener 规则...


  • 请不要使用的KeyListener 对于不要求重点被激活,即使在当时,用的键绑定而不是

  • 请不要使用的KeyListener 在文本组件,使用的 的DocumentFilter 而不是

在此基础上,你似乎改变的内容,我的假设是,一个的JTextField 或文本组件,您应该使用<$ C $事实 C>的DocumentFilter 过滤的变化被送到田间地头文件,例如...

 进口java.awt.EventQueue中;
进口java.awt.GridBagLayout中;
进口javax.swing.JFrame中;
进口javax.swing.JTextField中;
进口javax.swing.UIManager中;
进口javax.swing.UnsupportedLookAndFeelException;
进口javax.swing.text.AbstractDocument中;
进口javax.swing.text.AttributeSet;
进口javax.swing.text.BadLocationException;
进口javax.swing.text.Document中;
进口javax.swing.text.DocumentFilter;公共类DocumentFilterExample {    公共静态无效的主要(字串[] args){
        新DocumentFilterExample();
    }    公共DocumentFilterExample(){
        EventQueue.invokeLater(新的Runnable(){
            @覆盖
            公共无效的run(){
                尝试{
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                }赶上(ClassNotFoundException的| InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException前){
                }                JTextField的领域=新的JTextField(10);
                ((是AbstractDocument)field.getDocument())setDocumentFilter(新DecimalDocumentFilter())。                JFrame的帧=新的JFrame(测试);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(新的GridBagLayout());
                frame.add(场);
                frame.pack();
                frame.setLocationRelativeTo(NULL);
                frame.setVisible(真);
            }
        });
    }    公共类DecimalDocumentFilter扩展的DocumentFilter {        @覆盖
        公共无效insertString(DocumentFilter.FilterBypass FB,诠释抵消,
                字符串文本的AttributeSet attr)使用
                抛出BadLocationException的{            文档的文档= fb.getDocument();
            布尔hasDot = doc.getText(0,doc.getLength())含有(。);
            StringBuilder的缓冲=新的StringBuilder(文本);
            的for(int i = buffer.length() - 1; I&GT; = 0;我 - ){
                炭CH = buffer.charAt(ⅰ);
                如果(!Character.isDigit(CH)){
                    如果((CH ==&放'。';&安培;!hasDot)){
                        hasDot =真;
                    }其他{
                        buffer.deleteCharAt(ⅰ);
                    }
                }
            }
            super.insertString(FB,偏移,buffer.toString(),attr)使用;
        }        @覆盖
        公共无效替换(DocumentFilter.FilterBypass FB,
                的int抵消,诠释长度,串串,AttributeSet中的attr)使用抛出BadLocationException的{
            如果(长度大于0){
                fb.remove(偏移,长度);
            }
            insertString(FB,偏移,字符串attr)使用;
        }
    }}

这是基于例子这里

有原因以这种方式不使用的KeyListener ,例如数...


  • 您不能保证在听众被激活的顺序,这是完全有可能的事件可能被消耗达到你或内容还没有被添加到该字段的文件

  • 当你将文本粘贴到该领域它没有考虑到会发生什么

  • 这可能导致基因突变例外,当你试图去改变它的文档进行了更新......

仅举几

I have a program that implements keyListener. What I'm trying to do is only allow digits, backspace key, decimal key, and back arrow key to be pressed. Everything works except when I pressed the back arrow key it deletes the numbers I input`

public void keyReleased(KeyEvent e) {

        try{
if(!Character.isDigit(e.getKeyChar()) && e.getKeyChar() != '.' && e.getKeyChar() != e.VK_BACK_SPACE && e.getKeyChar() != KeyEvent.VK_LEFT){

                String input = inputIncome.getText();
                inputIncome.setText(input.substring(input.length()-1));  
            }

        }
        catch(Exception arg){

        }`

解决方案

KeyListener rules...

  • Don't use KeyListener for components which don't require focus to be activated, even then, use Key Bindings instead
  • Don't use KeyListener on text components, use a DocumentFilter instead

Based on the fact that you seem to be changing the contents of, what I assume is, a JTextField or text component, you should be using a DocumentFilter to filter the changes been sent to the fields Document, for example...

import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.DocumentFilter;

public class DocumentFilterExample {

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

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

                JTextField field = new JTextField(10);
                ((AbstractDocument)field.getDocument()).setDocumentFilter(new DecimalDocumentFilter());

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(field);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class DecimalDocumentFilter extends DocumentFilter {

        @Override
        public void insertString(DocumentFilter.FilterBypass fb, int offset,
                String text, AttributeSet attr)
                throws BadLocationException {

            Document doc = fb.getDocument();
            boolean hasDot = doc.getText(0, doc.getLength()).contains(".");
            StringBuilder buffer = new StringBuilder(text);
            for (int i = buffer.length() - 1; i >= 0; i--) {
                char ch = buffer.charAt(i);
                if (!Character.isDigit(ch)) {
                    if ((ch == '.' && !hasDot)) {
                        hasDot = true;
                    } else {
                        buffer.deleteCharAt(i);
                    }
                }
            }
            super.insertString(fb, offset, buffer.toString(), attr);
        }

        @Override
        public void replace(DocumentFilter.FilterBypass fb,
                int offset, int length, String string, AttributeSet attr) throws BadLocationException {
            if (length > 0) {
                fb.remove(offset, length);
            }
            insertString(fb, offset, string, attr);
        }
    }

}

This is based on the examples here.

There are number of reasons for not using a KeyListener in this way, for example...

  • You can't guarantee the order in which the listeners are activated, it's entirely possible that the event may be consumed before it reaches you or the content has not yet been added to the field's Document
  • It doesn't take into account what happens when you paste text into the field
  • It could cause a mutation exception as the document is been updated while you're trying to change it...

Just to name a few

这篇关于尝试使用按键侦听器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆