All Visual J++ Tips



ActiveX object properties

In addition to the usual properties, ActiveX controls often have additional properties particular to the control. To view those properties, right-click the object, and choose the second Properties listed in the pop-up menu (the one near the bottom).

ZD Journals' Visual J++ Developer's Journal



Adding variables to the Watch Window

During debugging, you can quickly add variables to the Watch Window by dragging them from the Variables Window. Using this technique, you can simultaneously view variables from several locations in your code without scrolling through long listings, or switching pages.

The Cobb Group's Visual J++ Developer's Journal



Be careful when comparing strings

Java allows you to compare two String objects, strng1 and strng2 using the following code:

  if(strng1 == strng2) then
  ...

Unfortunately, the effect may not be what you want. The code above actually compares the String locations, not their text value. To compare the text values, use:

  if(strng1.equals(strng2)) then
  ...

The Cobb Group's Visual J++ Developer's Journal



Call Java classes from an ASP script

Do you want an easy way to call a Java class from an ASP script? Try this out:

Step 1:

Write and compile a public Java class. Here's a simple example:

public class MonikerTest {
    public String SaySomething() {
           return "What do you want me to say?";
    }
}

Step 2:

Place your compiled Java class in a directory in the server's CLASSPATH. For example, you could copy it to your server's \WINNT\Java\TrustLib directory.

Step 3:

In your ASP script, instantiate your Java class using the VBScript GetObject function and your class' URL moniker:

<%
Dim myObj
set myObj = GetObject("java:MonikerTest")
response.write myObj.SaySomething
set myObj = nothing
%>

You can now call your class' public methods, just like you would with any other server component.

Andy Hoskinson



Configuring the Call Stack Window

During debugging, you can configure the Call Stack Window to display only method parameters, parameter types, or both. Viewing only the parameter types is particularly useful when your code contains a lot of long method names.

The Cobb Group's Visual J++ Developer's Journal



Controlling a Java Applet from your HTML script

Using IE4, you can access all of the variables and methods in a Java applet from your HTML scripts. Here's how it works:

Given variable and method definitions in an applet like the ones below:

class ShapeClass extends Applet {
   public int radius;
   public int width, length;
   public drawShape () {

   // Draw the correct shape.
   }
}

In your HTML page, use the <APPLET> tag to establish a reference to the applet, and create an ID for the applet that you can use to refer to the applet in your script.

<APPLET CODE = "ShapeClass.class"  ID = "doshape">

You can now use the ID attribute in your HTML scripts to access all of the public variables and methods in your applet:

<SCRIPT language = "JScript">
function  Square() {
   document.doshape.width = 100;
   document.doshape.length = 100;
   document.doshape.drawShape();
}
function  Circle() {
   document.doshape.radius = 50;
   document.doshape.drawShape();
}
</SCRIPT>

Only classes that are derived from java.Applet are directly accessible from your HTML script, and any methods in your applet that you want to be accessible must be declared as public.

ZD Journal's Visual J++ Developer's Journal



Converting from stacks to strings

Occasionally you may find it useful to be able to capture the output from a stack dump, redirect it to a string, and then perhaps to a window. The code below contains a snippet with two methods for capturing output from an exception. The first code segment in the method ExceptionToString redirects the output from printStackTrace to a PrintWriter object, which is, in turn, bound to a StringWriter. We can then grab the StringWriter contents and insert it into a real String and then do with it as we please.

The rest of the code in ExceptionToString directs all output on System.err to a byte array, which can then be printed or otherwise manipulated. Note that the first code segment handle a single event, whereas the second segment redirects all error output.

import java.io.*;
public class ExceptionToString {
  public ExceptionToString() {
    try {
      int zero= 0;
      System.out.println("Causing exception with 1/0 "+1/zero);
    } catch (Exception e) {
      StringWriter swriter = new StringWriter();
      e.printStackTrace(new PrintWriter(swriter));
      String text = swriter.toString();
      System.out.println("Caught individual exception " + text);
    }

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    System.setErr( new PrintStream( baos ) );
    try {
      int zero= 0;
      System.out.println("Causing exception with 1/0" + 1/zero);
    } catch (Exception e) {
      e.printStackTrace(); // Goes to the defined print stream
    }
    byte []output = baos.toByteArray();
    String f = new String( output );
    System.out.println("Caught exception text = "+f);
  }

  public static void main(String []args) {
    new ExceptionToString();
  }
}

Al Saganich, Visual J++ Developer's Journal



Editing code generated by Visual J++

Sometimes you need to edit the code generated by Visual J++ (for example, to set the tri-state attribute on a Checkbox). Visual J++ is happy to let you do that, just be sure that you close down the form designer window for the class first.

