私の直感的なアプローチは、DocumentFilterを使用し、テスト文字列の長さに基づいてテスト対象の正規表現を変更することです。したがって、テスト文字列の長さが10文字の場合、テストに使用する正規表現はまたは"(\\d{2})-bk\\d{3}\\."
です"\\d\\d\\d-bk\\d\\d\\d\\d\\."
。これは成功します"123-bk0001."
が、失敗し"123-bk000a."
ます。
処理する正規表現ごとにカスタマイズが必要になります(たとえば、テスト文字列の長さに基づいて正規表現の正しい場所に括弧を配置するなど)が、正規表現を動的にする方法はないと思います。長さに基づいて(これはあなたが求めているものです)。
import javax.swing.*;
import javax.swing.text.*;
public class JTextFieldSuperVerified extends Box{
public JTextFieldSuperVerified() {
super(BoxLayout.Y_AXIS);
final JTextField textBox = new JTextField(20);
((AbstractDocument)textBox.getDocument()).setDocumentFilter(new DocumentFilter(){
public void insertString(DocumentFilter.FilterBypass fb,int offset,String string,AttributeSet attr) throws BadLocationException{
StringBuilder newString = new StringBuilder(textBox.getText());
//Recreate the insert for testing
newString.insert(offset, string);
if(verifyText(newString.toString())){
fb.insertString(offset, string, attr);
}
}
public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException{
StringBuilder newString = new StringBuilder(textBox.getText());
//Recreate the delete for testing
newString.delete(offset, offset + length);
if(verifyText(newString.toString())){
fb.remove(offset, length);
}
}
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException{
StringBuilder newString = new StringBuilder(textBox.getText());
//Recreate the replace for testing
newString.replace(offset, offset + length, text);
if(verifyText(newString.toString())){
fb.replace(offset, length, text, attrs);
}
}
//make sure the change is allowed
public boolean verifyText(String s){
boolean result = true;
//Our basic regex to test
StringBuilder regexPattern = new StringBuilder("\\d\\d\\d-bk\\d\\d\\d\\d\\.\\1");
if(s.length() < 15){
//How we modify the regex based on how long the string we're testing is
if(s.length() < 4)
regexPattern.delete(s.length() * 2, regexPattern.length());
else if(s.length() < 7)
regexPattern.delete(s.length() + 3, regexPattern.length());
else if(s.length() < 12)
regexPattern.delete((s.length() - 3) * 2 + 3, regexPattern.length());
else if(s.length() < 15){
regexPattern.insert((s.length() - 11) * 2, ')');
regexPattern.insert(0, '(');
}
System.out.println(regexPattern.toString());
result = s.matches(regexPattern.toString());
}else{
//Fail everything over 14 chars
result = false;
}
return result;
}
});
add(textBox);
}
public static void main(String[] args){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JTextFieldSuperVerified());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}