All | About | AJAX | BASIC | Creator | General | Java | JavaFX | NetBeans | Personal | Posse | Ruby

20091108 Sunday November 08, 2009

JavaFX Coding Conventions

I've been writing a lot of JavaFX code over the last year. After some tweaking I've arrived at a style that I like a lot. I notice that even on my team there are some variations in how people format their code, so I thought I would document what I like in case this helps others get started. (I did a quick google search and didn't find any JavaFX coding convention documents anywhere. The closest thing I found was a blog entry, but while it contains a lot of good advice, the style it recommends does not match the practice of the JavaFX team (or the Sun Java style) either). Therefore, I thought I would document what I consider good JavaFX coding conventions.

Rather than post them here in a blog entry, I placed them in a Wiki page such that they can easily be improved and kept up to date as I get feedback and in case I change my mind :)

You can find the coding conventions document here:
http://wikis.sun.com/display/JavaFxCodeConv/Home

P.S. I will be speaking at Devoxx in Antwerp, Belgium next week! Hope to meet some of you there!

(2009-11-08 20:29:29.0) Permalink Comments [3]

20090608 Monday June 08, 2009

The Authoring Tool

We lifted the veil on the new designer tool for JavaFX last week at the JavaOne 2009 conference. Here's a screenshot:



The tool made a number of appearances:

The above video links just point to small chapters of each keynote; for full video replay go to the keynote replay page.

I've scanned the blogosphere and twitter for comments on the tool and demos and the feedback is very positive. Here's a particularly detailed blog post with pictures and video snippets detailing the Friday demo. Now we just need to finish the feature set, fix the bugs and polish everything! It's been a sprint for the whole team to get to this point. But we're not building a demo! We're building a product! So we're not getting much of a rest, it's right back to work to finish this thing!


(Photo by Balz Schreier)

P.S. In case you missed it, Larry Ellison from Oracle went on stage and made several comments regarding JavaFX in case the acquisition should happen - here's one article, there are many others.

P.S.2. We had our fourth annual Java Posse BOF live recording session last week. It was a blast. Dick stayed up editing and releasing the podcast the same night. If you're wondering what happened in the middle of the episode, where there's not much audio and a lot of laughing, that's me nearly drowning. I took a big swig of beer just as Joe made a joke; the beer went down the wrong tube, and then I was laughing so hard I couldn't breathe. My eyes were runny and I had beer all over my face and chest. Pretty embarrassing but reportedly also entertaining for others! Here's a photo from our get-together at a bar afterwards:


(Photo by
Toni Epple)

(2009-06-08 11:23:28.0) Permalink Comments [8]

20090429 Wednesday April 29, 2009

JavaFX editing tips!

The NetBeans support for editing JavaFX isn't as mature as for other languages. After working with it for a little bit I've figured out a few things you might find helpful:

(2009-04-29 17:42:49.0) Permalink Comments [3]

20090407 Tuesday April 07, 2009

Add Effects to the right Container!

The Flubber application I described earlier has an old stop-watch style timer with second and minute hands:



Making the clock hand move was trivial using value binding and a rotation transform on the hand graphics object:

transforms: Rotate {
    angle: bind (360.0 / 60 * minutes) - 90.0
}
Since we are using a binding expression, setting the minutes variable anywhere (and yes, assigning to it!) will cause the hand angle to be recomputed and the graphics updated.

Anyway - once we had the clock moving, the first thing we wanted to do was improve the look of the clock by adding a drop shadow. That was trivial; all we had to add was this:
effect: DropShadow {
    offsetX: 5
    offsetY: 5
    color: Color.BLACK
    radius: 10
}
That looked pretty good:



But look what happened when we let the timer run... Where is the light source?



What's happening here is that the drop shadow is rotating with the hand. Not what we want. We were all learning JavaFX that day, so we hacked it, using the following code:
effect: DropShadow {
    offsetX: bind Math.sin(Math.toRadians(handAngle + 45)) * 5.0
    offsetY: bind Math.cos(Math.toRadians(handAngle + 45)) * 5.0
    color: Color.BLACK
    radius: 10
}
Now, the drop shadow offset moves along with the rotation such that the shadow always appears in the right place. It worked, and we moved on.

Now that I understand JavaFX and the scenegraph a bit better I realize that this approach is wrong - there's a much simpler solution! We don't want to apply the drop shadow to the Path object directly, since the path is what we are rotating with our minute angle. Instead, we should simply move the effect out to the surrounding parent. That will apply the drop shadow after the shape has been rotated. Doing that, we can set our drop shadow initialization back to the original simple 5,5 delta, and we get exactly the result we want:



So, think about which node you apply effects to! And by the way, the effects framework is really fun to play with - you should definitely explore javafx.scene.effect.* !

(2009-04-07 19:38:57.0) Permalink

20090323 Monday March 23, 2009

JavaFX Text Component

At the Roundup a few weeks ago we rewrote the old Swing JFlubber application to JavaFX. We had a brand new graphical design done in PhotoShop, and we hooked up the functionality with some swanky effects. I might get into that in another blog entry.

But one challenge we ran into was that of displaying text. In the Flubber application we need to have an editable text area where flub times are automatically inserted and the user can add additional comments. JavaFX makes it easy to throw some simple text in a design, but edit, scroll, and so on? Not yet.

