import java.beans.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; public class JSpinField extends JPanel implements CaretListener, AdjustmentListener, ActionListener { public JSpinField() { super(); min = 0; max = 100; value = 0; darkGreen = new Color( 0, 150, 0 ); setLayout( new BorderLayout() ); textField = new JTextField( "0" ); textField.addCaretListener( this ); textField.addActionListener( this ); add( textField, BorderLayout.CENTER ); scrollBar = new JScrollBar(); scrollBar.setPreferredSize( new Dimension ( scrollBar.getPreferredSize().width, textField.getPreferredSize().height ) ); scrollBar.setMinimum( min ); scrollBar.setMaximum( max ); scrollBar.setValue( max - value ); scrollBar.setVisibleAmount( 0 ); scrollBar.addAdjustmentListener( this ); add( scrollBar, BorderLayout.EAST ); } protected void setValue( int newValue, boolean updateTextField, boolean updateScrollbar ) { int oldValue = value; if( newValue < min ) value = min; else if( newValue > max ) value = max; else value = newValue; if( updateTextField ) { textField.setText( Integer.toString( value ) ); textField.setForeground( Color.black ); } if( updateScrollbar ) scrollBar.setValue( max - value ); firePropertyChange( "value", oldValue, value ); } public void setValue( int newValue ) { setValue( newValue, true, true ); } public int getValue() { return value; } public void setMinimum( int newMinimum ) { min = newMinimum; scrollBar.setMinimum( min ); } public int getMinimum() { return min; } public void setMaximum( int newMaximum ) { max = newMaximum; scrollBar.setMaximum( max ); } public int getMaximum() { return max; } public void setFont( Font font ) { if( textField != null ) textField.setFont( font ); } public void setForeground( Color fg) { if( textField != null ) textField.setForeground( fg); } public void caretUpdate( CaretEvent e ) { try { int testValue = Integer.valueOf( textField.getText() ).intValue(); if( (testValue >= min ) && ( testValue <= max ) ) { textField.setForeground( darkGreen ); } else { textField.setForeground( Color.red ); } } catch( Exception ex ) { if( ex instanceof NumberFormatException ) textField.setForeground( Color.red ); // Ignore all other exceptions, e.g. illegal state exception } textField.repaint(); } public void adjustmentValueChanged( AdjustmentEvent e ) { setValue( max - e.getValue(), true, false ); } public void actionPerformed( ActionEvent e ) { if( textField.getForeground().equals( darkGreen ) ) setValue( Integer.valueOf( textField.getText() ).intValue() ); } static public void main( String[] s ) { JFrame frame = new JFrame( "JSpinField" ); frame.getContentPane().add( new JSpinField() ); frame.pack(); frame.setVisible( true ); } private JTextField textField; private JScrollBar scrollBar; private Color darkGreen; private int min; private int max; private int value; }