#java #swing #jframe #jtextfield #documentfilter
#java #swing #jframe #jtextfield #documentfilter
Вопрос:
Я пытаюсь создать тест по математике, и я только хочу, чтобы пользователь мог вводить числа, независимо от того, являются ли они отрицательными или положительными. Есть ли какой-либо способ сделать это? Я думал об использовании регулярных выражений, но я слышал, что они плохи в использовании. Я пытался использовать keylistener, но что тогда, если пользователь вставит? Я попытался проанализировать строку, чтобы получить целое число, но тогда отрицательный символ не будет работать.
Есть идеи?
package com.quiz.ui;
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class SSCCE {
private JFrame frame;
private JPanel contentPane;
private JTextField usernameField;
public static void main(String[] arguments) {
new SSCCE().construct();
}
public void construct() {
frame = new JFrame("Login");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(getContentPane());
frame.pack();
frame.setVisible(true);
}
public JPanel getContentPane() {
usernameField = new JTextField(5);
usernameField.addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent arg0) {
int keyCode = arg0.getKeyCode();
if ((keyCode > 47 amp;amp; keyCode < 58) || keyCode == 45) {
arg0.consume();
}
System.out.println(arg0.getKeyCode());
}
@Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
});
contentPane = new JPanel(new BorderLayout());
contentPane.add(usernameField);
return contentPane;
}
}
Ответ №1:
Используйте DocumentFilter:
NumberOnlyFilter.java:
import javax.swing.*;
import javax.swing.text.*;
import java.util.regex.*;
public class NumberOnlyFilter extends DocumentFilter
{
public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException
{
StringBuilder sb = new StringBuilder();
sb.append(fb.getDocument().getText(0, fb.getDocument().getLength()));
sb.insert(offset, text);
if(!containsOnlyNumbers(sb.toString())) return;
fb.insertString(offset, text, attr);
}
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attr) throws BadLocationException
{
StringBuilder sb = new StringBuilder();
sb.append(fb.getDocument().getText(0, fb.getDocument().getLength()));
sb.replace(offset, offset length, text);
if(!containsOnlyNumbers(sb.toString())) return;
fb.replace(offset, length, text, attr);
}
/**
* This method checks if a String contains only numbers
*/
public boolean containsOnlyNumbers(String text)
{
Pattern pattern = Pattern.compile("([ -]{0,1})?[\d]*");
Matcher matcher = pattern.matcher(text);
boolean isMatch = matcher.matches();
return isMatch;
}
}
и затем вы можете использовать его как:
((AbstractDocument)yourTxtField.getDocument()).setDocumentFilter(new NumberOnlyFilter());
Комментарии:
1. 1 У меня всегда возникает соблазн предварительно скомпилировать шаблон, но профилированное преимущество обычно незначительно.
2. Проблема с этим заключается в том, что символ
-
также должен быть разрешен.3. @Ron: Предложение Eng отличное (1 ), и вы можете легко использовать предложение Eng и разрешить, либо проанализировав строку, чтобы увидеть, является ли она подходящим числовым представлением, либо используя другую логику в фильтре.
4.
adjustLabel(...)
Метод не может быть найден.5. @Ron Ой, я всегда копирую этот код из своих старых файлов и забываю удалить
adjustLabel()
, извините 🙂
Ответ №2:
В качестве альтернативы, рассмотрите возможность проверки ввода с помощью InputVerifier
. Также может подойти форматированное текстовое поле.
Ответ №3:
Вы можете использовать Integer.parseInt(строка s, исходный код int), для десятичной системы счисления используйте 10 в качестве значения redix.
Комментарии:
1. Отрицательный символ не проходит проверку при использовании этого метода.
2. я не пробовал код, но в этой ссылке говорится, что он вернет отрицательное значение, [ссылка]( download.oracle.com/javase/1.4.2/docs/api/java/lang /… , int))