Al Saganich, Visual J++ Developer's Journal



Encouraging Garbage Collection

If you're going to create an object and then dispose of it right away, you can encourage the garbage collector to release the object's memory earlier by setting the reference to null as soon as you're done with the object.

public void imageWait(Image myImage)
{
  MediaTracker tracker = new MediaTracker(this);
  tracker.addImage(myImage);
  tracker.waitForID(0);
  tracker = null;
}

Visual J++ Developer's Journal



Format Floating Point Expressions

Unlike many other programming languages, JavaScript does not have a built-in function for formatting floating-point numbers. However, it's easy to create one using JavaScript's String methods. Try this:

function format(expr, decplaces) {
// Convert the number to a string str = expr.toString()

// Get the position of the decimal point
point= str.indexOf(".")

// Get the substring to the correct decimal place newstring
= str.substring(0, Number(point) + Number(decplaces) + 1)

//Convert the string to a number, and return
return(Number(newstring))
}

To call the function, just substitute the number you want to format for the first parameter, and the number of decimal places you want in the second parameter. For example, if you wrote these statements:

x = 23.56733
newnum = format(x, 2)

then the value of newnum would become 23.56.

Microsoft Web Builder



Formatting numbers

One of the areas in which Java is strong is with respect to internationalization and number formatting. Sometimes we wish to format numbers in a specific locale or given a certain number of digits. Two classes help with this, NumberFormat and DecimalFormat. For example, to format a specific number in a given LOCALE (French, for example) try

String numberString=NumberFormat.getInstance(locale.FRENCH).format(number);

Or to round to two decimal places try:

NumberFormat format = NumberFormat.getInstance();
format .setMaximumDecimalFractionDigits(2);
String numberString = format .format(number + 0.5);

You can also use the getCurrencyInstance method of NumberFormat to manipulate currency values.

Andy Hoskinson



Handling complex initialization

