Grinding Java - Dynamic Java

From EDM2
Jump to: navigation, search

By Shai Almog

Dynamic Java

There is a story about the creation of Visual Basic which claims that when MS engineers created the product it had no VBXs, and when they showed it to Mr. Gates he said that it's good, but should be made extensible. I don't know if that story is true, but I don't doubt for one second that the reason that Visual Basic is so widely successful is due to the fact it can be extended using OCXs and VBXs. Today Microsoft is pushing hard on Visual Basic for applications, as a tool to extend regular applications. The paradigm is clear: Tie the users to your environment by allowing them full control over it!

A couple of months ago I read an article in JavaWorld which discussed building a Basic emulator using Java. This struck me as odd, since Java is an interpreted language which can do anything that Basic can do so why not translate the code to Java/Java Bytecode? Maybe the author did not know how easy it is to bind new code into the VM?

This month I will develop the core for 2 related technologies:

  1. A compiler / executer for Java, which will allow you to add Java based extensions to your applications (as in VB for applications).
  2. A visual development form on which you can place Java components and Java beans (much like the VB forms).

A Java source compiler and byte code executor

These two classes supply a very simple to use and general tutorial on how to compile Java source files and the load the class files and execute them. As you will see in the source code this is very simple which makes the development of a serious Java IDE quite simple when using pure Java.

Grinding Java - Dynamic Java:MacroExtension.java

Things to notice:

  • We implement ClassLoader and override the loadClass method which allows as to determine the way in which a class is loaded. This gives us absolute power over the VM. Beware absolute power does not come without a price: you may by accident jeopardize the security of the VM. I.e. if you allow implementation of plugins over the Internet (like applets) you may "forget" to implement a security mechanism (as in the sandbox) and thus a rogue plugin could "attack" your host computer.
  • We check whether a class was already loaded into memory. This is not needed for memory conservation but for speed. Remember a class may be loaded from over the Internet which might make its loading overhead greater than the overhead of the extra memory used.

Grinding Java - Dynamic Java:SimpleStream.java

Things to notice:

  • The structure of the Java stream interface is quite interesting, and most surprisingly is not too portable. In Corba a stream is defined as an interface containing a write/read (depending on input or output stream) for every native data type, i.e. writeChar(char c). In Java the streams are byte oriented. This doesn't harm the portability of Java since it runs in a well defined VM, but it is more short sighted (in my humble opinion) than the Corba Implementation.

Visual editing of components on a Java container

Abstract
When developing plugins/components for your applications one of the most eye catching features that your user will first notice is the ability to visually manipulate them using drag and drop, and similar properties. Developing an application of that sort is surprisingly easy in Java due to the powerful infrastructure component model already located in the AWT.
Concept
The visual surface is in fact a Frame to which we add the power to manipulate components. This approach allows us to use the native capabilities built into the java.awt.Frame/Component classes. This approach forces us to remove some of the "unwanted" features of a Frame:
  1. When resizing a frame will reorganize the components in the window, which can be quite bad for visual applications.
  2. Components are created at a zero size which means we must allow a default size and resizing capabilities.
  3. Drag and drop of components on the surface should be allowed for absolute positioning.
  4. Properties of components should be modifiable.
  5. A toolbar is needed to allow selection of components to place on the development surface.
  6. We must create a way to manipulate Panels so that they will not become invisible once placed on the surface.
  7. Placing a component within a container must work correctly. When the mouse will point within the editing surface on an embedded container the object must be placed within it.

I have implemented 3,5 and 7 and patched up 2 so that the results will be visible. In my next column I will deal with the rest of the issues.

FormDesigner.java

  import macrolanguage.*;
 
  class FormDesigner
  {
    public static void main(String argv[])
    {
      new FormDesigner();
    }

    public FormDesigner()
    {
      toolbar = new EditToolbar(editForm);
    }

    private EditToolbar toolbar;
    private FreeFormEdit editForm = new FreeFormEdit();
  }

The FormDesigner class is the class which starts the project by creating a toolbar for visual development and a surface upon which components can be placed.

  package macrolanguage;

  import java.awt.*;

  /**
   * The exception NotAContainerException is thrown when an application
   * tries to reference an object or Component when it should be referencing
   * a container.
  **/
  public class NotAContainerException extends AWTException
  {
    public NotAContainerException(String errorString)
    {
      super("Not a container exception! " + errorString);
    }
  }

This exception is thrown to satisfy requirement 7, if a component is placed on another component it will throw an exception.

Grinding Java - Dynamic Java:FreeFormEdit.java

Things to notice:

  • This class delegates all of the mouse events to the mouseManager class rather than dealing with them itself. I chose the delegation strategy to avoid bloating the class with an unnecessary number of interfaces.
  • I set a default size to the Form. I feel that "standard" VB style visual editing is not a good thing for Java development, so I will try to remove all the sizes and measurement in my program. This does not mean replacing them with static ints (constants) which will achieve nothing.
  • I added a key listener yet did not implement its interface. Keys such as delete and escape should have a meaning in a visual environment.
  • When a component is added to the surface it is important to add listeners to mouse activities on it. These will allow us to select and move components using the mouse.
  • When putting a new Component on the surface we replace the mouse cursor with a '+' style cursor.

Grinding Java - Dynamic Java:MouseManager.java

Despite its outer simplicity this class was the biggest hurdle in developing the FreeFormEdit. The positioning interfaces in Java are quite complex due to the power of Java's Component module.

Things to notice:

  • mouseDragged gets the correct values when a positive direction is taken, yet the wrong ones when a negative direction is taken. I suspect a bug in this interface in IBM's alpha JDK 1.1.
  • Very little program logic is located in this class. All related actions are delegated back to the FreeFormEdit.
  • calculateParentContainerXY calculates the true XY positioning. It is essential to understanding the workings of the surface editor.

Grinding Java - Dynamic Java:EditToolbar.java

Things to notice:

  • Very little is done in this class. Most of the work is delegated to FreeFormEdit and some to MacroExtension. This is purely a UI class.
  • The toolbar is a Window class.
  • I chose a crude interface which requires entering the name of the class to place it on the surface. This is mostly to demonstrate just how powerful this solution is.

Conclusion

I wanted to start us off on the class file format and how to strip symbol information, but I feel that the visual development subject is far from finished so I intend to finish it before moving on. Next time I will deal with all of the issues I left open this time.