package hirondelle.stocks.portfolio;
import java.util.*;
import java.util.regex.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import hirondelle.stocks.util.Util;
import hirondelle.stocks.util.Consts;
import hirondelle.stocks.util.Args;
import hirondelle.stocks.util.ui.UiUtil;
final class RegexInputVerifier extends InputVerifier {
RegexInputVerifier(Pattern aPattern, UseToolTip aUseToolTip){
Args.checkForContent( aPattern.pattern() );
fMatcher = aPattern.matcher(Consts.EMPTY_STRING);
fUseToolTip = aUseToolTip.getValue();
}
enum UseToolTip {
TRUE(true),
FALSE(false);
boolean getValue(){
return fToggle;
}
private boolean fToggle;
private UseToolTip(boolean aToggle){
fToggle = aToggle;
}
}
@Override public boolean shouldYieldFocus(JComponent aComponent){
boolean isValid = super.shouldYieldFocus(aComponent);
if (isValid){
}
else {
JTextComponent textComponent = (JTextComponent)aComponent;
notifyUserOfError(textComponent);
}
return true;
}
@Override public boolean verify(JComponent aComponent) {
boolean result = false;
JTextComponent textComponent = (JTextComponent)aComponent;
fMatcher.reset(textComponent.getText());
if (fMatcher.matches()) {
result = true;
}
return result;
}
static final String ERROR_MESSAGE_START = "INVALID: ";
private Matcher fMatcher;
private boolean fUseToolTip;
private static final String TEXT_FIELD = "^(\\S)(.){1,75}(\\S)$";
private static final String NON_NEGATIVE_INTEGER_FIELD = "(\\d){1,9}";
private static final String INTEGER_FIELD = "(-)?" + NON_NEGATIVE_INTEGER_FIELD;
private static final String NON_NEGATIVE_FLOATING_POINT_FIELD =
"(\\d){1,10}\\.(\\d){1,10}"
;
private static final String FLOATING_POINT_FIELD =
"(-)?" + NON_NEGATIVE_FLOATING_POINT_FIELD
;
private static final String NON_NEGATIVE_MONEY_FIELD = "(\\d){1,15}(\\.(\\d){2})?";
private static final String MONEY_FIELD = "(-)?" + NON_NEGATIVE_MONEY_FIELD;
static final RegexInputVerifier INTEGER =
new RegexInputVerifier(Pattern.compile(INTEGER_FIELD), UseToolTip.FALSE)
;
static final RegexInputVerifier NON_NEGATIVE_INTEGER =
new RegexInputVerifier(Pattern.compile(NON_NEGATIVE_INTEGER_FIELD), UseToolTip.FALSE)
;
static final RegexInputVerifier TEXT =
new RegexInputVerifier(Pattern.compile(TEXT_FIELD), UseToolTip.FALSE)
;
static final RegexInputVerifier FLOATING_POINT =
new RegexInputVerifier(Pattern.compile(FLOATING_POINT_FIELD), UseToolTip.FALSE)
;
static final RegexInputVerifier NON_NEGATIVE_FLOATING_POINT =
new RegexInputVerifier(
Pattern.compile(NON_NEGATIVE_FLOATING_POINT_FIELD), UseToolTip.FALSE
)
;
static final RegexInputVerifier MONEY =
new RegexInputVerifier(Pattern.compile(MONEY_FIELD), UseToolTip.FALSE)
;
static final RegexInputVerifier NON_NEGATIVE_MONEY =
new RegexInputVerifier(Pattern.compile(NON_NEGATIVE_MONEY_FIELD), UseToolTip.FALSE)
;
private void notifyUserOfError(JTextComponent aTextComponent){
if ( isShowingErrorMessage(aTextComponent) ){
}
else {
UiUtil.beep();
showErrorMessage(aTextComponent);
}
}
private boolean isShowingErrorMessage(JTextComponent aTextComponent){
return aTextComponent.getText().startsWith(ERROR_MESSAGE_START);
}
private void showErrorMessage(JTextComponent aTextComponent) {
StringBuilder message = new StringBuilder(ERROR_MESSAGE_START);
message.append("\"");
message.append(aTextComponent.getText());
message.append("\"");
if ( fUseToolTip ) {
message.append(aTextComponent.getToolTipText());
}
aTextComponent.setText(message.toString());
}
public static void main(String... aArgs){
showGuiForExercisingVerifier();
}
private static JFrame fFrame;
private static JTextField fRegexField;
private static JTextField fInputField;
private static void showGuiForExercisingVerifier(){
fFrame = new JFrame("Test Regular Expressions - javapractices.com");
fFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel content = new JPanel();
content.setLayout( new BoxLayout(content, BoxLayout.Y_AXIS) );
content.setBorder( UiUtil.getStandardBorder() );
content.add( getEditor() );
content.add( getCommandRow() );
fFrame.getContentPane().add( content );
UiUtil.centerAndShow( fFrame );
}
private static JComponent getEditor(){
final JPanel content = new JPanel();
content.setLayout( new GridBagLayout() );
GridBagConstraints constraints = UiUtil.getConstraints(0,0);
constraints.fill = GridBagConstraints.HORIZONTAL;
fRegexField = UiUtil.addSimpleEntryField(
content, "Regular Expression:", null,
KeyEvent.VK_R, constraints,
"Double backslashes are not needed. Set Regex to init."
);
constraints = UiUtil.getConstraints(1,0);
constraints.fill = GridBagConstraints.HORIZONTAL;
fInputField = UiUtil.addSimpleEntryField(
content, "Test Input:", null,
KeyEvent.VK_I, constraints,
"This text is verified versus the regular expression"
);
UiUtil.addVerticalGridGlue(content, 2);
return content;
}
private static JComponent getCommandRow(){
JButton setRegex = new JButton("Set Regex");
setRegex.setMnemonic(KeyEvent.VK_S);
setRegex.setToolTipText("Start testing input versus the above regular expression");
setRegex.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
setRegex();
}
});
JButton test = new JButton("Test");
test.setMnemonic(KeyEvent.VK_T);
test.setToolTipText("Exercises verifier by simply receiving focus");
test.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
}
});
JButton close = new JButton("Close");
close.setMnemonic(KeyEvent.VK_C);
close.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent event) {
fFrame.dispose();
}
});
java.util.List<JComponent> buttons = new ArrayList<>();
buttons.add(setRegex) ;
buttons.add(test);
buttons.add(close);
return UiUtil.getCommandRow( buttons );
}
private static void setRegex(){
Pattern regex = Pattern.compile(fRegexField.getText());
RegexInputVerifier verifier = new RegexInputVerifier(regex, UseToolTip.FALSE);
fInputField.setInputVerifier(verifier);
}
}