/*
* [HexNumberFormatter.java]
*
* Summary: hex unsigned long NumberFormatter for a JSpinner.
*
* Copyright: (c) 2007-2017 Roedy Green, Canadian Mind Products, http://mindprod.com
*
* Licence: This software may be copied and used freely for any purpose but military.
* http://mindprod.com/contact/nonmil.html
*
* Requires: JDK 1.8+
*
* Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/
*
* Version History:
* 1.0 2007-08-15 initial version
*/
package com.mindprod.spinner;
import javax.swing.text.DefaultFormatter;
import java.text.ParseException;
/**
* hex unsigned long NumberFormatter for a JSpinner.
*
* @author Roedy Green, Canadian Mind Products
* @version 1.0 2007-08-15 initial version
* @since 2007-08-15
*/
@SuppressWarnings( { "WeakerAccess" } )
public final class HexNumberFormatter extends DefaultFormatter
{
// max chars with in hex digits.
private final int width;
/**
* constructor
*
* @param width how many chars wide is the field.
*/
public HexNumberFormatter( int width )
{
if ( width > 16 )
{
throw new IllegalArgumentException( "HexFormat width > 16" );
}
this.width = width;
}
/**
* Converts the passed in String into an instance of getValueClass
by way of the constructor that takes
* a String argument. If getValueClass
returns null, the class of the current value in the
* JFormattedTextField
will be used. If this is null, a String will be returned. If the constructor
* thows an exception, a ParseException
will be thrown. If there is no single argument String
* constructor, string
will be returned.
*
* @param string String to convert
*
* @return Object representation of text, namely Long, must match what JSpinnerNumberModel uses.
* @throws java.text.ParseException if there is an error in the conversion
*/
@SuppressWarnings( { "QuestionableName" } )
public Object stringToValue( String string ) throws ParseException
{
try
{
if ( string.length() > width )
{
throw new ParseException( "Max " + width + " digits allowed.",
0 );
}
// find out what sort of Number object is desired.
// Pick one matching value in NumberModel.
Object value = getFormattedTextField().getValue();
if ( value instanceof Integer )
{
return Integer.valueOf( string, 16/* radix */ );
}
else if ( value instanceof Long )
{
return Long.valueOf( string, 16/* radix */ );
}
else
{
throw new IllegalArgumentException(
"HexNumberFormatter only works with Integer and Long" );
}
}
catch ( NumberFormatException nfe )
{
throw new ParseException( string, 0 );
}
}
/**
* Converts the passed in Object into a String by way of the toString
method.
*
* @param value Value to convert, some sort of Number
*
* @return String representation of value, padded with left zeroes to width.
* @throws ParseException if there is an error in the conversion
*/
public String valueToString( Object value ) throws ParseException
{
// treat as unsigned
final long asLong = ( ( Number ) value ).longValue();
final String hex = Long.toHexString( asLong );
// apply lead zeroes as needed.
final int lz = width - hex.length();
return lz <= 0 ? hex : "0000000000000000".substring( 0, lz ) + hex;
}
}