Swing 1.1.1
I'm stuck with Swing 1.1.1, trying to create a filthy rich client at work. The reason for being stuck with an obsolete Swing release is that we're developing on CrE-ME, a Java ME CDC implementation for Windows CE.
Swing 1.1.1 is missing a lot of features you take for granted when you've been working with recent Swing releases and want to create visual effects. When I started to create the client UI I intended to use gradients and shadows because they're pretty. But wait, let's list some of the things that's missing in Swing 1.1.1
AlphaComposite- Bye bye drop shadow and transparency.
GradientPaint- It's true, no gradients... not even a
Paintinterface. AffineTransform- No scale operations and no rotation on the graphics canvas. Too bad.
The only thing left to do is faking as much as possible. I'm creating faux shadows, rendering solid shadows with colors carefully matched to the background. Gradients can be achieved with a tiled background image slice.
Migration, d'oh!
I just discovered that I'd only partiallly migrated this website to the new host. I switched host 6 months or so ago, but today I noticed that the site was connecting to the database at the old provider.
What bugs me with this is that the reason for switching host was that their database server had such a lousy uptime. Hopefully the site will be a bit faster from now on...
Heap dump analysis
A couple of weeks ago, at work, I had to tackle an OutOfMemoryError in production. I find these kind of errors especially though to fix since it's often hard to pinpoint the problem based solely on information found in the logs.
I could however finally solve it with help of Eclipse Memory Analyser (MAT). MAT is a tool to analyze heap dumps. It presents a graphical overview of the heap and makes it easy to drill down to analyze the data. It can also generate leak reports that can help to pinpoint leaky objects. It is also good to know that MAT had no problems handling really large heap dumps (> 512 mb). The by Sun provided jhat utility ran out of heap space when I tried it. Ironic, I know...
To use MAT, a heap dump is required. To take a heap dump one can use jmap, a utility program, bundled with the Java 6 JDK. The tricky part is not to take a heap dump, it is to get a chance to take it while the application is still running (remember, mine was in production).
24th November 2008, 22:41 CET.
On Demand Javascript
In a project I'm working I need to be able to dynamically load small javascript apps. A dynamically created menu should be able to launch the different apps it displays. The menu can be loaded with data sent as JSON from the server side and. Since the menu is dynamic, it isn't possible (and shouldn't be necessary) to load all scripts in advance.
The solution is to load scripts on demand. On demand javascript is neat, but requires that you somehow wait until the script has loaded before you execute it. Multiple solutions for this exists and many seems to use some sort of callback to solve the problem.
My approach is a bit different, yet simple. All apps are loaded through the same object. That object is also responsible for initiating the just loaded app and unload the previous one. This allows me to control the loading process with a simple timer.
var sas = {}; // namespace
sas.app = new function() {
var current = null;
var pollInterval;
var polled;
function init(name) {
current = sas.app[name];
current.init();
}
function demand(name) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', sas.app.path + name + '.js');
document.getElementsByTagName('head')[0].appendChild(script);
polled = name;
pollInterval = window.setInterval(poll, 100);
}
function poll() {
if (typeof sas.app[polled] != 'undefined') {
window.clearInterval(pollInterval);
init(polled);
}
}
return {
path : '',
load : function(name) {
if (current != null) {
current.destroy();
}
if (typeof this[name] == 'undefined') {
demand(name);
} else {
init(name);
}
}
}
}
This implementation makes the following assumptions about the loaded code.
- All apps must reside in the same package (i.e., namespace or object). In my example all apps must be in the
sas.apppackage. - All apps must be singletons (i.e. defined as
sas.app.MyApp = new function() { ... }). - The file name must match the class name (i.e.,
MyAppmust be saved to the fileMyApp.js).
I wan't to emphasis that these conditions apply to the current implementation, but I can't see any reason as to why it shouldn't be possible to write a solution that doesn't require all of these conditions to be met.
I've put up a small proof of concept from where the snipped above is copied. Note that the menu actually is a pluggable app in the same way that the dynamically loaded scripts are. I think that's pretty neat.
14th September 2008, 22:58 CET.
Swedish
I've decided to start another blog at http://se.samuelsjoberg.com. It is written in swedish and I hope to start typing more frequently on that blog (compared to this one).
However, I'm not ready to declare this blog dead yet. I'll just leave it here and see how things evolve.
Welcome to life

This is my son 11 hours after birth. He was born July 8th at 8.55 AM. His measurements were 3285 g and 50 cm.
The name is still pending, but we're starting to feel pretty confident about Hugo
.
We're gonna name him Hugo.
Comment spam
Last couple of days I've started to recieve comment spam. I've never had a problem with this before (probably because I post too little and have almost no readers), but anyway now I felt that something had to be done.
I didn't want to use a CAPTCHA so I decided to try Akismet instead. It is a collaborative effort to battle comment spam. I guess some bayesian filters and other fancy AI techniques are used.
I have implemented a first draft that is activated now. I'm using the PHP 4 class by Bret Kuhns to integrate with Akismet. Everything seems to work, Akismet agress with my that the spam I'm getting is in fact spam so all I have to do now is to remove the non-approved, spam comments from my database. The thing that remains is to make some fancy administration to handle false-positives, but I doubt I'll encounter many of those.
