注意
lowerLimit と upperLimit の値を変更して流用して下さい。
どの文字を打とうとしても半角数字1~30しか入力できません。
DocumentFilterは内部クラスを作った方が良いです。
※おそらく、このアルゴリズムは他の言語に応用可能。
ソースコード
Example
JTextField textField = new JTextField();
((PlainDocument)textField.getDocument()).setDocumentFilter(new DocumentFilter() {
/**
* 数値入力時、1から30までに制限
* @param fb
* @param offset カーソル位置
* @param length 置換文字数
* @param text 置換文字列
* @param attrs fb.getDocument().getDefaultRootElement().getAttributes()と同じ
*/
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)
throws BadLocationException
int lowerLimit = 1;
int upperLimit = 30;
int valueInput = 0;
try {
valueInput = Integer.parseInt(text);
} catch(Exception ex) {
// 入力値が数値以外、入力不可
return;
}
// 入力値が全角数字の場合、半角数値に自動変換
text = String.valueOf(valueInput);
// 元々1文字も入力されていない場合
if(fb.getDocument().getLength() == 0) {
// 1~9の文字のみ入力可能
if(valueInput != 0) {
super.insertString(fb, offset, text, attrs);
}
return;
}
// 元々文字が入力されていた場合
} else {
// 入力後の値の算出
String strAlready = fb.getDocument.getText(0, fb.getDocument().getLength());
int valueAlready = Integer.parseInt(strAlready);
int valueTotal = 0;
if(offset == 0) {
// Input Left
valueTotal = (int) (valueInput * Math.pow(10, strAlready.length()) + valueAlready);
} else if(offset == strAlready.length()) {
// Input Right
valueTotal = (int) (valueAlready * 10 + valueInput);
} else {
// Input Mid
int valueLeft = (int) ( Integer.parseInt(strAlready.substring(0, offset))
* Math.pow(10, strAlready.length()-offset+1) );
int valueAdd = (int) ( valueInput * Math.pow(10, strAlready.length()-offset) );
int valueRight = Integer.parseInt( strAlready.substring(offset, strAlready.length()) );
valueTotal = valueLeft + valueAdd + valueRight;
}
// 入力値を1から30までに制限
if(valueTotal > upperLimit) {
// 入力後の値 > 最大値
super.remove(fb, 0, strAlready.length()); // 元の文字をすべて削除
if(valueInput != 0) {
super.insertString(fb, 0, String.valueOf(valueInput), attrs); // 入力値設定
} else {
super.insertString(fb, 0, String.valueOf(upperLimit), attrs); // 最大値設定
}
} else if(valueTotal < lowerLimit) {
super.replace(fb, 0, strAlready.length(), String.valueOf(lowerLimit), attrs); // 最小値設定
} else {
super.replace(fb, offset, length, text, attrs); // 本来の値入力時のreplaceメソッド処理呼び出し
}
}
}
/**
* 値削除時、1より小さい値を入力不可に制限
* @param fb
* @param offset カーソル位置
* @param length 削除文字数
*/
@Override
public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
int lowerLimit = 1;
String strBefore = fb,getDocument.getText(0, fb.getDocument().getLength());
String strAfter = strBefore.substring(0, offset)
+ strBefore.substring(offset+length, fb.getDocument().getLength());
int afterValue = 0;
try {
afterValue = Integer.parseInt(strAfter);
} catch(Exception ex) {
// 入力値制御をしているため、エラーが起きるはずがない。
}
// 1より小さい値を設定不可
if(strAfter.length() == 0 || afterValue < lowerLimit) {
// 未入力や最小値より小さい値を設定した場合、最小値を設定
super.replace(fb, 0, strBefore.length(), String.valueOf(lowerLimit), fb.getDocument().getDefaultRootElement().getAttributes());
} else {
// 本来の値削除時のremoveメソッド処理呼び出し
super.remove(fb, offset, length);
}
}
});
これを書いた理由
どこにも書いていなかったから。