/**
* Copyright (C) 2015 Valkyrie RCP
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.valkyriercp.form.binding.swing.text;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
import java.util.regex.Pattern;
/**
* This DocumentFactory will create a Document which holds a {@link java.util.regex.Pattern}. This Pattern is then used
* to verify each character that is inserted. This makes it possible to eg. allow only alfanumeric. Note
* that if you need a specific sequence of characters, you probably need a formatted textField with formatter
* instead.
*
* @author Lieven Doclo
* @author Jan Hoskens
*/
public class RegExDocumentFactory implements DocumentFactory {
/** Pattern to use in the RegExDocument. */
private String characterPattern;
/** Converting to uppercase letters? */
private boolean convertToUppercase;
/** Default constructor sets the pattern to use '.'. */
public RegExDocumentFactory() {
this(".");
}
/**
* Construct a RegExDocumentFactory with the given pattern.
*
* @param characterPattern the pattern to use.
*/
public RegExDocumentFactory(String characterPattern) {
this(characterPattern, false);
}
/**
* Construct a RegExDocumentFactory with the given pattern and convert to uppercase if requested.
*
* @param characterPattern the pattern to use.
* @param convertToUppercase if <code>true</code> convert all letters to uppercase.
*/
public RegExDocumentFactory(String characterPattern, boolean convertToUppercase) {
this.characterPattern = characterPattern;
this.convertToUppercase = convertToUppercase;
}
/**
* Returns the pattern that is used by this RegExDocumentFactory.
*
* @return the pattern.
*/
public String getCharacterPattern() {
return characterPattern;
}
/**
* Set the pattern to be used by this RegExDocumentFactory.
*
* @param characterPattern the pattern.
*/
public void setCharacterPattern(String characterPattern) {
this.characterPattern = characterPattern;
}
/**
* Returns <code>true</code> if the Document should convert all lowercase letters to uppercase.
*
* @return <code>true</code> if lowercase is converted to uppercase.
*/
public boolean isConvertToUppercase() {
return convertToUppercase;
}
/**
* Set to <code>true</code> if all lowercase letters should be converted to uppercase.
*
* @param convertToUppercase set to <code>true</code> if conversion should happen.
*/
public void setConvertToUppercase(boolean convertToUppercase) {
this.convertToUppercase = convertToUppercase;
}
/** {@inheritDoc} */
public Document createDocument() {
return new RegExDocument(getCharacterPattern(), isConvertToUppercase());
}
private static class RegExDocument extends PlainDocument {
private final Pattern pattern;
private final boolean convertToUppercase;
public RegExDocument(String stringPattern, boolean convertToUppercase) {
this.pattern = Pattern.compile(stringPattern, Pattern.DOTALL);
this.convertToUppercase = convertToUppercase;
}
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
if (str == null) {
return;
}
char[] upper = str.toCharArray();
StringBuilder builder = new StringBuilder();
char character;
for (int i = 0; i < upper.length; i++)
{
if (convertToUppercase)
character = Character.toUpperCase(upper[i]);
else
character = upper[i];
if (pattern.matcher(Character.toString(character)).find()) {
builder.append(character);
}
}
super.insertString(offs, builder.toString(), a);
}
}
}