Complex initializations need only be done once and the result stored for later use. For example if you need to create a list of integer values and then load them, you can create a class that stores the information and then load it as follows. (Note that the resource file needs to stored in the same location as the class file or the classloader will complain!

class someClass {
     private static final int[] values = initsomeClass();
     private static final int countVALUES = 27;
     private static int[] initsomeClass() {
     int[] values = new int[countVALUES];
     try {
          DataInputStream data = new

          DataInputStream(someClass.class.getResourceAsStream("someClass.dat"));
          for (int i = 0; i < countVALUES; ++i)
               p[i] = data.readInt();
          data.close();
     }
     catch (IOException e) {
          return null;
     }
    return values;
  }
  ...
}

Al Saganich



Indenting and unindenting code blocks

You can quickly indent (move to the right) or unindent (move left) a block of code in the Visual J++ editor. To do so, select the block, and press [Tab] to indent the block or [Shift]+[Tab] to unindent it.

The Cobb Group's Visual J++ Developer's Journal



Loading audio files

In many applets that play sounds, you'll see code such as the following to load an audio file:

AudioClip myClip = getAudioClip("http://www.cobb.com/vjp/welcome.au");

Using absolute URLs, particularly for things like sound files, is a mistake. Instead, load the files relative to the location of the applet, as in:

AudioClip myClip = getAudioClip(getCodeBase(), "welcome.au");

As long as the sound files are in the same directory as the applet, it doesn't matter what the absolute URL is.

The Cobb Group's Visual J++ Developer's Journal



Manually positioning buttons in a Java applet

Java's layout managers are great when you want to maintain the relative position of objects in an applet without manually repositioning them when the applet's size changes. However, you may occasionally want to stipulate absolute layout coordinates for objects such as buttons or other menu-related components. To do so, you must use the statement

SetLayout(null);

Where you'd ordinarily specify the name of the layout manager. If you proceed without a layout manager, you also have to use the add and reshape methods to add, position, and size the component.

The Cobb Group



Parsing a delimited list using the StringTokenizer class

Have you ever had a need to parse a delimited list in your Java application? It's easy to do with the java.util.StringTokenizer class. For example, if you wanted to parse a comma-delimited list, you might write a Java class that looked something like this:

import java.util.StringTokenizer;

public class ListParser {

  public static void main (String[ ] args) {
    String delimList = "test 1,test 2,test 3,test 4,last test message";
    System.out.println("The comma-delimited list is \"" + delimList + "\"");
    String[ ] arrayList = readTokens(delimList, ",");

    for(int i = 0; i < arrayList.length;i++) {
        System.out.println("Item number " + (i+1) + " is \"" + arrayList[i] + "\"");
    }
  }

  public static String[ ] readTokens(String text, String token) {

    StringTokenizer parser = new StringTokenizer(text, token);

    int numTokens=parser.countTokens( );

    String[ ] list = new String[numTokens];

    for (int i=0; i < numTokens; i++) {

      list[i] = parser.nextToken( );
    }
    return list;
  }
}

When you run this class using Jview, your output will look like this:

The comma-delimited list is "test 1,test 2,test 3,test 4,last test message" Item number 1 is "test 1" Item number 2 is "test 2" Item number 3 is "test 3" Item number 4 is "test 4" Item number 5 is "last test message"

Andy Hoskinson



Querying your applet's browser

Occasionally you may need to write an applet that depends on a Microsoft Internet Explorer-specific extension that is not common to all browsers. How do you find out if the browser that's running your applet supports the extension that you want to use?

Java provides a number of underlying classes that provide information about the system. For example, they can tell you what security manager is loaded, what OS your applet is running under, and which browser is running. You can then use this information to create an applet that's sensitive to the browser under which it's running.

Start by getting information about the system as a whole via the java.lang.System class method getProperty. The getProperty method allows the developer to get a wide variety of environment-specific information. It returns a string that represents the property that's been requested. For example, to determine the OS that an applet is running under we could ask

String os = System.getProperty("os.name");

which on my machine returns "WindowsNT".

We can then use the information returned to build a browser-sensitive applet using the java.version and java.vendor properties. The code below shows a snippet of a class that extends Applet and has a method called Supported. The Supported method accepts a vendor and a major/minor java version and tests for them.

public static boolean bVersionSupported = true;
public boolean Supported(String vendor, int major, int minor) {
  // Technically the vendor and major/minor version
  // numbers shouldn't all be blank, but we allow it anyway.

  // If the user gave a name that NOT the expected
  // vendor, return unsupported.
  if (vendor != "" && !System.getProperty
    ("java.vendor").toLowerCase().startsWith(vendor.toLowerCase()))
    return bVersionSupported = false;

  // Passed the vendor test; check major and minor
  // version numbers,if given.
  if ( 0 == major && 0 == minor)
    return bVersionSupported = true;
  int iMajor = 0;
  int iMinor = 0;
  String version = System.getProperty("java.version");
  System.out.println("Version is " + version);
  int dot = version.indexOf('.');
  if (dot < 0)
    iMinor = 0;
  else {
    String sMinor = version.substring(dot+1).trim();
    // Find the last alpha character.
    version = version.substring(0, dot);
    int end = sMinor.length();
    for (int i = 0; i < sMinor.length(); i++){
      if ( sMinor.charAt(i) < '1' || sMinor.charAt(i) > '9') {
        end = i;
        break;
      }
    }
    iMinor = Integer.parseInt(sMinor.substring(0, end).trim());
    version = version.substring(0, dot);
  }
  version = version.trim();
  iMajor = Integer.parseInt(version);
  if (iMajor > major )
    return bVersionSupported = true;
  else if ((iMajor == major && iMinor >= minor))
    return bVersionSupported = true;
  else
    return bVersionSupported = false;
}

Most of the actual meat of this method is in the string manipulations required to pull the version information into its component parts; however, you can see how the getProperty method allows the developer to get all kinds of useful information about the system.

Al Saganich, Visual J++ Developer's Journal



Registering and Unregistering ActiveX controls

If you wish to develop your own ActiveX control, or install a new control that's not a part of Windows, you need to register it using RegSvr32. RegSvr32 adds appropriate entries to the Windows Registry so that Windows will be aware of the control. Register a control with RegSvr32 with the following command:

C:\Winnt\System32\RegSvr32.exe =>{controlname}

where controlname is the complete path and name of any .dll, ocx, .tlb, or .exe ActiveX control. Under normal circumstances, RegSvr32 is located in WinNT\System32 under NT and in Windows\System under Win98 and Win95.

To unregister,add /u to the command line, as in

C:\Winnt\System32\RegSvr32.exe {controlname} /u

Consider unregistering a control when you want to be sure you've replaced an old version of the control with a new one.

ZD Journals' Visual J++ Developer's Journal



Set the layout behavior of controls with the J++ Form Designer

The Visual J++ Form Designer allows you to both anchor and dock controls on a form. When a control is anchored to an edge of its container, the distance between the control and the specified edge remains constant when the container resizes. When a control is docked to the edge of its container, it remains in contact with that edge when the container resizes.

A control can be anchored to any combination of the edges of a control. If the control is anchored to opposite edges of its container (for example, to the top and bottom), it resizes when the container resizes. To anchor the control within the form, double-click on the anchor property for the control. In the Anchor editor, click the cross bars to enable and disable anchoring between the control and the form edge.

More than one control can be docked to the edge of a form. If multiple controls are docked to the same edge, one is docked to the edge of the container, and the others are docked as close as possible to the edge without covering each other. To modify docking behavior for a control, double-click the control's dock property. In the Docking editor, click the bars to enable and disable docking for the control. Click None to disable docking.

ZD Journal's Visual J++ Developer's Journal



Simplest expressions on the left, please

Frequently, one of the expressions evaluated in && (AND) and (OR) operations requires more processing overhead to return a result. To maximize program efficiency, you should always include the simpler of the two expressions on the left side of the logical operator. Java always evaluates the left-hand expression first and, if it proves to be false, returns a logical value of false for the complete expression without taking the time to evaluate the second expression in the pair. By performing the easier calculation first, you may circumvent the second calculation altogether.

Visual J++ Developer's Journal



Specifying dependencies

When writing Java-based services we occasionally require dependencies. That is, our services must start in a certain order. You can specify what services your code is dependent on by overriding the getServiceDependencies method in your service class. For example, to create a service that is dependent on RPC being started, override the method as follows.

protected Object getServiceDependencies() {
    String dependsOn = "RPCSS\000\000";
    return dependsOn ;
}

Note that the dependencies string is a list of double null terminated strings. So, to create a dependency on two services specify the dependsOnstring as "Service1\000Service2\000\000", etc!

Al Saganich



Use Conditional Compilation for debugging J++ 6.0 applications

The newest version of J++ includes the ability to do conditional compilation, a handy mechanism for debugging your code, particularly if you are working on larger projects. Similar to the #ifdef/#else/#endif structure available to C programmers, J++'s conditional compilation allows you to include or exclude entire blocks of code at run time using the conditional directives #if, #else, #endif, #define, and #undef. Here's an example of how conditional directives work:

#define DEBUG

#if DEBUG
   System.out.println("We have a problem");
#else
   System.out.println("All's well");
#endif

The #define statement sets the identifier DEBUG (you can substitute any name, of course) to true. That would cause the statement within the #if block to execute. Simply removing the #define statement, or changing it to #undef DEBUG, will cause the #else block to execute.

How might you put the power of conditional compilation to work? Here are a few examples:

* Include diagnostic code during development, and then exclude it all at run time by simply removing the one #define statement.
* Exclude code that you think you may want to include again at a later date.
* Switch among several code sections to experiment with different implementations by #define-ing different identifiers.

You can also use expressions with the #if and #else directives, just as you can with the standard Java if/else structure.

ZD Journal's Visual J++ Developer's Journal



Use J++ 6.0's Dynamic Syntax Checking to find your errors as you type

As you enter code in the new and improved J++ 6.0 Text Editor, compiler errors you may be making are underlined with a red squiggle. Microsoft calls it Dynamic Syntax Checking, a feature of their IntelliSense technology, and it can help save you time by pointing out your errors before you compile. If you rest your cursor over the red squiggle, you'll get an Error Tip to help you correct your mistake. And, if you click the right mouse button on the red squiggle, you can select Error Help from the short-cut menu to get online help for the error that's been identified.

If you haven't seen any red squiggles while entering code, Dynamic Syntax Checking may be disabled. To enable it, (or to disable it you're a long-time Java user that rarely makes compiler errors) do the following:

