JavaFX Revive the Java GUI

August 21st, 2007

What can JavaFX offer us? At the beginning, after JavaOne in May 2007, everybody was inspired by the hype of the new Flash / Silverlight / Flex competitor. But do we really need a new Flash? I don’t think so, Flash is well established and spread. This couldn’t be done so fast with JavaFX, especially the authoring tool of Flash would hard to take out, in the near future.

So a equal competitor with a chance to overtake Flash is JavaFX not. Well, not yet. But JavaFX could take a change with the fact, that JavaFX Script has the whole Java thing behind. With Java you have potentially more possibilities than you have with Flash. ActionScript (the Flash scripting language) is going to be better and more Java like each version, but Java is the real object oriented language, and it is more scalable, and because of this it is better for huge applications.

But the Java world is to hard to reach for designers or let me say design oriented developers ( like me, too ;-) ). Design or aesthetic enthusiasts love to see something while developing, something Flash provides easily. So I think JavaFX could close this gap. It is more design oriented and provides easy and fast success.

JavaFX is still wearing the shoes of a child (it’s a German saying) but I think the tool support is a key factor and the animation stuff also. If it will be possible to shift rendering more and more, perhaps with Direct3D or OpenGL, to the graphics card it will have success.

Hey, have a look at the new Microsoft Windows Vista, or even more the new Leopard Mac OS X. The time of smooth sliding widget is still present, and Java and Sun must play a role in this game, not for being cool, no - just to survive.

The proposed Consumer JRE will also be a key to success. Depend the Flash loading time to the Java Applet loading time. It is not acceptable for the consumer.

So I hope, JavaFX will get more fancier … of course first it must get faster and graphic card oriented to reach this step two target.
But if the world of smooth animated widgets come alive with JavaFX on the (Java) Desktop and on Rich Internet Applications (RIA) than Java might compete with the cool Mac Apps. I think in future your GUI must be more cool (not overloaded) to build good “joy of use” applications, that people like, or perhaps fell in love with. Watch the iPhone GUI, people do not even ask for prices they just love it and sleep days in front of Apple Stores.

Me for my part, I am working currently on a Swing LookAndFeel created with JavaFX. I am working on the interface calling ComponentUIs build in JavaFX and used by Java Swing JComponents. It’s a huge thing and lacks on the speed a bit, but I think it has a future perspective. Because only building LookAndFeels with Photoshop sliced PNGs couldn’t be the best solution for the future. Thinking for resolution independent GUIs. Smooth animated and vector based widgets are the future.

Thanks, for reading and for comments!
Flo.

Multiple Inheritance with JavaFX

August 21st, 2007

All developer coming from Java, might feel a bit strange with this possibility because, our Java teachers always thought us, that it is a good thing not to have multiple inheritance. Well you can build dangerous constructs with this. In Java we have interfaces for this problem, but JavaFX Script doesn’t provide interfaces, so it might be a needful thing to have this multiple inheritance here. But use it carefully, as I wanna show you it could end up in confusion very fast.
Ok, let me explain you how it behaves right now.

Let me assume, we have two classes M1 and M2 and a class MAll, that extends M1 and M2.

//class 1
public class M1 {
attribute num: Number;
operation M1 ();
}

operation M1.M1() {
System.out.println(”M1 print some information: {this.num}”);
}

//class 2
public class M2 {
attribute s: String;
operation M2 ();
}

operation M2.M2() {
System.out.println(”M2 print some information: {this.s}”);
}

//extends class 1 and 2
public class MAll extends M2, M1 {

}

var object = new MAll() {
num: 123,
s: “hello”
};

This would print on your console:

M2 print some information:
123
hello

This shows us that the behavior in which the constructors of the superclasses are called is a bit strange, but has a rule. The rule is, that the constructor of the class is called which has been extended first. The constructor of the second, third and so on extended class are never going to be called.

But you can override a constructor of course. If you modifiy the upper code like this:

//extends class 1 and 2
public class MAll extends M1, M2 {
operation MAll();
}

operation MAll.MAll() {
super();
System.out.println(”MAll print some information: {this.s}”);
}

You will get that as an output:

MAll print some information:
123
hello

That shows, that you can override the constructor and shows that you do not have the possibility to call the constructor of the super class. The “super()” has no effect. That’s a pity.

These two examples show also, that the attributes “num” and “s” are not initialized at the time, when the constructor is called. But afterwards.

I posted this (a bit) strange behaviour of multiple inheritance to the JavaFX mailinglist and Chris Oliver (the inventor of JavaFX) answered this:

Support for both constructors and multiple inheritance is only half-baked currently - sorry about that. We’re still discussing the semantics and implementation strategies. For now, I recommend avoiding both features as they’re almost certainly going to change significantly from the current behavior.
Chris (25th of July 2007)

So, I think in further versions things will change a bit.

JavaFX with a Look and Feel

August 20th, 2007

If you want to use a different LookAndFeel (LaF), perhaps set on a Java Swing application, you will recognize a confusing problem. Your set LookAndFeel, if it is not the OS native LaF, will be reset to the native LaF, mostly Windows or Mac OS X Look and Feel.

I think the javafx.ui.UIElement.fx file of the runtime of JavaFX has a piece of code, that resets the Look and Feel always to the systems LaF (in line 101).
I have no idea how to avoid this easily, perhaps with one line in your applications code. I just build a workaround for that, a so called LookAndFeelKeeper. It’s a standard Java class:

public class LookAndFeelKeeper {

private static String lookAndFeel;

public static void keep() {
try {
if (!UIManager.getLookAndFeel().getClass().getName().equals(lookAndFeel)) {
System.out.println(”LaF reset from ” + UIManager.getLookAndFeel());
if (lookAndFeel == null) {
lookAndFeel = UIManager.getLookAndFeel().getClass().getName();
}
UIManager.setLookAndFeel(lookAndFeel);
} else {
System.out.println(”No LaF reset (current = ” + UIManager.getLookAndFeel() + “)”);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}

public static void setLookAndFeel(String lookAndFeel) {
LookAndFeelKeeper.lookAndFeel = lookAndFeel;
}

public static String getLookAndFeel() {
return LookAndFeelKeeper.lookAndFeel;
}
}

1. You have to instance it once when your applications starts in you code. The best place would be there, where you set you new LaF:

LookAndFeelKeeper.setLookAndFeel(”com.app.your.YourLookAndFeel”);

Or directly in your own LaF, if you wrote one by your own. Then you can override the initialize() method of your LookAndFeel.

@Override
public void initialize() {
super.initialize();
// protects the application from a reset of the LaF by JavaFX
LookAndFeelKeeper.setLookAndFeel(this);
}

2. a) You always have to call

LookAndFeelKeeper.keep();

when you instanciate a new JavaFX component for example in a

trigger on new ComponentName { LookAndFeelKeeper.keep(); }

statement.

2. b) As an alternative you can create a file called “LookAndFeelKeeper.fx”, with this content. You have to import this to your application, at a place before new components got created.

package packagename;

//Look And Feel Hack, that keeps the initially set Look and Feel.
import de.centigrade.jfxlaf.util.LookAndFeelKeeper;
<<de.centigrade.jfxlaf.util.LookAndFeelKeeper>>.keep();

This solution helps in my case but is not really satisfying. I hope some JavaFX experts have a better solution or a explanation why this Look And Feel reset happens at all?

Best,
Florian

Reflection / Introspection for a class with JavaFX

August 20th, 2007

Here is an solution on how the Reflection / Introspection of a class might work with JavaFX Script.
In the following example there exists a class “MyClass” and a sub class of it, called “MySubClass1″.
With this solution you can specify a type of a subclass and you can instantiate it somewhere else.

class MyClass { }
class MySubClass1 extends MyClass { }
// 1) specify a type
var type: Class = MySubClass1.class;
// 2) get the class with the type
var c: Class = (Class) type;
// 3) instantiate the class of the subclass of MyClass
var my:MyClass = c.instantiate();

With this solution you can instantiate any subclass of a superclass somewhere else in your code.

JavaFX import

August 14th, 2007

The imports of JavaFX do not behave like every other import concept, they differ from the import idea known from Java and from and idea like “include” or “require” from PHP or other scripting languages has.

After posting questions to the JFX mailing list, I try to summaries the answers people posted to JavaFX import concept:

  1. You can write an import statement everywhere in your file, but it would be called always at the beginning on the evaluate process of a script.
  2. The order of import statements is not the order in which they going to be executed. You must consider that it is randomized
  3. A import twice in a file has no effect, the import will only be executed once.
  4. Loose statements in a file are executed when the import happens.

Registry, Store, Pool concept in JavaFX

August 13th, 2007

The concept of static calls doesn’t really exist in JavaFX.
There is for example no reserved word “static”.

So what can we do, if we still need a static concept? For example a Pool, Store or Registry concept, in which we can store objects by a key. In the following example I have 4 files, that are hosted in the “tmp” package:

1. a Registry class
2. a first RegistryUser1 file, that puts something into the Regestry
3. a second RegistryUser2 file, that takes this something out again
4. and a Main file to run all the stuff.

Lets start with the Main file:

————————————————–

RegistryMain.fx
package tmp;

import tmp.Registry;
import tmp.RegistryUser2;
import tmp.RegistryUser1;

————————————————–

Then the Registry Class:

————————————————–

 

Registry.fx
package tmp;

operation getSharedRegistry(): Registry {
println(”>>> getSharedRegistry()”);
var REGISTER_NAME : String = “myRegistry”;
var sharedObject: Registry = (Registry) <<javax.swing.UIManager>>.get(REGISTER_NAME);

if (sharedObject == null) {
println(”>>> Instantiating ViewRegistry.”);
sharedObject = new Registry();
<<javax.swing.UIManager>>.put(REGISTER_NAME, sharedObject);
}
println(”>>> sharedRegistry = {sharedObject}”);
return sharedObject;
}

class Registry {
private attribute map: <<java.util.HashMap>>;
public operation Registry();
public operation register(key: String, value: String);
public operation get(key: String): String;
}
operation Registry.Registry() {
this.map = new <<java.util.HashMap>>();
}
operation Registry.register(key: String, value: String) {
println(”>>> register()”);
this.map.put(key, value);
}
operation Registry.get(key: String) {
println(”>>> get()”);
var s:String = (String) this.map.get(key);
return s;
}

————————————————–

The first User, that fills the map in the Registry:

————————————————–

RegistryUser1.fx
package tmp;

var input:String = “string goes into”;
getSharedRegistry().register(”MYNAME”, input);

————————————————–

The second User, that reads the data, that we put into in User1:

————————————————–

RegistryUser2.fx
package tmp;

var output : String = getSharedRegistry().get(”MYNAME”);

println(”output = {output}”);