Skip to content
Snippets Groups Projects
Commit 1e6aefcc authored by Raphael GIRARDOT's avatar Raphael GIRARDOT
Browse files

- new filtered documents (useful for SCAN-941)

- some code refactoring
parent 5d84c777
Branches
Tags
No related merge requests found
/*
* This file is part of SwingUtilities.
*
* SwingUtilities is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* SwingUtilities is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License along with SwingUtilities. If not, see
* <https://www.gnu.org/licenses/>.
*/
package fr.soleil.lib.project.swing.text;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
/**
* A {@link PlainDocument} that filter received strings.
*
* @author Rapha&euml;l GIRARDOT
*/
public abstract class AFilteredDocument extends PlainDocument {
private static final long serialVersionUID = 3790757385170435708L;
// This allows to temporarily deactivate the validation, useful for setting text that doesn't match
private boolean enabled = true;
protected AFilteredDocument() {
super();
}
/**
* Builds a {@link StringBuilder} containing the filtered string value, from given {@link String} at given starting
* offset in this document.
*
* @param str The {@link String}.
* @param offs The starting offset &ge; 0.
* @return A {@link StringBuilder}, never <code>null</code>.
*/
protected abstract StringBuilder buildFilteredValue(String str, int offs);
/**
* Returns whether text validation is turned on.
*
* @return true if the input validation is turned on.
*/
protected boolean isEnabled() {
return enabled;
}
/**
* Enables or disables the validation. This is useful for setting text that would not match.
*
* @param enabled true to enable validation, false otherwise.
*/
protected void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@Override
public final void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
if (enabled) {
StringBuilder sb = buildFilteredValue(str, offs);
if (sb.length() > 0) {
super.insertString(offs, sb.toString(), a);
sb.delete(0, sb.length());
}
} else {
super.insertString(offs, str, a);
}
}
}
......@@ -14,59 +14,27 @@
*/
package fr.soleil.lib.project.swing.text;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
/**
* Used to filter textfields with number formats
*
* @author Rapha&euml;l GIRARDOT
*/
public class DocumentNumber extends PlainDocument {
private static final long serialVersionUID = 7939323980254285155L;
public class DocumentNumber extends AFilteredDocument {
private boolean allowNegativeValues = false;
private boolean allowFloatValues = false;
private boolean allowScientificValues = false;
// this allows to temporarily deactivate the validation, useful for setting text that doesn't
// match
private boolean enabled = true;
public DocumentNumber() {
super();
}
/**
* Numbers only
* Returns whether there is an 'e' or an 'E' before given index in document.
*
* @param index The index.
* @return A <code>boolean</code>.
*/
@Override
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
if (enabled) {
StringBuilder sb = new StringBuilder();
char car;
boolean e = false;
for (int i = 0; i < str.length(); i++) {
car = str.charAt(i);
if (Character.isDigit(car)) {
sb.append(car);
} else if (Character.toLowerCase(car) == 'e' && isAllowScientificValues()) {
e = true;
sb.append(car);
} else if (car == '.' && isAllowFloatValues()) {
sb.append(car);
} else if (car == '-' && (isAllowNegativeValues() || e || hasScientificBeforeIndex(offs))) {
sb.append(car);
}
}
super.insertString(offs, sb.toString(), a);
} else {
super.insertString(offs, str, a);
}
}
protected boolean hasScientificBeforeIndex(int index) {
boolean scientific;
if (index < 0) {
......@@ -124,20 +92,26 @@ public class DocumentNumber extends PlainDocument {
this.allowScientificValues = allowScientificValues;
}
/**
* @return true if the input validation is turned on
*/
public boolean isEnabled() {
return enabled;
// Numbers only
@Override
protected StringBuilder buildFilteredValue(String str, int offs) {
StringBuilder sb = new StringBuilder();
char car;
boolean e = false;
for (int i = 0; i < str.length(); i++) {
car = str.charAt(i);
if (Character.isDigit(car)) {
sb.append(car);
} else if (Character.toLowerCase(car) == 'e' && isAllowScientificValues()) {
e = true;
sb.append(car);
} else if (car == '.' && isAllowFloatValues()) {
sb.append(car);
} else if (car == '-' && (isAllowNegativeValues() || e || hasScientificBeforeIndex(offs))) {
sb.append(car);
}
/**
* Enable or disable the validation. This is useful for setting text that would not match.
*
* @param enabled true to enable validation, false otherwise
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
return sb;
}
}
/*
* This file is part of SwingUtilities.
*
* SwingUtilities is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* SwingUtilities is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License along with SwingUtilities. If not, see
* <https://www.gnu.org/licenses/>.
*/
package fr.soleil.lib.project.swing.text;
import java.util.Arrays;
import javax.swing.text.PlainDocument;
/**
* A {@link PlainDocument} that may accept only some characters, or refuse these characters.
*
* @author Rapha&euml;l GIRARDOT
*/
public class FilteredCharactersDocument extends AFilteredDocument {
private static final long serialVersionUID = 1012512913754903130L;
private static final char[] EMPTY = new char[0];
private char[] filteredCharacters;
private boolean escaped;
public FilteredCharactersDocument() {
super();
}
/**
* Returns whether a character belongs to a list of filtered characters.
*
* @param character The character.
* @param filteredCharacters The list of filtered characters, represented by an ellipse.
* @return A <code>boolean</code>. <code>true</code>if the character belongs to the list, <code>false</code>
* otherwise.
*/
protected boolean isFiltered(char character, char... filteredCharacters) {
boolean filtered = false;
for (char c : filteredCharacters) {
if (c == character) {
filtered = true;
break;
}
}
return filtered;
}
/**
* Returns the characters filtered by this {@link FilteredCharactersDocument}.
*
* @return A <code>char</code> array, never <code>null</code>.
*/
public char[] getFilteredCharacters() {
return filteredCharacters.clone();
}
/**
* Sets the characters filtered by this {@link FilteredCharactersDocument}.
*
* @param filteredCharacters The characters that should be filtered by this {@link FilteredCharactersDocument}.
*/
public void setFilteredCharacters(char... filteredCharacters) {
this.filteredCharacters = filteredCharacters == null ? EMPTY : filteredCharacters.clone();
}
/**
* Adds some characters in the list of filtered characters.
*
* @param characters The characters to add.
* @see #getFilteredCharacters()
* @see #setFilteredCharacters(char...)
*/
public void addFilteredCharacters(char... characters) {
if ((characters != null) && (characters.length > 0)) {
char[] filteredCharacters = this.filteredCharacters;
int count = 0, index = 0;
boolean[] allowed = new boolean[characters.length];
boolean valid;
for (char character : characters) {
valid = !isFiltered(character, filteredCharacters);
allowed[index++] = valid;
if (valid) {
count++;
}
}
if (count > 0) {
char[] result = Arrays.copyOf(filteredCharacters, filteredCharacters.length + count);
index = 0;
for (int i = 0; i < characters.length; i++) {
if (allowed[i]) {
result[filteredCharacters.length + index++] = characters[i];
}
}
this.filteredCharacters = result;
}
}
}
/**
* Returns whether the filtered characters are characters that should be escaped or whether these characters are the
* only accepted ones.
*
* @return A <code>boolean</code>:
* <ul>
* <li><code>true</code>: The filtered characters are characters that should be avoided in text.</li>
* <li><code>false</code>: The filtered characters are the only ones that should be accepted in text.</li>
* </ul>
* @see #setEscaped(boolean)
* @see #getFilteredCharacters()
* @see #setFilteredCharacters(char...)
* @see #addFilteredCharacters(char...)
*/
public boolean isEscaped() {
return escaped;
}
/**
* Sets whether the filtered characters are characters that should be escaped or whether these characters are the
* only accepted ones.
*
* @param escaped Whether the filtered characters are characters that should be escaped or whether these characters
* are the only accepted ones.
* <ul>
* <li><code>true</code>: The filtered characters are characters that should be avoided in text.</li>
* <li><code>false</code>: The filtered characters are the only ones that should be accepted in
* text.</li>
* </ul>
* @see #isEscaped()
* @see #getFilteredCharacters()
* @see #setFilteredCharacters(char...)
* @see #addFilteredCharacters(char...)
*/
public void setEscaped(boolean escaped) {
this.escaped = escaped;
}
@Override
protected StringBuilder buildFilteredValue(String str, int offs) {
char c;
char[] filteredCharacters = this.filteredCharacters;
boolean escaped = this.escaped;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
c = str.charAt(i);
if (isFiltered(c, filteredCharacters)) {
if (!escaped) {
sb.append(c);
}
} else if (escaped) {
sb.append(c);
}
}
return sb;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment