尝试使用按键侦听器 [英] Trying to use key Listener
问题描述
我有一个实现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
,例如数...
- 您不能保证在听众被激活的顺序,这是完全有可能的事件可能被消耗达到你或内容还没有被添加到该字段的
文件前code>
- 当你将文本粘贴到该领域它没有考虑到会发生什么
- 这可能导致基因突变例外,当你试图去改变它的文档进行了更新......
仅举几
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 aDocumentFilter
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屋!