1. On the Tools menu, click Options.

2. In the Options dialog box, expand the Text Editor node (click on the + sign next to it).

3. Select Java Tasks.

4. In the Tasks group of the property page, check (or uncheck) "Check syntax as you type"

5. In the Error Display group of the property page, check (or uncheck) "Underline syntax errors as you type"

Although occasionally the Error Tip is the less-than-helpful "Syntax error", Dynamic Syntax Checking can show you where your errors are before you compile your code, which can be a real time saver, particularly for beginners.

ZD Journal's Visual J++ Developer's Journal



Use J++ 6.0's Localization feature to take your applications global

Use J++ 6.0's Localization feature to provide several language versions of your application. This new feature allows you to create separate resource files for every form in your application, for every language in use. If you use the required naming convention for these files, your user's computer will select the right resource file at execution time based on user preferences.

ZD Journals' Visual J++ Developer's Journal



Use Java's Vector class for faster performance

When performance is an issue, static arrays perform better than dynamic storage structures. However, if a static structure won't work, consider using Java's Vector class instead of the LinkedList class. Vectors provide dynamic storage and easy access, just as linked lists do, but they are actually faster for many applications.

ZD Journals' Visual J++ Developer's Journal



Use MediaTracker.waitForID() to monitor image loading

If you want your to wait until an image loads before proceeding, you can use the MediaTracker.waitForID() method to defer execution until the image is ready for display.

