Swing/NumericTextField のバックアップの現在との差分(No.1)
TITLE:JTextFieldの入力を数値に制限する
JTextFieldの入力を数値に制限する
Posted by terai at 2008-06-09- category: swing folder: NumericTextField title: JTextFieldの入力を数値に制限する tags: [JTextField, JFormattedTextField, InputVerifier, DocumentFilter, PlainDocument] author: aterai pubdate: 2008-06-09T10:55:29+09:00 description: JTextFieldへのキー入力や貼り込みを数値のみに制限する方法をテストします。 image:
概要
JTextField
へのキー入力や貼り込みを数値のみに制限する方法をテストします。ソースコードは、Validating Text and Filtering Documents and Accessibility and the Java Access Bridge Tech Tipsからの引用です。
Screenshot
Advertisement
概要
JTextFieldへの入力を数値のみに制限します。ソースコードは、Validating Text and Filtering Documents and Accessibility and the Java Access Bridge Tech Tipsからの引用です。- &jnlp;
- &jar;
- &zip;
#screenshot
サンプルコード
#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
JTextField textField1 = new JTextField("1000");
textField1.setHorizontalAlignment(JTextField.RIGHT);
textField1.setInputVerifier(new IntegerInputVerifier());
JTextField textField2 = new JTextField();
textField2.setDocument(new IntegerDocument());
textField2.setText("2000");
JTextField textField3 = new JTextField();
#spandel
((AbstractDocument)textField3.getDocument()).setDocumentFilter(new IntegerDocumentFilter());
#spanend
#spanadd
((AbstractDocument) textField3.getDocument()).setDocumentFilter(new IntegerDocumentFilter());
#spanend
textField3.setText("3000");
JFormattedTextField textField4 = new JFormattedTextField();
textField4.setFormatterFactory(new NumberFormatterFactory());
textField4.setHorizontalAlignment(JTextField.RIGHT);
textField4.setValue(4000);
JSpinner spinner = new JSpinner(new SpinnerNumberModel(0, 0, Integer.MAX_VALUE, 1));
#spandel
((JSpinner.NumberEditor)spinner.getEditor()).getFormat().setGroupingUsed(false);
#spanend
#spanadd
((JSpinner.NumberEditor) spinner.getEditor()).getFormat().setGroupingUsed(false);
#spanend
spinner.setValue(5000);
解説
- 1:JTextField + InputVerifier
- Validating with Input Verifiers
- InputVerifierを継承するIntegerInputVerifierを作成し、これをJComponent#setInputVerifierメソッドで設定しています。
- 別コンポーネントにフォーカスが移動するときに、数値かどうか評価します。
- 数値でない場合、テキストは変化せずbeep音が鳴り、フォーカス移動がキャンセルされます。
解説
-
1
:JTextField
+InputVerifier
- Validating with Input Verifiers
-
InputVerifier
を継承するIntegerInputVerifier
を作成し、これをJComponent#setInputVerifier(...)
メソッドで設定 - 別コンポーネントにフォーカスが移動するときに数値かどうか評価する
- 数値以外、または結果が範囲外となる場合、テキストは変化せず
beep
音が鳴りフォーカス移動がキャンセルされる
#spandel
class IntegerInputVerifier extends InputVerifier{
#spanend
@Override
public boolean verify(JComponent c) {
#spanadd
class IntegerInputVerifier extends InputVerifier {
#spanend
@Override public boolean verify(JComponent c) {
boolean verified = false;
JTextField textField = (JTextField)c;
try{
JTextField textField = (JTextField) c;
try {
Integer.parseInt(textField.getText());
verified = true;
}catch(NumberFormatException e) {
} catch (NumberFormatException e) {
UIManager.getLookAndFeel().provideErrorFeedback(c);
//Toolkit.getDefaultToolkit().beep();
// Toolkit.getDefaultToolkit().beep();
}
return verified;
}
}
- 2:JTextField + Custom Document
- Validating with a Custom Document
- PlainDocumentを継承するIntegerDocumentを作成し、これをJTextComponent#setDocumentメソッドで設定しています。
- キー入力、文字列のペーストが行われたときに、数値かどうか評価します。
- 入力が数値でない場合、beep音が鳴り、テキストは変化しません。
-
2
:JTextField
+Custom Document
- Validating with a Custom Document
-
PlainDocument
を継承するIntegerDocument
を作成し、これをJTextComponent#setDocument(...)
メソッドで設定 - キー入力、文字列のペーストが行われたときに数値かどうか評価する
- 入力が数値以外、または結果が範囲外となる場合、
beep
音が鳴りテキストは変化しない
class IntegerDocument extends PlainDocument {
int currentValue = 0;
public IntegerDocument() {
super();
}
#spanadd
#spanend
public int getValue() {
return currentValue;
}
@Override
public void insertString(int offset, String str, AttributeSet attributes) throws BadLocationException {
if(str==null) {
#spanadd
#spanend
@Override public void insertString(int offset, String str, AttributeSet attributes)
throws BadLocationException {
if (str == null) {
return;
}else{
} else {
String newValue;
int length = getLength();
if(length==0) {
if (length == 0) {
newValue = str;
}else{
} else {
String currentContent = getText(0, length);
StringBuffer currentBuffer = new StringBuffer(currentContent);
currentBuffer.insert(offset, str);
newValue = currentBuffer.toString();
}
currentValue = checkInput(newValue, offset);
super.insertString(offset, str, attributes);
}
}
@Override
public void remove(int offset, int length) throws BadLocationException {
#spanadd
#spanend
@Override public void remove(int offset, int length) throws BadLocationException {
int currentLength = getLength();
String currentContent = getText(0, currentLength);
String before = currentContent.substring(0, offset);
String after = currentContent.substring(length+offset, currentLength);
String after = currentContent.substring(length + offset, currentLength);
String newValue = before + after;
currentValue = checkInput(newValue, offset);
super.remove(offset, length);
}
#spanadd
#spanend
private int checkInput(String proposedValue, int offset) throws BadLocationException {
if(proposedValue.length()>0) {
try{
if (proposedValue.length() > 0) {
try {
int newValue = Integer.parseInt(proposedValue);
return newValue;
}catch(NumberFormatException e) {
} catch (NumberFormatException e) {
throw new BadLocationException(proposedValue, offset);
}
}else{
} else {
return 0;
}
}
}
- 3:JTextField + DocumentFilter
- Validating with a Document Filter
- DocumentFilterを継承するIntegerDocumentFilterを作成し、これをAbstractDocument#setDocumentFilterメソッドで設定しています。
- 別コンポーネントにフォーカスが移動するときに、数値かどうか評価します。
- 入力が数値でない場合、beep音が鳴り、テキストは変化しません。
-
3
:JTextField
+DocumentFilter
- Validating with a Document Filter
-
DocumentFilter
を継承するIntegerDocumentFilter
を作成し、これをAbstractDocument#setDocumentFilter(...)
メソッドで設定 - キー入力、文字列のペーストが行われたときに数値かどうか評価する
- 入力が数値以外、または結果が範囲外となる場合、
beep
音が鳴りテキストは変化しない
class IntegerDocumentFilter extends DocumentFilter {
//int currentValue = 0;
@Override
public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
if(string == null) {
// int currentValue = 0;
@Override public void insertString(DocumentFilter.FilterBypass fb,
int offset, String string, AttributeSet attr) throws BadLocationException {
if (string == null) {
return;
}else{
} else {
replace(fb, offset, 0, string, attr);
}
}
@Override
public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException {
#spanadd
#spanend
@Override public void remove(DocumentFilter.FilterBypass fb, int offset, int length)
throws BadLocationException {
replace(fb, offset, length, "", null);
}
@Override
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
#spanadd
#spanend
@Override public void replace(DocumentFilter.FilterBypass fb, int offset, int length,
String text, AttributeSet attrs) throws BadLocationException {
Document doc = fb.getDocument();
int currentLength = doc.getLength();
String currentContent = doc.getText(0, currentLength);
String before = currentContent.substring(0, offset);
String after = currentContent.substring(length+offset, currentLength);
String after = currentContent.substring(length + offset, currentLength);
String newValue = before + (text == null ? "" : text) + after;
//currentValue =
checkInput(newValue, offset);
fb.replace(offset, length, text, attrs);
}
private static int checkInput(String proposedValue, int offset) throws BadLocationException {
#spanadd
#spanend
private static int checkInput(String proposedValue, int offset)
throws BadLocationException {
int newValue = 0;
if(proposedValue.length() > 0) {
if (proposedValue.length() > 0) {
try {
newValue = Integer.parseInt(proposedValue);
}catch(NumberFormatException e) {
} catch (NumberFormatException e) {
throw new BadLocationException(proposedValue, offset);
}
}
return newValue;
}
}
- 4:JFormattedTextField + DefaultFormatterFactory
- How to Use Formatted Text Fields
- DefaultFormatterFactoryを継承するNumberFormatterFactoryを作成し、これをJFormattedTextField#setFormatterFactoryメソッドで設定しています。
- キー入力、文字列のペーストが行われたときに、数値かどうか評価します。
- 数値でない場合、テキストは以前の値にUndoされます。
-
4
:JFormattedTextField
+DefaultFormatterFactory
- How to Use Formatted Text Fields
-
DefaultFormatterFactory
を継承するNumberFormatterFactory
を作成し、これをJFormattedTextField#setFormatterFactory(...)
メソッドで設定 - 別コンポーネントにフォーカスが移動するときに数値かどうか評価する
- 数値以外の場合、テキストは以前の値に
Undo
される - 数値が範囲外となる場合、最小値、または最大値に調整される
#spandel
class NumberFormatterFactory extends DefaultFormatterFactory{
#spanend
private static NumberFormat amountEditFormat = NumberFormat.getNumberInstance();
private static NumberFormatter numberFormatter = new NumberFormatter();
static{
amountEditFormat.setGroupingUsed(false);
numberFormatter.setValueClass(Integer.class);
((NumberFormat)numberFormatter.getFormat()).setGroupingUsed(false);
}
public NumberFormatterFactory() {
super(numberFormatter, numberFormatter, numberFormatter);
}
#spanadd
class NumberFormatterFactory extends DefaultFormatterFactory {
#spanend
private static NumberFormatter numberFormatter = new NumberFormatter();
static {
numberFormatter.setValueClass(Integer.class);
((NumberFormat) numberFormatter.getFormat()).setGroupingUsed(false);
}
#spanadd
#spanend
public NumberFormatterFactory() {
super(numberFormatter, numberFormatter, numberFormatter);
}
}
- 5:JSpinner + SpinnerNumberModel
- JFormattedTextFieldの場合と同等です。
-
5
:JSpinner
+SpinnerNumberModel
-
JFormattedTextField
の場合と同等
-
参考リンク
- Validating Text and Filtering Documents and Accessibility and the Java Access Bridge Tech Tips
- How to Use Formatted Text Fields
参考リンク
- Validating Text and Filtering Documents and Accessibility and the Java Access Bridge Tech Tips
- How to Use Formatted Text Fields
- JSpinnerで無効な値の入力を許可しない