Swing/NumericTextField のバックアップの現在との差分(No.19)
- 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 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();
((AbstractDocument) textField3.getDocument()).setDocumentFilter(new IntegerDocumentFilter());
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));
((JSpinner.NumberEditor) spinner.getEditor()).getFormat().setGroupingUsed(false);
spinner.setValue(5000);
View in GitHub: Java, Kotlin解説
-
1
:JTextField
+InputVerifier
解説
-
1
:JTextField
+InputVerifier
- Validating with Input Verifiers
-
InputVerifier
を継承するIntegerInputVerifier
を作成し、これをJComponent#setInputVerifier
メソッドで設定しています。 - 別コンポーネントにフォーカスが移動するときに、数値かどうか評価します。
- 数値以外、または結果が範囲外となる場合、テキストは変化せず
beep
音が鳴り、フォーカス移動がキャンセルされます。 -
InputVerifier
を継承するIntegerInputVerifier
を作成し、これをJComponent#setInputVerifier(...)
メソッドで設定 - 別コンポーネントにフォーカスが移動するときに数値かどうか評価する
- 数値以外、または結果が範囲外となる場合、テキストは変化せず
beep
音が鳴りフォーカス移動がキャンセルされる
#spandel
class IntegerInputVerifier extends InputVerifier{
#spanend
#spanadd
class IntegerInputVerifier extends InputVerifier {
#spanend
@Override public boolean verify(JComponent c) {
boolean verified = false;
JTextField textField = (JTextField) c;
try {
Integer.parseInt(textField.getText());
verified = true;
} catch (NumberFormatException e) {
UIManager.getLookAndFeel().provideErrorFeedback(c);
//Toolkit.getDefaultToolkit().beep();
// Toolkit.getDefaultToolkit().beep();
}
return verified;
}
}
-
2
:JTextField
+Custom Document
-
2
:JTextField
+Custom Document
- Validating with a Custom Document
-
PlainDocument
を継承するIntegerDocument
を作成し、これをJTextComponent#setDocument
メソッドで設定しています。 - キー入力、文字列のペーストが行われたときに、数値かどうか評価します。
- 入力が数値以外、または結果が範囲外となる場合、
beep
音が鳴り、テキストは変化しません。 -
PlainDocument
を継承するIntegerDocument
を作成し、これをJTextComponent#setDocument(...)
メソッドで設定 - キー入力、文字列のペーストが行われたときに数値かどうか評価する
- 入力が数値以外、または結果が範囲外となる場合、
beep
音が鳴りテキストは変化しない
class IntegerDocument extends PlainDocument {
int currentValue = 0;
public IntegerDocument() {
super();
}
#spanadd
#spanend
public int getValue() {
return currentValue;
}
#spanadd
#spanend
@Override public void insertString(int offset, String str, AttributeSet attributes)
throws BadLocationException {
if (str == null) {
return;
} else {
String newValue;
int length = getLength();
if (length == 0) {
newValue = str;
} 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);
}
}
#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 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 {
int newValue = Integer.parseInt(proposedValue);
return newValue;
} catch (NumberFormatException e) {
throw new BadLocationException(proposedValue, offset);
}
} else {
return 0;
}
}
}
-
3
:JTextField
+DocumentFilter
-
3
:JTextField
+DocumentFilter
- Validating with a Document Filter
-
DocumentFilter
を継承するIntegerDocumentFilter
を作成し、これをAbstractDocument#setDocumentFilter
メソッドで設定しています。 -
別コンポーネントにフォーカスが移動するときに、数値かどうか評価します。 - キー入力、文字列のペーストが行われたときに、数値かどうか評価します。
- 入力が数値以外、または結果が範囲外となる場合、
beep
音が鳴り、テキストは変化しません。 -
DocumentFilter
を継承するIntegerDocumentFilter
を作成し、これをAbstractDocument#setDocumentFilter(...)
メソッドで設定 - キー入力、文字列のペーストが行われたときに数値かどうか評価する
- 入力が数値以外、または結果が範囲外となる場合、
beep
音が鳴りテキストは変化しない
class IntegerDocumentFilter extends DocumentFilter {
//int currentValue = 0;
// int currentValue = 0;
@Override public void insertString(DocumentFilter.FilterBypass fb,
int offset, String string, AttributeSet attr) throws BadLocationException {
if (string == null) {
return;
} else {
replace(fb, offset, 0, string, attr);
}
}
#spanadd
#spanend
@Override public void remove(DocumentFilter.FilterBypass fb, int offset, int length)
throws BadLocationException {
replace(fb, offset, length, "", null);
}
#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 newValue = before + (text == null ? "" : text) + after;
//currentValue =
checkInput(newValue, offset);
fb.replace(offset, length, text, attrs);
}
#spanadd
#spanend
private static int checkInput(String proposedValue, int offset)
throws BadLocationException {
int newValue = 0;
if (proposedValue.length() > 0) {
try {
newValue = Integer.parseInt(proposedValue);
} 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
#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
- How to Use Formatted Text Fields
- JSpinnerで無効な値の入力を許可しない