/* * [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; } }