Re: resize JTable
- From: steve <steve@xxxxxxx>
- Date: Fri, 7 Oct 2005 05:15:03 +0800
On Wed, 5 Oct 2005 09:49:26 +0800, Roedy Green wrote
(in article <5a66k1p55jm4s3epbklbh5bee004ec133a@xxxxxxx>):
> On Wed, 5 Oct 2005 05:34:38 +0800, steve <steve@xxxxxxx> wrote or
> quoted :
>
>> MM123
>> MM9492
>> MM5596
>> MM80753
>> MM1234556
>>
>> but we do not always use a 2 letter prefix, and some of our part numbers
>> (rarely) might be
>>
>> 12ASASA8545-878
>>
>> i suspect the best way is to compare length then alpha, that should fix it.
>
> Here is the code. I have only tested it with the test harness. Before
> you trust it, it should be given examples to exercise all the code.
>
> The big thing wrong with it is on every key compare it goes through a
> great song and dance to parse the key into fragments. Ideally that
> should be done once, not once per compare.
>
> You could have Compare cache the values or your could precompute them
> on a separate pass.
>
> However, for a sort of only a few thousand you won't notice and big
> slowdown.
>
> It is a big ugly the kludge it uses to flush the accumulations for the
> last key fragment. I'd like to see a tidier way to handle that. I
> wanted to avoid repeating code just to handle the last frag.
>
>
> // Comparator for Catalog Numbers. Sorts alpha and numeric parts
> separately.
> // Sorts numeric parts numerically.
>
> import java.lang.StringBuilder;
> import java.util.ArrayList;
> import java.util.Arrays;
> import java.util.Comparator;
>
> class CatalogOrder implements Comparator<String>
> {
> /**
> * Compare two Strings. Callback for sort, as a catalog number.
> * effectively returns b-a;
> * @return +1, b>a, 0 a=b, -1 b<a, case insenstive
> */
> public final int compare( String a, String b )
> {
> // for speed could do tidyKey ahead of time, instead of calling
> once per compare.
>
> Object[] aa = tidyKey( a );
>
> Object[] bb = tidyKey( b );
>
> int min = Math.min (aa.length, bb.length );
> long diff;
>
> for ( int i=0; i<min; i++ )
> {
> if ( aa[i] instanceof String && bb[i] instanceof String )
> {
> diff = ((String)aa[i]).compareTo( (String)bb[i] );
> }
> else if ( aa[i] instanceof Long && bb[i] instanceof Long )
> {
> diff = ((Long)aa[i]).longValue() -
> ((Long)bb[i]).longValue();
> }
> else
> {
> // Mismatched. Not a very consistent catalog number
> system.
> // Treat numbers as less than letters.
> return aa[i] instanceof Long ? -1 : 1;
> }
> if ( diff != 0 )
> {
> // can't just return raw diff, since it is a long
> return diff < 0 ? -1 : 1;
> }
> } // end for
> // we fell out the bottom of the loop with detecting a
> difference.
> // the longer key then comes later.
> if ( aa.length < bb.length ) return -1;
> if ( aa.length > bb.length ) return 1;
> // were absolutely identical
> return 0;
>
> } // end compare
>
> /**
> * Used create an aux sortable multifield key from a catalog
> number.
> * Converts an alphanumeric key to an array of mixed Strings and
> Longs
> * breaking catalog number into alpha and numeric fields
> */
> public static Object[] tidyKey ( String catalog )
> {
>
> // chars in this catalog number
> int catalogLength = catalog.length();
>
> // 0-terminated array to hold the catalog String
> // 0 lets us go round the loop one extra time to flush
> accumulation.
> char[] catalogChars = new char[ catalogLength + 1];
>
> // copy catalog to char[]. Terminal 0 already in place.
> for ( int i=0; i<catalogLength; i++ )
> {
> catalogChars[i] = catalog.charAt( i );
> }
>
> // Where we accumulate the fragments of the the key, either
> String or Long
> ArrayList<Object> keys = new ArrayList<Object>( 5 );
>
> // keep track if we are processing numbers or letters.
> boolean inNumeric = false;
>
> // where we accumulate the next chunk of key
> StringBuilder accum = new StringBuilder( catalogLength );
>
> // loop once for each char, plus one more time to flush the
> append buffer.
> for ( int i=0; i<catalogLength+1; i++ )
> {
> char c = catalogChars[i];
> boolean isNumeric = '0'<= c && c <= '9';
> if ( isNumeric != inNumeric || c == 0 )
> {
> // we need to finish off the previous accumulation
> if ( inNumeric )
> {
> // finish off previous numeric field
> String numeric = accum.toString();
> if ( numeric.length() > 0 )
> {
> keys.add ( new Long( numeric ) );
> }
> inNumeric = false;
> }
> else
> {
> // finish off previous alpha field
> String alpha = accum.toString();
> if ( alpha.length() > 0 )
> {
> keys.add ( alpha );
> }
> inNumeric = true;
> }
> // clear for reuse
> accum.setLength( 0 );
> }
>
> // tack onto key fragment we have accumulated already,
> // or to newly cleared accum
> accum.append ( c );
> } // end for
>
> return keys.toArray( new Object[ keys.size() ] );
> } // end tidyKey
>
> /**
> * test harness
> *
> * @param args not used
> */
> public static void main ( String[] args )
> {
>
> // test tidyKey
> Object[] key = tidyKey( "12ASASA8545-878" );
> for ( Object keyFrag : key )
> {
> System.out.println ( keyFrag.getClass().getName() + " : " +
> keyFrag.toString() );
> }
>
> // try sorting some catalog numbers
>
> String[] cats = {
> "MM123",
> "MM9492",
> "MM80753",
> "MM5596",
> "MM1234556",
> "12ASASA8545-878A",
> "12ASASA8545-878",
> "12ASASA8545-876",
> };
> Arrays.sort( cats, new CatalogOrder() );
> for ( String cat : cats )
> {
> System.out.println( cat );
> }
> } // end main
> }
>
>
>
thanks roedy, I'm going to take a look at this over the weekend, whilst I
tidy up my 'date' implementation in the JTable.
.
- References:
- Re: resize JTable
- From: steve
- Re: resize JTable
- From: Roedy Green
- Re: resize JTable
- From: Dag Sunde
- Re: resize JTable
- From: Roedy Green
- Re: resize JTable
- From: steve
- Re: resize JTable
- Prev by Date: Re: Cloning a Cloneable Map
- Next by Date: how can I get my applet to keep its resources after applet.destroy()
- Previous by thread: Re: resize JTable
- Next by thread: Re: resize JTable
- Index(es):
Relevant Pages
|