トップ 差分 一覧 ソース 置換 検索 ヘルプ PDF RSS ログイン

Swingコンポーネントで入力制限

http://terai.xrea.jp/Swing/NumericTextField.html

 方法1 入力制限機能付き JTextField

DocumentとInputVerifier、FocusListener を使って、
 ・長さチェック
 ・パッディング
 ・IM制御
の機能を持ったTextFieldを実装する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
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はコンポーネントを抜けるときにチェックされる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 は入力中にチェックされる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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;
    }
  }
[カテゴリ: プログラミング言語 > Java]

[通知用URL]



  • Hatenaブックマークに追加
  • livedoorクリップに追加
  • del.icio.usに追加
  • FC2ブックマークに追加

最終更新時間:2010年11月15日 22時02分52秒