/*******************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Tiny Look and Feel * * (C) Copyright 2003 - 2007 Hans Bickel * * For
* licensing information and credits, please refer to the * comment in file
* de.muntjak.tinylookandfeel.TinyLookAndFeel * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
package de.muntjak.tinylookandfeel.controlpanel;
import java.awt.Event;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
/**
* NumericTextField
*
* @version 1.0
* @author Hans Bickel
*/
@SuppressWarnings (
{ "all" } )
public class NumericTextField extends JTextField
{
private Vector listeners;
private ActionEvent actionEvent;
private int min, max, columns;
private boolean resistUpdate;
public NumericTextField ( int columns, int value, int min, int max )
{
super ( columns );
this.columns = columns;
this.min = min;
this.max = max;
setHorizontalAlignment ( JTextField.RIGHT );
setText ( "" + value );
addKeyListener ( new ArrowKeyAction ( this, min, max ) );
actionEvent = new ActionEvent ( this, Event.ACTION_EVENT, "" );
}
public int getValue ()
{
if ( getText ().length () == 0 )
return 0;
return Integer.parseInt ( getText () );
}
public void setValue ( int newValue )
{
if ( resistUpdate )
return;
setText ( String.valueOf ( newValue ) );
}
public void addActionListener ( ActionListener l )
{
if ( listeners == null )
{
listeners = new Vector ();
}
if ( listeners.contains ( l ) )
return;
listeners.add ( l );
}
public void removeActionListener ( ActionListener l )
{
if ( listeners == null )
return;
if ( !listeners.contains ( l ) )
return;
listeners.remove ( l );
}
public void notifyActionListeners ()
{
if ( listeners == null )
return;
resistUpdate = true;
Iterator ii = listeners.iterator ();
while ( ii.hasNext () )
{
( ( ActionListener ) ii.next () ).actionPerformed ( actionEvent );
}
resistUpdate = false;
}
protected Document createDefaultModel ()
{
return new NumericDocument ();
}
protected class NumericDocument extends PlainDocument
{
NumericDocument ()
{
addDocumentListener ( new KeyInputListener () );
}
public void insertString ( int offs, String str, AttributeSet a )
throws BadLocationException
{
if ( str == null || str.length () == 0 )
return;
if ( getLength () + str.length () > columns )
return;
if ( !checkInput ( str ) )
{
Toolkit.getDefaultToolkit ().beep ();
return;
}
String text = getText ( 0, getLength () );
if ( offs == 0 )
{
text = str + text;
}
else if ( offs >= text.length () )
{
text += str;
}
else
{
text = text.substring ( 0, offs ) + str + text.substring ( offs );
}
int val = Integer.parseInt ( text );
boolean correct = false;
if ( val < min )
{
val = min;
correct = true;
}
else if ( val > max )
{
val = max;
correct = true;
}
if ( correct )
{
remove ( 0, getLength () );
super.insertString ( 0, String.valueOf ( val ), a );
}
else
{
super.insertString ( offs, str, a );
}
}
private boolean checkInput ( String s )
{
for ( int i = 0 ; i < s.length () ; i++ )
{
if ( !Character.isDigit ( s.charAt ( i ) ) )
{
return false;
}
}
return true;
}
}
class ArrowKeyAction extends KeyAdapter implements ActionListener
{
private JTextField theField;
private javax.swing.Timer keyTimer;
private int step;
ArrowKeyAction ( JTextField field, int min, int max )
{
theField = field;
keyTimer = new javax.swing.Timer ( 20, this );
}
public void keyPressed ( KeyEvent e )
{
if ( e.getKeyCode () == 38 )
{ // up => decrease
step = 1;
if ( e.getModifiers () == KeyEvent.SHIFT_MASK )
{
step = 10;
}
changeVal ();
keyTimer.setInitialDelay ( 300 );
keyTimer.start ();
}
else if ( e.getKeyCode () == 40 )
{ // up => increase
step = -1;
if ( e.getModifiers () == KeyEvent.SHIFT_MASK )
{
step = -10;
}
changeVal ();
keyTimer.setInitialDelay ( 300 );
keyTimer.start ();
}
}
public void keyReleased ( KeyEvent e )
{
keyTimer.stop ();
}
// the keyTimer action
public void actionPerformed ( ActionEvent e )
{
changeVal ();
}
private void changeVal ()
{
int val = Integer.parseInt ( theField.getText () ) + step;
if ( val > max )
val = max;
else if ( val < min )
val = min;
// this should trigger insertUpdate()
theField.setText ( "" + val );
}
}
class KeyInputListener implements DocumentListener
{
public void changedUpdate ( DocumentEvent e )
{
}
public void insertUpdate ( DocumentEvent e )
{
notifyActionListeners ();
}
public void removeUpdate ( DocumentEvent e )
{
notifyActionListeners ();
}
}
}