Sunday November 08, 2009 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]
Monday June 08, 2009
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:
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)
Wednesday April 29, 2009 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:
DropShadow. Not knowing
where it lives I would just type DropS to get NetBeans to show it to me and also import it for me (and advantage
of using code completion instead of just typing the name). But that just didn't work - after typing DropShadow and
attempting code completion it wouldn't show me any matches!
Tuesday April 07, 2009
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.
effect: DropShadow {
offsetX: 5
offsetY: 5
color: Color.BLACK
radius: 10
}
That looked pretty good:
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.* !
Monday March 23, 2009 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:
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:
scrollPane.setBorder(new EmptyBorder(new Insets(0,0,0,0)));
textPane.setFont(new java.awt.Font("American Typewriter", 0, 14));Here's what we get:
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:
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):
Wednesday March 11, 2009 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]