public void imageWait(Image myImage)
{
  MediaTracker tracker = new MediaTracker(this);
  tracker.addImage(myImage);
  tracker.waitForID(0);
  tracker = null;
}

The Cobb Group's Visual J++ Developer's Journal



Use System.arraycopy() to copy arrays and subsets of arrays

If you want to copy elements between arrays, don't copy them one at a time inside a loop. Instead, use System.arraycopy(), which moves a block of data much more efficiently.

System.arraycopy(sourceArray, sourceStartIndex,
                 destArray, destStartIndex, numberToCopy);

The Cobb Group's Visual J++ Developer's Journal



Use the auto modifier with Win32 J/Direct Unicode functions

If you're using J/Direct to call Win32 API functions, you won't want to specify the Unicode or ANSI version of the function (if multiple versions exist). The ANSI versions will run on any platform, but will run slower than the Unicode versions on Windows NT systems. To allow the Java VM to determine which version to call, use the "auto" modifier in the import statement, as shown below:

/** @dll.import("USER32", auto) */
static native int MessageBox(int hwnd, String text, String title, int style);

Visual J++ Developer's Journal



Use the Immediate Window to help debug your applications

To view and change values during Debugging, use the Immediate window. You can evaluate any expression, variable, or object in the window and see the value that is returned, or you can see the effects of commands you enter. To display the Immediate window, choose View | Debug Windows | Immediate.

Add expressions or variables to the Immediate window from the Text Editor, or from the Local or Watch windows, or enter expressions into the Immediate window to display or change the value of variables, properties, and expressions. If you select a variable for evaluation, the Immediate window will return its current value; for expressions, the evaluated results are returned.

ZD Journal's Visual J++ Developer's Journal



Use the Object Browser to add components to your projects

The Object Browser allows you to browse, filter, and search for components that you may want to add to your projects. To access the Object Browser, choose View | Other Windows | Object Browser.

The left pane of the Object Browser window shows a list of all the packages or libraries that can be referenced from the current project. Each can be expanded to show the classes contained in the package. Members associated with those classes appear in the right pane.

You can customize the view in the Object Browser, group and sort members and classes, and search for specific members and classes. Although by default the Object Browser only displays the packages and libraries that can be referenced from the current solution, you can also add additional packages and libraries to the Object Browser window from other COM Libraries, Java Installed Packages, and other Java packages.

ZD Journals' Visual J++ Developer's Journal



Using names for Java methods that differ from the name the DLL uses

You may want to use a name for a Java method that is different from the name the DLL uses when it exports the function. For example. you may need to conform to naming conventions prescribed by your own site. In that case, just use the @dll.import directive along with the entrypoint modifier. For example. if you wanted to use the GetSysColor function, but wanted to change the first letter to lowercase, you would include the following:

/**@dll.import ("USER32",entrypoint="GetSysColor") */
  static native int getSysColor(int nIndex);

The entrypoint modifier has now set up the aliasing for you.

ZD Journal's Visual J++ Developer's Journal



Using println statements in the debugger

Println statements are very handy for debugging your applications, but how can you see the output when you're running an applet in the debugger? By default, when you create a Visual J++ 6.0 project and run it within the debugger, the applet is actually run via the Wjview.exe application. This application interacts with the Visual J++ IDE, and supports all those bells and whistles for which Microsoft products are known. It also eats all system.out.println statements.

However, you can see all of your output quickly and easily by changing a debugger default. To do that, choose Project | Properties from the menu, then select the Launch tab, if it isn't already selected. Then check the Launch As A Console Application check box. Now, when you run your applet, you'll be greeted with what appears to be a DOS window, which contains all your System.out messages.

Al Saganich, Visual J++ Developer's Journal



Write to the NT Event Log from a Java class

Ever wondered how you can log something to the NT Event log from a Java class? It's easy, if you use the com.ms.util.EventLog class that ships with the Microsoft SDK for Java. Try this out:

Step 1: Write and compile this class with Visual J++:

import com.ms.util.EventLog;

public class EventLogTest {
     public static void main (String[] args)  {
         EventLog myEventlog = new EventLog("EventLogTest");
         myEventlog.reportEvent(EventLog.INFORMATION, (short)0, 0,
         "This is a test event log message");
     }
}

Step 2: Run this class on your NT server using JView.

Step 3: Open up the NT Event Viewer application, and look at your Application Log. Your event should be at (or near) the top.

Andy Hoskinson