- I see differences in rendering between my Mac and PC
- Creating forms manually is much more painful than I would like
- It still feels to early to be using Java FX until proper tooling is available
- Concerns about whether Java FX will be supported once Oracle complete the purchase of Sun
- Java FX seems better at multimedia style websites rather than functional applications (in my opinion), i.e. Ext-JS provides what appears to be simpler form handling and validation.
Friday, 27 November 2009
JavaFX on hold...
Tuesday, 20 October 2009
JavaFX Week 7 (Animation)
The signer certificate has expired
When trying to run the sample application CustomNode_animation_colliding_balls_3steps I noticed that it would not run due to the following error
init:
deps-jar:
keytool error: java.lang.Exception: Key pair not generated, alias
already exists Warning: The signer certificate has expired.
compile:
jar:
standard-run:
java.lang.NoSuchMethodException: collidingballs.MotionBall_3.javafx$run$(com.sun.javafx.runtime.sequence.Sequence)
at java.lang.Class.getMethod(Class.java:1581)
at com.sun.javafx.runtime.Entry.start(Entry.java:63)
at com.sun.javafx.runtime.Main.main(Main.java:80)
browser-run:
jws-run:
midp-run:
run:
BUILD SUCCESSFUL (total time: 3 seconds)
To fix this, I simply went to the project properties, selected the 'application' tab, then disabled the 'self signed jar' option. I guess another project already has stored a certificate that conflicts with this demo.
Adding a little debug on-screen
I was asked whether we could output some debug quickly to see the values of the x position offset (xoff), scale and xflip, after a little consideration I added a VBox to provide a simple layout manager and then added three labels that were bound to those values. Hey presto, simple on-screen debug.
import javafx.ext.swing.SwingLabel;
import javafx.scene.layout.VBox;
.
.
VBox {
content:[
SwingLabel {
text: bind "Xoff = {xoff}"
width:400
},
SwingLabel {
text: bind "Scale = {scale}"
width:400
},
SwingLabel {
text: bind "xflip = {xflip}"
width:400
}
]
}
.
.
Flipping Sharks!
It took a while to work out what timeline was required to move the sharks form the top-left of the screen to the bottom-right, to include the zoom and flipping of the Sharks.
I used three variables that I bound at different locations in the scene graph (actually I had help on this one by collegues at work).
var scale = 0.3;
var xoff = 0;
var xflip = 1.0;
My timeline was always pretty much right, but the key part is in the next section
var st = Timeline {
keyFrames: [
at(0s) {
scale => .3;
xoff => 0;
xflip => 1.0
},
at(2s) {
scale => 1.0 tween Interpolator.LINEAR;
xoff => 300 tween Interpolator.LINEAR;
xflip => 1.0
},
at(2.5s) {
scale => 1.0 tween Interpolator.LINEAR;
xoff => 350;
xflip => -1.0 tween Interpolator.EASEBOTH;
},
at(4s) {
scale => 0.3;
xoff => 0;
xflip => -1.0
},
at(5s) {
scale => 0.3;
xoff => 0;
xflip => 1.0
}
],
autoReverse: false,
repeatCount: Timeline.INDEFINITE
};
The Sharks ImageView was not happy having a transform applied to scale the sharks position and flipping in one go, so Chris at work came up with this option to have a sequence of transformations that are applied one after the other.
var shark = ImageView {
.
.
transforms: bind [
Transform.scale(scale,scale),
Transform.scale(xflip,1,theImage.width/2,0)
]
translateX: bind xoff
.
.
};
Sunday, 13 September 2009
JavaFX Week 3.3 - Good video tutorials / overviews
Introduction to JavaFX - Jim Weaver gives a high-level overview of JavaFX, including lots of code snippets. This is a little slow paced and uses the command-line compiler - I assume this is before the Netbeans plugin was available. Covers closures too, which is in my opinion 'advanced' rather than an introduction topic. Closures are 'the ability to access variables in the context that the function was created within'. This video is worth watching to understand binding, including bi-directional binding and triggers - useful for form-based user interfaces for example.
JavaFX SDK - Danny Coward (excellent presenter) shows exporting from Photoshop and some good demonstrations of JavaFX in use (includes playing media with emphasis of deploying the same app on multiple devices, i.e. mobile devices and desktop, integration between JavaFX and Javascript in the browser).
Overview about the API - Richard Bair and Martin Brehovsky cover the API, primative types, sequences, operators, flow control, binding, object literals, scene graphs, animations, transitions. I recommend this video the most.
An interview with the JavaFX team - The Java Posse interviews the JavaFX team.
- What is JavaFX?
- Why a new language?
- What happened with the JavaFX launch? (There was a problem with the launch)
- How should people evaluate JavaFX?
- What new features does JavaFX bring to UI developers?
- What does binding allows us to do?
- What is the JavaFX runtime size?
- How should you prepare your libraries for use in JavaFX
- How to develop new JavaFX components
- Any plans to use JavaFX script in non UI domains (i.e. server)
- Is there a recommended client/server communications API
- Where's the interfactive JavaFX shell
- Any plans to support scene graph for other JVM languages
- What other technologies will interact with the JavaFX language
- Any plans to create a JavaFX component market place
- Will there be a JSR for JavaFX?
- Why should Flex/Silverlight developers want to look / change to JavaFX
- What about the Applet experience
- What about JavaFX tools
- Support from Eclipse?
- Anything else you want to share with
Enjoy!
Friday, 11 September 2009
JavaFX Week 3.1 New knowledge (and broken examples)
Additionally a nod to Russell Miles, an experienced developer and author of many books, but more importantly a friend, he has blogged a response to my 'first impressions of JavaFX' post. He didn't agree with all my points, but I would like to put him straight on one thing - JavaFX is statically typed, evidence is here from the horses mouth...
Source: Learning JavaFX script PDF resource (By Robert Eckstein and the Authors of the JavaFX Programming Language Reference, July 2007) "The JavaFX Script programming language (hereinafter referred to as JavaFX) is a declarative, statically typed scripting language from Sun Microsystems, Inc."
My blog today covers some interesting points from that documentation...
JavaFX is primitive
(Primitive types)The JavaFX programming language provides only four primitive types: String, Boolean, Number, and Integer. Note that, unlike the Java programming language, primitives are written with an initial capital letter! So I guess that's something along these lines
JavaFX Java equivalent
String java.lang.String
Boolean boolean
Number floats and doubles
Integer byte,short, int, long
But you can fully qualify the Java type to get a Java Boolean, if that's what you really, really want.
// var b : Boolean = null; <-- does not work
var b: java.lang.Boolean = null;
The feedback I received on the JavaPosse was that using nulls is BAD BAD BAD, it makes some sense when you are using objects that map on to database objects - but even that apparently is bad practice, a boolean that's null to me implies 'not known', so I think it's okay - the user might not have specified a value, so you don't want to assume 'false' or 'true' - because they will have specific meanings. I guess I might need to re-evaluate my thinking a bit, but I like my user-interfaces to not force the user to enter all the fields - to the extent that nulls are used where the user has not specified an intentional value.
In my last post I was struggling to understand why Boolean in JavaFX can't be null, but it now makes more sense, knowing that Boolean is mapped to a primative boolean. Why does that make more sense?... Well, lets put our Java hat back on for a second...
public class JavaCode {
public boolean getPrimativeBoolean() {
return null; // WILL NOT COMPILE
}
public Boolean getObjectBoolean() {
return null; // THIS IS OKAY
}
}
So there we go, the answer is Boolean in JavaFX is a primitive boolean in Java, and because Java primitives can't hold a null, then you can't do it in JavaFX either. So I still need a solution to hold null values, but at least I understand why I can't using Boolean in JavaFX!
Of course I can simply wrap a primitive boolean in some simple class, but I am worried that I might cause some problems when I want to introduce binding later on.. i.e. I try to bind to my wrapper object, but the wrapper object doesn't actually change.
Oh, and that explains why String could be set to null, because in Java there is no primitive String - only the object based String. See, it all makes sense now ;-)
But, then they mention cardinality operators - take a look at this...
var variableName [: typeName] [? | + | *] [= initializer];
Operator Meaning
? Optional (For example, it can be null.)
+ One or more
* Zero or more
So, now it sounds like I can set my Booleans to be nullable?
var myBool : Boolean? = null;
var myBool : String ? = null;
Hmm, well neither of those work for me! Netbeans says "Sorry, I was trying to understand a qualified identifier but I got confused when I saw '?'", bless - how honest! Maybe it's because I'm reading a PDF dated back to July 2007 and perhaps the language spec has changed since. Hopefully I will catch up with this a little more later.
Multi-line Strings
Unlike Java you can create a String over multiple lines...
var s = "This
contains
new lines";
Sequences (again)
In one of my posts I said that it would be nice to create a new sequence based on the 'values' of another sequence - rather than rely on the index numbers. Well, you can - and very nicely too...
"If some of the expressions inside the square brackets look odd, don't worry. They are actually Xquery-Update (similar
to XPath) predicates. In this case, the period inside the brackets does not refer to an index but instead to the value
of the index. JavaFX technology will test each one in the array until the expression is true, then apply the insert."
var x = [1,2,93,55];
insert 10 after x[. == 93]; // yields [1,2,93,10,55]
But that does not work for me in Netbeans "Sorry, I was trying to understand an expression but I got confused when I saw '.'." I am starting to get the feeling that either I don't have the latest version of Netbeans, or the plug-ins are out-of-date.
These examples do not work for me either:
// insert into weekdays after weekdays[. == 3];
// var a:Integer* = select n*n from n in [1..10];
// var a:Integer* = select n*n from n in [1..10] where (n%2 == 0);
// var a:Integer* = select n*m from n in [1..4], m in [100,200] where (n%2 == 0);
I did find some combinations that worked and that I was comfortable with
var days=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];
var weekdays = days[0..5];
var daysStartingWithT = days[p | p.startsWith("T")];
var mixedUp = [ days[p | p.startsWith("S")], days [p | p.startsWith("T")] ];
for (day in mixedUp) {
println(day);
}
Results in
Sat
Sun
Tue
Thu
Async - 'do'
Since my last blog covered asynchronous subjects, I found the following code block impressive - but alas, once more, I can't get it to run, it does not recognize 'do', I can't imagine that they have taken something so useful out. Perhaps someone can tell me what I am missing? :-(
// in the AWT Event Dispatch Thread (EDT)
var result = new StringBuffer();
do {
// now in a background thread
var url = new URL("http://www.foo.com/abc.xml");
var is = url.openStream();
var reader = new BufferedReader(new InputStreamReader(is));
var line;
while (true) {
line = reader.readLine();
if (line == null) {
break;
}
result.append(line);
result.append("\n");
}
}
// now back in the EDT
System.out.println("result = {result}");
Does anyone know where I can get a PDF that contains all of the JavaFX language specification - I really need something up to date for the train ;-)
Tuesday, 8 September 2009
JavaFX Week 3 - Async
Background tasks in JavaFX - A good article on binding variables to the user interface and discusses the fact JavaFX1.2 is single-threaded and how to deal with writing to variables from a background thread. One comment highlights a bug in JavaFX 1.2, where the percentDone from a Task is returning 0..100 instead of 0..1 - something to bear in mind.
JavaFX 1.2 Async blog by Baechul - Well worth reading, although it might be a bit heavy for a newbie to JavaFX, especially if they haven't done Java before. I've created a class diagram that acts as a summary of this blog because I found it so useful as an overview...
And a version with comments (but I'm not convinced that they will be readable)...
Basically there seems to be some rules to follow, they seem similar to Swing
(Thank you philho for correcting my post in your comments!)
- You must update the user interface components from the EDT (event dispatch thread)
- User interface stuff happens on the EDT, so you can use the javafx.lang.FX.deferAction class to post actions to the UI thread (Presumaly this is similar to SwingUtilities.invokeLater).
- Typically you implement the RunnableFuture interface in one class, then extend JavaTaskBase in another class. The JavaTaskBase class has a create method that you override to create your RunnableFuture instance.
Jim Weavers JavaFX Blog - shows an example where you can start multiple threads and cancel them, with a user interface showing the progress of each thread.
What seems very clean is that the JavaFX API also uses the thread classes identified above, so for example,HttpRequest extends JavaTaskBase. Some user interface controls take advantage of this, notibly the ProgressBar integrates nicely with the JavaTaskBase class. This means that as data is transferred using the HttpRequest object, the ProgressBar can be set up to automatically update to show the progress!
Interestingly you are limited to eight threads running in parallel in JavaFX, this sounds a little limiting.
I hope some of that is interesting for you.
Regards,
Rob.
Monday, 7 September 2009
JavaFX Week 2 - Oddities
Static types / Inferred types
It became obvious that with JavaFX the types can be inferred, or specified by the programmer. As an experiment I tried to infer the type of a variable and then re-assign the value to some other value that just happened to be a different type, it turns out that's not allowed...
var x; // Type not specified
x = "Rob"; // x becomes a String type
// But now we can't set it to an int
// because it's not compatible!
// x = 55;
JavaScript would enable you to re-assign anything to the variable, because it's a dynamic language and although JavaFX looks kind of dynamic, it's not. I guess that's because it uses Java under the hood and therefore it has to be statically typed. So then I thought, how could I make this 'feel' a little more like JavaScript. My thoughts were to simply specify that it was an 'Object', after-all everything must extend object directly, or indirectly.
var x2:Object; // So will this work?
x2 = "Rob2";
x2 = 55; // Yes
Whether this way of thinking is wrong, I don't know yet - it's too early to tell.
JavaFX data types can't be null
Okay, this one makes me feel really un-comfortable, why wouldn't you want the ability to make something null - All of these are illegal?
// null - For the JavaFX data types, you
// can't set them to null!
// var b:Boolean = null; // Invalid
// var i:Integer = null; // Invalid
// var n:Number = null; // Invalid
Now, the interesting bit here is that Booleans default value is false, Integer is 0 and Number is 0.0. Are there any exceptions to this? Well, it appears so...
var s:String = null; // This compiles!
Oddly the above works - but why is it different between String and Boolean for example? This made me think - 'I know, JavaFX can re-use existing Java libraries, so if I access a Boolean from a Java class that sets it to null, it must be null!'.
JavaClass.java
package week2blog;
public class JavaClass {
public Boolean getMeANullBoolean() {
return null;
}
}
Main.fx
var jc:JavaClass = new JavaClass();
var b2 = jc.getMeANullBoolean();
println("b2={b2} type:{b2.getClass()}");
// b2=null type:null
So, null is okay when integrating with existing Java code, so what can't I do it in JavaFX - I don't know yet, so I'll have to do some more digging!
My only thought was that perhaps JavaFX String is not the same as a Java String object? So one last experiment here:
println(b2.getClass()); // returns NULL!?
println(b2.TYPE); // boolean
var myb:Boolean;
println(myb.getClass()); // returns java.lang.Boolean
println(myb.TYPE); // boolean
Now that's odd isn't it! The JavaFX ones class is NULL, whereas the Java one is java.lang.Boolean... So this would imply that they are different?
Sequences
I like the sequence stuff - that's pretty neat, but I couldn't help but think that I don't want to do things by the index of an object in the sequence, why couldn't I look it up, for example:
var days=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];
var weekdays = days[0..4];
// Would be nice to do something like this, but I haven't
// found anything yet:
// var weekdays2 = days[0..weekdays["Fri"]];
// var weekdays2 = days[0..weekdays.indexOf("Fri")];
Expressions / functions / returning null
I have to admit I am a little confused about when a null is expected to be returned from an expression or functions. The documentation states
the JavaFX Script programming language is an expression language, which means that everything, including loops, conditionals, and even blocks are expressions. In some cases (such as while expressions) the expressions have Void type, which means they don't return a result value.
Expressions will return the value of the last line, but functions will return null / void if no return type specified.
So taking these a bit at a time...
If this is true 'If no return value is specified, a function returns Void by default', then why does the following return a number?
function test4() {
{
var x = 10;
}
}
println("test4 = {test4()}"); // this displays 10 still
If this is true 'In some cases (such as while expressions) the expressions have Void type' then I concur that this is true because this code snippet results in "Void type not allowed here".
// In some cases (such as while expressions)
// the expressions have Void type
function test5() {
var x = 0;
while(x==0){
x = 10;
}
}
// Can't do this "'void' type not allowed here"
// println("test5 = {test5()}");
If this is true 'but functions will return null / void if no return type specified' then why does this return a number!...
function test() {
return '9';
}
function test2() {
var x=10;
}
println("test = {test()}"); // returns 9 (as a String)
println("test2 = {test2()}"); // returns 10 (as a Number)
I can only get it to nag / not return a value if I say that the function doesn't return anything, by specifying a Void return (notice the capital 'V' by the way!).
function test3() : Void {
var x=10;
}
// Can't do this because test3() can't return anything
// println("test3 = {test3()}");
I hope that I have given you some food for thought, if you happen to know any answers to those oddities, then please post a reply!
Thanks all,
Rob.
Saturday, 5 September 2009
JavaFX - First impressions
I have just started following a free online course from the Java Passion series (by Sang Shin). If you are also interested in joining, visit JavaPassion.com.
This post is to cover my first impressions of JavaFX (1.2), using my new MacBook (Mac OS X 10.5.8 Intel Core 2 Duo with 2Gb RAM).
My previous experience has been heavy use of Java with Swing for client-side programming and the Spring framework with JSP for server-side programming. I decided to increase my knowledge by learning how to program the iPhone and in addition learn JavaFX (which currently will not run on the iPhone - damn!).
Having no ties to Sun, these posts will be independent and may contain positive and negative views of Java FX and associated technologies.
By following the link for JavaFX.com using Firefox 3.5 on my Mac crashed FireFox the first time I visited the page. I have re-visited the page today to make this post and I am now receiving the message "An applet from 'dl.javafx.com' is requesting unrestricted access to your computer". Impact - Poor user experience. Solution - This could be FireFox 3.5 that experienced the problem, so perhaps there is nothing that Sun could do here, but an explanation or warning that I need to accept the request to download the applet should have been provided, additionally why does the applet on subsequent visits to the page require unrestricted access to my computer - this makes me nervous, surely only certain applications I launch should ask for higher permissions? Impact - Concerns over security, Solution - Explain this up-front, or make it so that JavaFX.com site does not require full permissions. Should I allow the option to 'Allow all applets from dl.javafx.com access'?! - Well I've now said yes.
After my first visit to JavaFX.com I was asked for my admin username and password within the Mac OS to install the Java FX runtime, I was surprised to find that I was not shown any progress bar or indication that the installation was happening - it looked as though it had failed.
The bottom third of the JavaFX.com website was a solid blue region with no indication that Java FX was not installed and then suddenly I noticed that this area became populated and Java FX was working. Impact - Poor user experience. Solution - A simple progress bar or 'installing' splash screen.
The headings on the website are 'Explore', 'See' and 'Learn'... Okay, is it just me that doesn't know the difference between 'explore' and 'see'? Is it obvious to you which one the samples are in? Wouldn't it be better to call it 'samples'? Explore actually gives you some marketing blurb, a break-down of what it is with a 'learn more' link, that takes you to a completely different page than the main 'Learn' button. Impact - User confusion. Solution - Yes I know this really is a pedantic thing, but simply naming the main buttons makes it a cleaner first-impression.
Within the 'see' section (sorry 'samples'), you find plenty of samples. But, in my opinion lots of them look amaturish and they are embarrasing to show as examples of how powerful JavaFX can be. Impact - Makes Java FX look crap, Solution - Move all the basic ones to a developer section as learning aids and only keep the professional looking samples. One of the samples is a video, very highly compressed, this makes video support look bad - I'm sure they done this for bandwidth reasons, but it does look poor from a user perspective.
Whilst viewing some JavaFX samples, I scrolled the browser window using the scroll-button on my mouse. During the scrolling the pages were flickering and sometimes the video seemed to disappear until I scrolled slightly further. Impact - User disappointment, solution - I guess we just have to wait until JavaFX has matured a bit, or this could be a FireFox / Mac only issue.
Whilst trying to use the JavaDoc for the first time, I was reasonably impressed with the contents of the documentation, but the user-interface seems as clunky as hell, for example, clicking on any subject causes the tree-view of the topics to jump back to the top of the screen, in fact, I'm sure it's a full page-load, shouldn't this be using AJAX by now? Also, the font's seem too big and stuff just generally takes up too much of my screen real-estate. Impact - Makes using Javadoc slow, solution - offer the typical javadoc view, it is fast, clean and good-enough, you don't have to JavaFX'ify everything you know! Oh, and a little bug in Netbeans 6.7 could be that if I select a JavaFX keyword and then right-click and choose Javadoc, it does nothing. I then try to visit the Javadoc search window and it ends up searching endlessly - never completing.
NetBeans seems to have good support for the language, the auto-completion worked a treat and the code is very easy to read - I'm very impressed with this bit. My only criticism would be that there's no built in visual editor at this stage, I certainly don't want to use Photoshop to generate a simple form and export the artifacts for integration. Although there does seem to be a program called 'DataBox' that I will be trying out soon, visit DataBox.
I've written a note on a post-it note, that says "Warnings of unrestricted access x 2, one after the other", but unfortunately I can't remember what this was all about, but I know I was thinking at the time 'This is not a good user experience'.
I did find some of the branding confusing, one minute we are on a site talking about JavaFX, then the next minute there are popups about Java Web Start and then JNLP launchers and then applets... what exactly is the user supposed to call them? Even in the samples I couldn't work out whether the ones embedded in the browser were 'applets' or 'java fx' plugins and those that popped up outside the browser were... erm, applications through web-start? Problem - confusing message, Solution - call everything Java FX and make the samples launch them all the same for consistency.
When launching the samples, some would cause a dialog to be popped up with the percentage complete, then launched in a separate browser not in-line with the page, this meant I also ended up with lots of .jnlp files in my download directory... this is messy for the user and means that I need to clean up afterwards. Solution - perhaps these .jnlp files should be in the temporary internet files location unless the user chooses to 'keep' the download?
So my overall first impressions
JavaFX language - 9 out of 10
User experience - 7 out of 10
Quality of samples - 3 out of 10
Developer support - 9 out of 10 due to lots of samples, online documentation and the JavaPassion resource.
So, if I only had one sentence to wrap up my feelings "Java FX is very satisfying from a developers perspective, but needs some polish for the users experience to improve".
Thanks for reading my first post, please post comments to keep me motivated!
Rob.