http://terai.xrea.jp/Swing/NumericTextField.html
!!方法1 入力制限機能付き JTextField
DocumentとInputVerifier、FocusListener を使って、
・長さチェック
・パッディング
・IM制御
の機能を持ったTextFieldを実装する。
{{code Java,
package tools.gui;
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
import java.util.*;
import java.awt.event.*;
public class JTextFieldEx extends JTextField implements FocusListener {
final public static int PADDING_NO = 0;
final public static int PADDING_RIGHT = 1;
final public static int PADDING_LEFT = 2;
public static final int IM_NONE = 0;
public static final int IM_HIRAGANA = 1;
public static final int IM_HALFKANA = 2;
public static final int IM_FULLASCII = 3;
public static final int IM_OFF = 4;
private static final Character.Subset[] SUBSET_OFF = null;
private static final Character.Subset[] SUBSET_HIRAGANA = new Character.Subset[] {java.awt.im.InputSubset.KANJI};
private static final Character.Subset[] SUBSET_HALFKANA = new Character.Subset[] {java.awt.im.InputSubset.HALFWIDTH_KATAKANA};
private static final Character.Subset[] SUBSET_FULLASCII = new Character.Subset[] {java.awt.im.InputSubset.FULLWIDTH_LATIN};
private int imType = IM_NONE;
private int length;
private int padType;
private boolean blnPadEmpty;
private LengthInputVerifier verifier;
public JTextFieldEx() {
this("");
}
public JTextFieldEx(String text) {
this(text, 10, 256);
}
public JTextFieldEx(String text, int column, int length) {
super(text, column);
this.imType = IM_NONE;
this.length = length;
this.padType = PADDING_NO;
this.blnPadEmpty = false;
this.verifier = new LengthInputVerifier();
this.setDocument(new LengthDocument());
this.setInputVerifier(verifier);
addFocusListener(this);
}
public void setPadding(char c, int padType) {
this.padType = padType;
verifier.setPadChar(c);
}
public void setPadding(char c) {
setPadding(c, PADDING_LEFT);
}
public void setPaddingWhenEmpty(boolean blnPadEmpty) {
this.blnPadEmpty = blnPadEmpty;
}
public int getLength() {
return length;
}
public void setLength(int newValue) {
this.length = newValue;
}
public int getImType() {
return imType;
}
public void setImType(int newValue) {
this.imType = newValue;
}
public void focusGained(FocusEvent e) {
if (imType != IM_NONE) {
Character.Subset[] subsets = SUBSET_OFF;
switch (imType) {
case IM_HIRAGANA:
subsets = SUBSET_HIRAGANA;
break;
case IM_HALFKANA:
subsets = SUBSET_HALFKANA;
break;
case IM_FULLASCII:
subsets = SUBSET_FULLASCII;
break;
}
getInputContext().setCharacterSubsets(subsets);
}
}
public void focusLost(FocusEvent e) {
if (imType != IM_NONE) {
getInputContext().setCharacterSubsets(SUBSET_OFF);
}
}
private class LengthDocument extends PlainDocument {
public void insertString(int offs, String str, AttributeSet a)
throws BadLocationException {
if (getLength() >= length) {
return;
}
super.insertString(offs, str, a);
}
}
private class LengthInputVerifier extends InputVerifier {
private char padChar;
private String padString;
public LengthInputVerifier() {
setPadChar(' ');
}
private void createPadString() {
char[] c = new char[length];
Arrays.fill(c, padChar);
padString = new String(c);
}
private void setPadChar(char padChar) {
this.padChar = padChar;
createPadString();
}
public boolean verify(JComponent c) {
JTextComponent txtcomp = (JTextComponent)c;
String inputtext = txtcomp.getText();
int textlength = inputtext.length();
// 空文字をパッディングしない場合
if (!blnPadEmpty && textlength == 0) {
return true;
}
if (textlength == length) {
return true;
}
boolean verified = false;
try {
if (textlength > length) {
txtcomp.setText(inputtext.substring(0, length));
} else {
if (padType == PADDING_LEFT) {
inputtext = padString + inputtext;
textlength = inputtext.length();
txtcomp.setText(inputtext.substring(textlength - length));
} else if (padType == PADDING_RIGHT) {
inputtext = inputtext + padString;
txtcomp.setText(inputtext.substring(0, length));
}
}
verified = true;
} catch (NumberFormatException e) {
UIManager.getLookAndFeel().provideErrorFeedback(c);
//Toolkit.getDefaultToolkit().beep();
}
// if (!verified){
// JOptionPane.showMessageDialog(c,"エラーです");
// }
return verified;
}
}
}
}}
!!方法2 JTextField + InputVerifier
方法1が大がかりで嫌な場合は、方法2、方法3を使う。
InputVerifierはコンポーネントを抜けるときにチェックされる。
{{code Java,
class IntegerInputVerifier extends InputVerifier{
@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();
}
return verified;
}
}
}}
!!方法3 JTextField + Custom Document
Document は入力中にチェックされる。
{{code Java,
class IntegerDocument extends PlainDocument {
int currentValue = 0;
public IntegerDocument() {
super();
}
public int getValue() {
return currentValue;
}
@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);
}
}
@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);
}
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;
}
}
}}
{{category2 プログラミング言語,Java}}