Eclipse tip: better systrace template

Eclipse’s systrace template is very handy. For the uninitiated: it’s where eclipse allows you to type “systrace”, or even “syst” for that matter, hit ctrl+space, and have eclipse fill in

System.out.println( "enclosingClass.enclosingMethod()" );

I often want to also print out the values of the arguments to the current call, but it’s tedious to go back into the generated template code and edit in all the " + arg1 + ", " + arg2 + " required.
Happily we can add a new template that effectively will do this for us:
Under Preferences/Java/Editor/Templates, add a new template that looks like this:

System.out.printf( "${enclosing_type}.${enclosing_method}( %1s, %2s, %3s, %4s )\n", ${enclosing_method_arguments} );

and call it something like traceargs4. This template will print the values of the method arguments (calling formatTo() on Formattable object args, and toString() on other objects). Unfortunately, the templates cannot detect the number of arguments, and so you’ll need to add in separate templates for different numbers of arguments, e.g.:

traceargs1: System.out.printf( "${enclosing_type}.${enclosing_method}( %1s )\n", ${enclosing_method_arguments} );

traceargs2: System.out.printf( "${enclosing_type}.${enclosing_method}( %1s, %2s )\n", ${enclosing_method_arguments} );

traceargs3: System.out.printf( "${enclosing_type}.${enclosing_method}( %1s, %2s, %3s )\n", ${enclosing_method_arguments} );

Note that you’ll get an runtime exception if you try to format more arguments than exist, e.g.: using traceargs4 in a 1-argument method.

An alternative/addition to having many separate traceargs templates is having one that is large enough for almost all methods, and that you trim to fit for smaller ones:

System.out.printf( "${enclosing_type}.${enclosing_method}( %1s, %2s, %3s, %4s, %5s, %6s, %7s, %8s${cursor} )\n", ${enclosing_method_arguments} );

will leave the cursor ready to delete the unwanted formatting variables.

That’s pretty handy. :slight_smile:

If you wrote your own System.out.println couldn’t you write a var-args version that didn’t need different base strings, and therefore use one macro all the time without editing it?

Indeed you could. Didn’t think of that… :stuck_out_tongue:
The method would look something like


public class SysTrace
{
	public static void trace( String prefix, Object... args )
	{
		StringBuilder buff = new StringBuilder( prefix );
		buff.append( "( " );
		for( int i = 0; i < args.length - 1; i++ )
		{
			buff.append( args[ i ] );
			buff.append( ", " );
		}
		buff.append( args[ args.length - 1 ] );
		buff.append( " )" );
		System.out.println( buff.toString() );
	}
}

and the template like

SysTrace.trace( "${enclosing_type}.${enclosing_method}", ${enclosing_method_arguments} );

It won’t automatically insert an import for SysTrace - templates are just text replacement, but I’ve got eclipse set to organise imports on every save anyway.

Nice!

Just use the fully specified class name.