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:
- A compiler / executer for Java, which will allow you to add Java based
extensions to your applications (as in VB for applications).
- 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.
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.
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:
- When resizing a frame will reorganize the components in the
window, which can be quite bad for visual applications.
- Components are created at a zero size which means we must allow
a default size and resizing capabilities.
- Drag and drop of components on the surface should be allowed
for absolute positioning.
- Properties of components should be modifiable.
- A toolbar is needed to allow selection of components to place on
the development surface.
- We must create a way to manipulate Panels so that they will
not become invisible once placed on the surface.
- 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.
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.
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.
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.
|