October 2005 Archives

java.io.Console

| 1 Comment

Build 57 of Java 6 includes a new class java.io.Console.

Javadocs are at the link above. And you can also leran more at Alan Bateman's blog .

Highlights:

  • Obtain the Console object with System.console(). It returns null if there is no console.
  • a readPassword() method for reading input that is not echoed on the console
  • a readLine() method for reading input from the user. Much simpler than wrapping a BufferedReader around an InputStreamReader around System.in
  • Also supports printf() and format() methods just like System.out does.

Client side sparkline images

| 2 Comments

Sparklines are a new graphical concept championed by Edward Tufte, author of a number of very cool books that you have probably already heard about. Sparklines are an idea from his forthcoming book, and he explains them in a draft chapter from that forthcoming book at sparklines.org.

If you're using a browser that understands the data: URL, here's an example of a sparkline:

Server load: 16.

Note, that this particular sparkline is hard-coded in this blog entry. The demos below show how they are dynamically generated.

As part of my newfound obsession with client-side drawing techniques (I really think it could change the web) I've created a way to generate sparkline images using client-side Java and JavaScript. This is proof-of-concept stage, but if you're running Firefox and have the Java plugin installed, click on these links to try out the demos:

  • spark.html: this demo uses LiveConnect to script Java directly. It does not use an applet at all. This means it will not work in IE. I don't know about other browsers' support for this kind of direct scripting of Java classes. This demo returns a PNG image encoded in a data: URL. This also means it won't work in IE, since IE does not support the data: scheme.
  • spark2.html: this demo uses a SparklineGenerator applet to create the PNG image, which it returns as a javascript: URL. This is supposed to be for compatibility with IE, but it still doesn't work in that browser for me. It could probably be made to work somehow... This demo also moves toward an unobtrusive JavaScript technique in which sparklines are coded with a new <sparkline> tag, which gets replaced by the image after document load by JavaScript and the applet.

You'll need to understand both Java and JavaScript to make use of this stuff. But if it interests you, you can use my code for any purpose as long as you attribute it to me.

Flash for client-side vector graphics!

| 7 Comments

In my previous entry, I asked about the possiblity of using Flash as a vector graphics engine, for scripting by client-side JavaScript code. With help from Geoff Stearns and his blog Deconcept I've figured out how to do it.

I've figured out how to do it in Flash 8, at least. Flash 8 has a new ExternalInterface API that transparently makes ActionScript methods callable from JavaScript. (It is possible, though not nearly so simple to do similar things in earlier versions of Flash.) Here is my trivial ActionScript file, which I named Canvas.as:

import flash.external.ExternalInterface;

class Canvas {
    static function main() {
        Stage.scaleMode = "noScale";
        Stage.align = "TL";
        ExternalInterface.addCallback("beginFill", _root, _root.beginFill);
        ExternalInterface.addCallback("beginGradientFill", _root,
                                      _root.beginGradientFill);
        ExternalInterface.addCallback("clear", _root, _root.clear);
        ExternalInterface.addCallback("curveTo", _root, _root.curveTo);
        ExternalInterface.addCallback("endFill", _root, _root.endFill);
        ExternalInterface.addCallback("lineTo", _root, _root.lineTo);
        ExternalInterface.addCallback("lineStyle", _root, _root.lineStyle);
        ExternalInterface.addCallback("moveTo", _root, _root.moveTo);
    }
}

I compiled this code with the open-source mtasc ActionScript compiler like this:

mtasc -swf Canvas.swf -main -version 8 Canvas.as

This produced the file Canvas.swf which you can download by clicking the link.

The ActionScript code doesn't do anything except make the Flash drawing API accesible to JavaScript. If you embed this SWF file in your web page, it is simply blank, until you draw something to it yourself. Here is a demo:

<embed src="Canvas.swf" quality=high bgcolor=#FFFFFF width="400" height="200"
name="canvas" align="" type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer">

<p><button onclick="draw()">Draw in the Canvas</button>
<script>
function draw() {
    document.canvas.beginFill(0xAAAAFF, 100);
    document.canvas.lineStyle(5, 0x0000FF, 100);
    document.canvas.moveTo (10, 10);
    document.canvas.lineTo (200, 100);
    document.canvas.lineTo (10, 190);
    document.canvas.lineTo (10, 10);
    document.canvas.endFill();
}
</script>

This demo uses the <embed> tag instead of the <object> tag, so it won't run in IE. But I have tested it in Firefox, and it works. But only if you have Flash 8 installed. And Flash 8 is not available for Linux yet. If you've got Flash 8 running in Firefox (or Safari?) give the demo a try!

Comments, suggestions, improvements, or whatever are very welcome. I plan to tweak Canvas.as a bit to expose methods for adding text, but I think that will be straightforward. I was disappointed to discover that the Flash drawing API is not nearly as robust as that of the <canvas> tag or of SVG of VML. In particular all curves must be done with quadratic beziers. Cubic beziers, circles, arcs and so on must all be approximated with a single curveTo() function. So it might be worth adding some basic shape-drawing primitives (circles, rounded rectangles, etc) to Canvas.as as well.

Feel free to use this code (and the swf file) for any purpose, with attribution.

Flash for client-side vector graphics?

| 6 Comments

I know very little about Flash, but it seems to me that it would make a good substitute for the <canvas> tag as well as SVG and VML. From a basic perusal of the Macromedia web site, it appears that it is possible for client-side JavaScript to communicate with the ActionScript interpreter in the Flash plugin. If so, JavaScript ought to be able to get ActionScript to draw lines, curves, and do other vector-graphics type things.

ActionScript has an eval() function. I would think that it would be possible to create a tiny SWF file that does nothing more than define a hidden TextField object and an onChanged event listener for that field. The event listener would take the new value of the TextField and pass it to eval(). Client-side JavaScript would then set the value of the TextField with the TSetProperty method that is exported by the Flash player. And voila! Client-side JavaScript can then make pass arbitrary ActionScript commands to the Flash Player. This gives us scriptable client-side vector graphics that work anywhere Flash is installed.

Can anyone tell me why this wouldn't work? Is anyone already doing it? If you make this work and release your code openly, you'll get a link and an attribution in the next edition of my JavaScript book!

Books

Comprehensive coverage of Ruby 1.8 and 1.9

"The New Most Important Ruby Book"
Peter Cooper,
rubyinside.com

Completely updated for Ajax and Web 2.0

"A must-have reference"
Brendan Eich,
creator of JavaScript

The classic Java quick-reference