Proper GUI components for JavaFX is coming. But in the mean time, there are some tricks you can use. Put simply, you can use a Swing text area, but without looking like Swing. Here's how. First, create a JavaFX scenegraph node for the Swing text component:

var textPane = new JTextPane();
var scrollPane = new JScrollPane(textPane);
var text: SwingComponent = SwingComponent.wrap(scrollPane);
Let's see how that looks:



Ugh!! Not what we want. Obviously, we don't want the text area to look like Swing... we have a nice background as part of the PhotoShop design that we want to use under below the text. But that's not hard to fix. Java colors have an alpha channel, for opacity. We can use a completely transparent background on the text area to make it just pass through its background (and we have to make the scroll pane nonopaque as well):
textPane.setBackground(new java.awt.Color(0,0,0,0)); // 0 opacity => 100% transparent!
textPane.setForeground(java.awt.Color.WHITE);
textPane.setCaretColor(java.awt.Color.WHITE);
scrollPane.setOpaque(false);
Let's try again:



Much better! But there is still a gray rectangle on top of the graphics, placed there by the border of the scrollpane. We can get rid of that too:
scrollPane.setBorder(new EmptyBorder(new Insets(0,0,0,0)));




Now we're talking! But the font is too small. Dick told me he wants to use a Courier font. So let's try this one:
textPane.setFont(new java.awt.Font("American Typewriter", 0, 14));
Here's what we get:



Ewwwwww! The font is not antialiased. I tried a bunch of things to fix this -- for example setting antialias rendering hints on the component itself, setting the aa system property, etc. It looks like there is a bug here in that the rendering hints aren't picked up properly for the wrapped Swing components. But I did find a workaround that works: We can set the antialiasing rendering hints directly on the graphics object ourselves. That means we need to get involved in the painting of the component itself, but luckily that's trivial. Instead of creating a new JTextPane, we'll create a simple subclass of it where we override the paint method to add the rendering hints:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JTextPane;

public class AntiAliasedTextArea extends JTextPane
{
    @Override
    public void paint(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        super.paint(g);
    }
}
Now we can just change
var textPane = new JTextPane();
to
var textPane = new AntiAliasedTextPane();
and we get this:



Ta-da!

But there is one more problem... What if we add a lot of text:



Scrollbars! We don't want those. This text pane won't be used for much text, so you can just move the caret around like in a text field to navigate the overflow content. So let's turn off the scrollbars:

scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
and with that, the text pane behaves exactly the way we want. Now you can manipulate text in the usual way: textPane.setText(string), textPane.getText(), etc.

While we're at it, let's fix the selection colors as well such that when you select text you don't get the telltale Swing light blue:

textPane.setSelectionColor(new Color(255, 255, 255, 50));
textPane.setSelectedTextColor(new Color(255, 255, 255, 255));
Note again how we can use transparency on this colors to give a nice glass effect on the selection (I also bumped up the font size):



Hopefully these tricks will help you with your text needs until we have real JavaFX components...

(2009-03-23 09:51:48.0) Permalink Comments [8]

20090311 Wednesday March 11, 2009

New Job

Apologies for the recent blog silence for me. It's not that I've been slacking off. Quite to the contrary! The biggest news is that I've changed teams: I'm now working on JavaFX! And more specifically, the designer tool.

If you don't know what JavaFX is, you're probably reading my blog because you're interested in Ruby, Python or the various other languages for NetBeans I've been involved with. If so, fear not - NetBeans language support is in great hands - Erno just improved the Rails dynamic finders code completion for Ruby for example. Of course, as an open source project we can always use more contributors! I've received a bunch of patches for the Python support recently which I've been happy to apply immediately. Keep 'em coming!

Briefly, JavaFX is a new UI stack for Java which makes it trivial to build pretty, dynamic and interactive UIs. While Java has always made it easy to target multiple operating systems, JavaFX makes it easy to target the completely separate platforms of desktop, web and mobile. If you haven't looked into it, you should.

JavaFX has its own language, JavaFX Script. It has some language level features which makes it really suited to building UI applications - from something simple like a literal for durations (so you can write 2m or 5s or 250ms in your source code), to something advanced like variable bindings which give you all of the power of traditional property change listeners, but without the pain (and it's more powerful than that - you can for example bind the rotation angle of a clock hand to an expression which computes the angle from the current time, and whenever the time variable changes the clock hand rotation is updated.) As a Java developer (and a Ruby and Python and JavaScript coder as well) I can truly say I've seen some things in JavaFX Script that I would like to see in other languages. I might talk about that in an upcoming blog entry.

If you're one of the alternate-languages-on-the-JVM people, I think you should seriously look into adding a binding layer for the JavaFX platform to your language. Libraries like Groovy Swingbuilders (and similar libraries for Ruby etc) have made Swing more accessible, but at the end of the day you're still dealing with Swing. If you want to add drop shadows, transition animations etc. a JavaFX DSL would be a much better approach. And besides, we're firing on all 256 cylinders on the JavaFX platform -- from the base Java platform (adding modularity so we can provide a barebones FX runtime), to the graphics system, to components, to the language, and up to the designer tool! I think it's going to shake up the RIA space - which is why I wanted to be part of it.

I promise my next blog entry won't be long in waiting, I've got a bunch of things queued up!

(2009-03-11 18:47:37.0) Permalink Comments [7]