Wednesday, July 23, 2008

Crippled Apple LaF for Java Swing

Recently I found very-very unpleasant thing with Apple Look & Feel for Swing on OSX. On JDesktopPane, to get all the internal frames getAllFrames() is called. Works fine everywhere except OSX: it does not returns iconified frames. The reason, because they are not JInternalFrame.JDesktopIcon instances as normally everybody else in the World does, but are apple.laf.CUIAquaInternalFramePane.Dock instead. WTF?.. At first, I wanted to abandon OSX LaF and use something else instead. But "Substance" release that works on Java 5 is hell buggy and still very ugly on the same Java 5. New Nimbus LaF is really cool, look great, works and feels awesome, but... looks like an alien in OSX reminding me all this GTK things with X11. Additionally, it does not run on Java 5 at all.

Why Java 5? Yes, it is old, but thanks to (inaudible) Apple, there is no Java 6 on Tiger that the whole thing should also run. In fact, Apple LaF is the best for Java 5, allows font anti-aliasing, behaves correctly as OSX app should and overall looks great, so I do not really want to abandon entire LaF either.

Thus ss a consequence, to get code working everywhere without tweaks and if/else uglyness to detect what platform it runs on, I had to implement my own window tracker.

* * *

Works fine, but still pisses developers off, when everybody have to have dozen workarounds or class extensions to fix here/there various "broken bones".

Apple wants to go Enterprise? Steve, which object of your body you use when you are thinking about Java versions interoperability (an enterprise industry standard, no matter somebody wants to accept it or not) between OSX versions? So what should I do if I have heterogeneous environment with various Macs and PCs and want to go with less old stuff (soon we will have Java 7, while Apple is enforcing me to use Java 4 or even 4)?.. Right: throw macs away from the Enterprise, because they are not compatible between each other, install PCs and bite yourself for other things they brings to you... But to get rid of most advanced desktop OSX workstations is what I definitely do NOT want to do either.

Very stupid.

Saturday, July 05, 2008

HDR Image

This is my very first HDR image:

Nothing really special, except that I found (once again) for buying cheap stuff is always equals to losing your money. In my case I bought a cheap tripod. As a result, HDR image is not really crisp and sharp, because camera slightly change position per each frame. :-(

Sunday, June 22, 2008

Screenshots Series

Few funny (or not) screenshots I took recently.

First one — Sun Solaris 10 installation. I did not noticed it much before, but that's how bad design of UI installers done. The question is: why do I need to see huge Solaris logo twice and who needs to read stupid useless incomplete Help hint that says for to go to next screen I have have to click on button "next"? Who need this screen and why there are no any functionality on it? They could use this amount of space to do something actually useful: agree to licence or start selecting components etc. No, instead you see this:

You think it is only this one screen? No. If you go through entire Solaris installation (that is unable to complete on my hardware, unfortunately) you will see lots of things like this everywhere. Instead, OpenSolaris looks indeed very promising and actually cool. Some people have complains for packaging, but that's other topic. :-)

The next one is on Dell website. Not much comment for this new Linux logo on the left side:



The third one is from apple.com and is interesting. On the site with series of video-based "howto" is a title: "Find out how". While watching a movie, I captured this frame that shows interesting combination. The only question is: find out how what... If the context is "how to configure XRaid with XServer and find why it always does not works properly", then the answer is probably just in front of you on the cover-flow... :-)

L337 h4x0r spam

I've JUST created new mailbox... And it already got L337 amount of spam crap... :-(

Beautifully Engineered Opera 9.5

I wisited opera.com for an update for Opera browser that likely "won" Acid 3 test from Safari. The website says:

beautifully engineered
Discover the new standard in Web browsing. Download Opera today to get the fastest and most powerful Web browser available and make the most of your time online.

However, after removing fugly opera's default "Macintosh native" skin and replacing it with something that actually tries to resemble Cocoa, the real beauty looks like this:


I understand it is still better than recently released Firefox 3. But... yet, Opera, you need to try harder... Me? I am just fine with WebKit (Safari) on Mac that is fastest and gets 100/100 with no any problems (grin here).

P.S. The "winner" of Acid 3 was actually Opera 9.0 for some weird reasons...

Tuesday, June 10, 2008

Salute To Cisco VPN

I just ran find / -perm +00002 -ls > /tmp/world-write and among other crap I found this hilarious thing:

731350 0 drwxrwxrwx 13 root wheel
/etc/opt/cisco-vpnclient

3731351 0 drwxrwxrwx 49 root wheel
/etc/opt/cisco-vpnclient/Certificates


Great installation, Cisco!

*morons* :-(

Thursday, May 08, 2008

Plugins In Java

I wanted to implement plugin mechanism in my applications. But the thing is, that the plugins should could be also a standalone applications with main() static function inside. This is not very that difficult in principle, just have nice way to do that. Another thing I really want to have, is a call-back mechanism that can get all the arbitrary things, implemented in the parent application. They can be a printing and reporting stuff, authentication, authorization and so on. Finally, I want to have some shared space, where all the plugins can store their arbitrary data and interoperate between each other. What I really do not want to have is a typical bloatware, built on top of some fat framework that does lots of workarounds for specific needs. The thing should be as simple as possible. 

But the challenge is, that if it would be a, let's say, Groovy or Python, then it is pretty easy to implement is: just pass a class instance. Since it is all dynamic — stuff just works. However, Java is a static language that has lots of goodness over dynamic languages, but also this is the place, where ugly shapes appears too.

I am not sure I got it completely right, but at least I could shrink entire http://jpf.sourceforge.net just up to few methods and thus throw away all the framework with no harm to the functionality.

Here above "Plugin Application" is a standalone application that is also a plugin and could be fully acquired by "Base Application". You can run your plugin app, but also you can get it's functionality in the "Base Application" by simply dropping entire JAR file into specified subfolder. That's all it is: just move the JAR and you're done.

Plugin Application has a file plugin.properties that is an XML (can not believe for the shame that there are no support for UTF-8 in plain-text properties!!!) and these props just simply describes what class is main to acquire and how. There also some additional information, like application title, some specific config paths and a menu icon to use. :-)

Base Application simply reads the folder with all the plugins that are subfolders with required libraries and properties file, finds a properties file, parses and registers the plugins. Then once user needs one, launcher actually loads it.

The most worse part of the whole story is a call-back mechanism. This should be a third external package, that is available for both main application and all the plugins. There are two things: an interface and dummy class that implements basically nothing. Real implementation is inside the main application that inherits that dummy class and implements the interface of the call-back. Base Application passes the type of the dummy class something like this:
Class paramType [] = {third.external.package.DummyCallback.class};
Class remoteObject = Class.forName("your.remote.object");
Method meth = remoteObject.getMethod("remoteMethod", paramType);
Above is how you prepare things. Now, call them, where RealCallback class is actually an instance of implemented call-back. In this example I create new one on the fly, but probably in your application it is commonly accessed field that has better constructor and does some real things:
Object params [] = {new ReallCallback()};
meth.invoke(remoteObject.newInstance(), params);

That's it. Base Application has been found remote object, a method and invoked it. Now, on the other side of the whole chain, the following thing is done:

import third.external.package.DummyCallback;
public void remoteMethod(DummyCallback callback) {
callback.dosomething();
}

This is probably the whole idea that already works for me pretty fine.