📄 input.java
字号:
// we need it to check for the Esc key. The action and focus
// listeners are added only if we need them because of
// exit validation.
if( !customizer.validatesOnExit() )
getDocument().addDocumentListener( characterValidator );
}
/** @return true if the data was valid and the listeners notified
*/
private boolean validateInputAndNotifyListenersIfValid()
{
String text = Input.this.getText();
valid = customizer.isValid( text );
if( valid )
{ lastValid = text;
fire_ActionEvent();
}
return valid;
}
private void retainFocus()
{ Input.this.requestFocus();
invalidate();
}
private final DocumentListener characterValidator = new CharacterObserver();
private class CharacterObserver implements DocumentListener
{ public void removeUpdate(DocumentEvent event){/*uninteresting*/}
public void changedUpdate(DocumentEvent event)
{ insertUpdate(event);
}
public void insertUpdate(DocumentEvent event)
{
offset = event.getOffset(); //used by paint
length = event.getLength(); //used by paint
// Document d = event.getDocument();
// String newText = d.getText(offset, length);
String fullText = Input.this.getText();
valid = Input.this.customizer.isValid( fullText );
if( !valid );
{
// You can't modify a Document in a
// DocumentListener, so force a repaint
// and update the valiator in paint(),
// which checks the "valid" flag, set
// set earlier.
invalidate();
}
}
}
/** Override of event dispatcher dismisses any popups when any
* event is detected.
*/
protected void processEvent( AWTEvent e )
{ super.processEvent(e);
if( e.getID()!=KeyEvent.KEY_RELEASED )
dismissPopups();
}
private void dismissPopups() // Not synchroinzed---must be called from
{
if( popup != null ) // AWT event thread.
{ popup.hide();
popup=null;
}
}
/** This method must be public because it's public in the base class. Don't
* override it.
*/
public void paint( Graphics g )
{ try
{ // Before you repaint, modify the document
// to eliminate any invalid characters detected by.
// the document listener
if( !valid )
{
explainTheProblem( getLocationOnScreen(), getText() );
getDocument().remove( offset, length );
Toolkit.getDefaultToolkit().beep();
valid = true;
}
super.paint(g);
}
catch( BadLocationException e)
{ Logger.getLogger("com.holub.PAC").warning
( Log.stackTraceAsString(e)
);
}
}
private void explainTheProblem( Point location, String badInput )
{
String help = customizer.help( badInput );
if( help != null && help.length() > 0 )
{ JLabel text = new JLabel();
text.setText
("<html><head>"
+"<style type=\"text/css\">"
+"body{ font: 11pt verdana, arial, helvetica, san-serif; background: #ffffcc}"
+"</style>"
+"</head><body>"
+"<table border=0 cellspacing=0 cellpadding=6><tr><td>"
+ help
+ (customizer.validatesOnExit()
? "<p>Press Esc to reset this field." : "")
+"</td></tr></table></body></html>"
);
// Move the location a bit so that it doesn't completely
// obscure the control.
location.translate(getWidth() * 1/2, getHeight() * 1/2);
popup = PopupFactory.getSharedInstance().getPopup( this, text,
location.x, location.y );
popup.show();
// Create a timer to kill the popup after POPUP_LIFETIME
// seconds of user inactivity
// Must be an javax.swing.Timer timer so that dismissPopups() will
// work correctly.
Timer t=new Timer( POPUP_LIFETIME * 1000,
new ActionListener()
{ public void actionPerformed(ActionEvent evt)
{ dismissPopups();
}
}
);
t.setRepeats(false);
t.start();
}
}
private ActionListener listeners = null;
/************************************************************************
* Action listeners are notified when the control holds valid
* input and the user is done entering data. This will happen
* in two situations:
* <ol>
* <li> The user hit Enter and the contents
* are properly validated.
* <li>When a control looses focus,
* and the control holds a valid string. (It's actually not possible
* for the control to loose focus when the contents aren't valid,
* and a notification <em>is not sent</em> if the user exits
* the control by hitting Esc.). The {@link ActionEvent ActionEvent}'s
* "command" string holds the user input as would be returned from
* <code>toString()</code>.
* </ol>
* @param l
*/
public synchronized void addActionListener(ActionListener l)
{ listeners = AWTEventMulticaster.add(listeners, l);
}
/** Remove a listener added by a prior
* {@link #addActionListener addActionListener(...)} call.
*/
public synchronized void removeActionListener(ActionListener l)
{ listeners = AWTEventMulticaster.remove(listeners, l);
}
public void fire_ActionEvent()
{ if( listeners != null )
{ ActionEvent e = new ActionEvent( this, 0, toString() );
listeners.actionPerformed(e);
}
}
//----------------------------------------------------------------------
// Misc short methods.
public Dimension getMinimumSize() { return getPreferredSize(); }
public Dimension getMaximumSize() { return getPreferredSize(); }
public String toString() { return getText(); }
/************************************************************************
* A test class.
*/
public static class Test
{ public static void main( String[] args )
{
Customizer weird =
new Customizer()
{ public boolean validatesOnExit(){ return true; }
public boolean isValid( String s )
{ System.out.println("Weird validating: [" + s + "]" );
return s.length() == 0;
}
public String help( String badInput )
{ return "Only empty strings are valid";
}
public void prepare( JTextField current )
{ current.setToolTipText("Only empty strings are valid");
}
};
final Input s1 = new Input( "", weird, BOXED, false );
s1.setColumns(10);
Customizer integer = new NumericInput.Behavior(-100, 100, 0);
Customizer money = new NumericInput.Behavior(0, 10000,2);
Customizer plain = new NumericInput.Behavior();
final Input n1 = new Input( "99", integer, UNDERLINED, true );
final Input n2 = new Input( "123.00", money , BOXED, false);
final Input n3 = new Input( "1,234.567", plain, BORDERLESS, false);
ActionListener reporter =
new ActionListener()
{ public void actionPerformed( ActionEvent e )
{ System.out.println("--------------------");
System.out.println( "n1=" + n1.getText() );
System.out.println( "n2=" + n2.getText() );
System.out.println( "n3=" + n3.getText() );
}
};
n1.addActionListener( reporter );
n2.addActionListener( reporter );
n3.addActionListener( reporter );
try // check that validation occurs on initialization
{ Input x = new Input( "xxx", plain, BOXED, true );
System.out.println("Initialization validation Failed");
}
catch( IllegalArgumentException e )
{ System.out.println("Initialization validation OK");
}
n1.setColumns(5);
JPanel panel = new JPanel();
panel.setLayout( new FlowLayout(FlowLayout.CENTER, 10, 10) );
panel.setBackground( Color.WHITE );
panel.add(n1);
panel.add(n2);
panel.add(n3);
panel.add(s1);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground( Color.WHITE );
frame.getContentPane().setLayout( new BorderLayout() );
frame.getContentPane().add(panel, BorderLayout.SOUTH );
frame.pack();
frame.show();
frame.addWindowListener
( new WindowAdapter()
{ public void windowClosing( WindowEvent e )
{ System.out.println( "n1=" + n1.getText() );
System.out.println( "n2=" + n2.getText() );
System.out.println( "n3=" + n3.getText() );
System.exit(0);
}
}
);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -