My gut approach is to use the DocumentFilter and modify the Regex you're testing against based on how long your test string is. So if your test string is 10 characters long, the regex you'd use to test it is "(\\d{2})-bk\\d{3}\\."
or "\\d\\d\\d-bk\\d\\d\\d\\d\\."
. This would pass "123-bk0001."
, but fail "123-bk000a."
.
It would take some customization for each regex you would want to process (for example placing the parenthesis in the correct spot in the regex based on the length of the test string), but I don't think there's a way to make a regex dynamic based on length (which is what you're after).
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);
}
}