The people   Coding standards   Design   Rewrite rule   TODO   DONE   Sun Java  

Javadocs   Class Hierarchy   Index   NAWS   MTRX   security   servlets   Skang   Squeal & Stuff   zen developer  


Skang coders guide


THIS DOCUMENT IS OUT OF DATE.

A new version is due within a week.


Package net.matrix_rad.skang

This is preliminary documentation for the Skang skin language, everything is subject to change. Consider this a work in progress for now. Not everything is implemented or documented properly. Not everything has been tested everywhere yet. If in doubt, Example.java, Matrix.java, Resume.java, Watch.java and Yabba.java show how to do things properly. SkangAWT.java is an example of how to write a module that interfaces to a particular widget set, though it does double duty, interfacing to AWT and NAWS.

The matrix-DFS project will use Skang. matrix-DFS will be the driving force behind further development of Skang, as it requires extremely fancy GUI stuff. Somewhere on the matrix-DFS site you will find a graphic of runestones idea of the client GUI, that gives you an idea of what I am aiming for.

Skang will be hosted from the matrix-RAD site.

The purpose of Skang is to allow the definition of GUI's over a network connection or from a file. Sub classing the Skang class to use it directly is also possible. Usually, this sort of thing is refered to as a GUI "skin", basically an upper layer that defines the layout of the GUI in a manner that allows easy customization. Skang is much more than that, as the skin itself can be active, rather than just a change of graphics that other skin systems do.

Skang actually tries to be a few things besides skins, it is also a generic applet / application with generic handling of things like parameter passing. Skang is a more precise / intelligent replacement for HTML forms that is extendable.

Sometime in the future I will include a GUI editor that is invokable from within a running skin. This will allow ordinary web users to change the look of the skin, have the new skin stored on the server, and a cookie set in their browser that says "next time, use my version of the skin". It can also be used by programmers to write skin files from within a running application, and have the new skin automagically loaded into the running app. The way this will work is to have a button or combination of keys that pops up a palette of widgets and tools, and lets the user drag and drop things around on the original skin, when the new skin is saved, the palette goes away, and the skin is left in it's new configuration. For programmers, it does away with the "move two pixels to the left, compile, run, damn it should have been three, stop running, move one pixel to the left, compile, run cycle.

Skang has a Developers menu, available by right clicking any widget. The menu includes a line that reports on the health of each loaded module. If everthing is fine, you just get the name of the module, if the module is broken you might get a useful description of the problem as well. The Developers menu will let you edit all your source files, reload the current skin, toggle the output widgets on and off, recompile the whole thing, and create a distribution. It will also hook into any dump and check commands you may have defined, and which will have default methods added in the future. Finally, you get a whole bunch of information about your running program. Most of the developer menu works in a browser, and it will eventually all work in a browser.

And now, a first for programming language documentation, an interpreter for the language is included right here in the documentation! The following applet uses the Skang.skang skin file that is included in the Skang package. Skang.skang demonstrates many features of Skang, and includes a TextField widget called Tester that will allow you to type in Skang commands to see their effect on the applet itself. Note that it is possible to remove the Tester widget, but you can always hit your browsers Reload button. A button to reload the skin is included as well, so long as you haven't removed it B-). Some space at the top and left has been provided to create your own widgets. All the pre programmed widgets on this skin have the word "Test" in the name, followed by a number, so avoid that for your own widgets. This doesn't apply to the standard widgets, which have the standard names.

This requires a Java applet to run, but your browser does not support Java.

Here is the Skang.skang file in all it's gory. The HTML code that loaded the above applet is :

  <P ALIGN="CENTER">
    <applet code="net.matrix_rad.skang.Skang.class" name="Skang" codebase="../.."
      alt="Please enable Java in your browser, this requires a Java applet to run."
      width=580 height=380>
This requires a Java applet to run, but your browser does not support Java.
    </applet>
  </P>


Skang, the skin language

Skang is a simple, extendable language, with only a few complications. The general syntax is a keyword followed by a white space seperated list of arguments, with one command per line. Commas are considered to be white space. C and C++ style comments are allowed, empty lines are ignored. The keyword is case insensative, but all else is case sensative.

See net.matrix_rad.skang.SkangSkanglet.java for the base set of arguments and commands. See net.matrix_rad.skang.SkangAWTSkanglet.java for the AWT based commands. If these do not exist, run the "skanglet" ANT target to create them.

Skang is also an API, and the class that all Skang modules should extend. By extending the Skang class the programmer automatically gets support for a number of things, including the Skang language. Skang will do the right thing when run as an applet or application. Skang will display a splash screen / applet while it is busy doing all this fancy stuff for you. Skang will parse your arguments for you, be they command line arguments, properties files, or applet parameters. Skang will parse a .skang file with the same name as your module. A minimal Skang module is :

package net.host;
import java.lang.String;
import net.matrix_rad.skang.Skang;

public class Example extends Skang
{
  public static void main(String someArguments[])
  {
    Skang.main(someArguments);
  }

  public final static String CLASS_CLASS        = "Example";
  public final static String CLASS_PACKAGE      = "net.host";
  public final static String CLASS_VERSION      = "1.0 final";
  public final static String CLASS_VERSION_NO   = "1.0";
  public final static String CLASS_VERSION_DATE = "2001-08-30 12:27:00";
  public final static String CLASS_AUTHOR       = "David Seikel";
  public final static String CLASS_COPYRIGHT    = "2001";
}
The main() definition should be written exactly as is, although you could add stuff after the call to Skang.main(). Think of Skang.main() as the equivilent of the super.init() in an applet's init() method. The various CLASS_* strings identify your module to Skang and allow it to automatically generate copyright text, getAppletInfo() text, application usage text, and other things. There is also a CLASS_OSINFO string, but it is OK to inherit that from Skang. If the above is all the Java you need for any particular application, then you don't even need that bit, just call Skang directly with the name of your .skang file.

Skang.main() instantiates your class, then turns it into an applet, and does the usual applet processing from then on. That means that you can override init() as if you were writing an applet. Don't forget to call super.init(). initGUI() is a new method that you can override to do any initialization tasks after the GUI is defined. No need to call super.initGUI() if you are sub classing Skang directly, Skang.initGUI() does nothing. NEVER override run(), use runBit() instead. runBit() is called from Skang.run in a loop, so you don't need to write a loop, or take care of thread issues, or anything. Just include in your runBit() the things you would normally include in your main loop, but with out the loop. Never override start(), stop(), destroy(), getAppletInfo(), or getParameterInfo(), as Skang does that all for you. No need to call getParameter(), Skang does it for you. In the future, I may relax the restrictions on overriding start(), stop(), and destroy(), although I never needed to override those.




Skang Things

Skang uses the concept of "Thing". All Skang arguments and commands are Things, as are all Widgets added into the system by Skang commands. The Java methods and fields attached to Skang commands and arguments are also Things. Each Skang module is a Thing. Finally, purely for internal reasons, the Class of each widget added by a Skang command is also a Thing. The Developers menu, after reporting on the health of each module, shows the entire Thingspace. The argument 'name' for Skang commands refers to a Thing, usually a widget. Skang will keep track of how many times a Thing has crashed, and display that in the developers menu.

Skang What

Skang has a "What", which is used as a central repository of all sorts of stuff, see the javadocs for details. If you need to use What, add this to your class :

  public static What areWe = new What();
Skang modules have a built in What and automatically use it as needed. Some of the things in What are there to give non Skang classes access to some of the Skang magic. A good example is the NAWS widgets, they usually subclass Component, and being a full Skang module is overkill for them, but they sometimes need some of the Skang stuff.

The various booleans are usually referenced via the object (areWe.standAlone), while the various cached objects and methods are usually referenced through the class (What.seperator). It doesn't really matter almost everything is static anyway, it's just syntactic sugar. The exceptions are the AppletStub and AppletContext methods, which implement those two Interfaces when Skang is running as an Application.

Extending Skang commands and arguments

Adding your own Skang commands and arguments is now very simple, thanks to a JavaDoc doclet that does all the hard work for you. Write a class that extends Skang and add public methods and fields to it. The methods should return String or void. The fields should be String or int. Then javadoc your Skang extension methods and fields properly using the @.skang, @.skangarg, @.required, and @.shortcut javadoc tags. Finally, run the "skanglet" ANT target (done for you during a normal build) to produce a skanglet. A skanglet is a Java source file with "Skanglet" added to the end of your class name. The skanglet also has a default skin definition, based on any .skang file with the same name as your class.

Skang commands have several predefined argument types, see net.matrix_rad.skang.Skang.SKANG_ARGS for the full list. Limit yourself to using those types in your SKANG syntax definition. Skang will take the syntax string, and search for a matching method, then remove the last argument, search for a matching method, and continue until it runs out of arguments to remove. So if you declare enough variations of the method, you can have some arguments as optional.

Skang complications

'name=data' is the same as 'set name,data'. Unlike other commands, several 'name=data' pairs can be on one line, seperated by white space. This was done so that in the future, command line processing will use the same routine to decode the command line arguments.

A _ (underline) in front of a number means to tanslate from lines to pixels. For example _10 means multiply the number of pixels in a line by 10. A line is defined as being tall enough to fit a TextField into. This does mean that underlines can not be used in names. The dollar sign ($) can be used, and is compatible with most other naming schemes you may need to interface with.

'name.method arg1, arg2, "etc"' - will invoke that method on the named Thing, with those String or int arguments.

The data argument is always quote delimited. Widget names have to be valid Java field names.

You can use some replacable paramaters for action :

  %a - the action
  %d - the widgets value
  %n - the widgets name
  %t - the widgets type

For each widget, if there is an isValidWidgetname(), then it gets called during ActionEvent, set, and get time. Example : boolean isValidCardNo(String aValue)

The return value of all commands is a negative number followed by text in the case of an error, or the name of the widget affected, followed by any other output needed :
  -1 Parser warning
  -2 Parser error
  -3 Name error
  -4 Type error
  -5 Argument error
  -6 Invalid value
  -7 
  -8 Unhandled exception
  -9 Unhandled error


This file was last modified on Friday, 05-Nov-2004 10:51:44 EST