Wednesday, April 29, 2009

JavaFX editing tips!

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


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:



  • One thing I do a lot when experimenting with FX is trying to comment out parts of the scenegraph to try different things.
    The way I comment/uncomment
    in NetBeans is using the Toggle Comment action -- Ctrl-/ or Cmd-/ depending on your platform. But in JavaFX that keystroke does nothing!
    It turns out they have implemented Comment and Uncomment, just not toggle. So you can just use those actions instead (they're in
    the editor toolbar on the right.)

    Or, if you're like me, you really want Toggle Comment. Especially because it has a keybinding. In that case you can install
    this plugin which adds toggle comment
    support for .fx files. It's a trivial module (just two small files (1,2)) so I'm hoping this will be
    included in the next version.





  • The second issue I ran into is that the editor sometimes tells me my source code is wrong - and I'll stare at it without figuring out
    the problem. Turns out - I'm often right. The code is okay, and the background parser is confused. At the
    roundup a number of other people ran into this bug.

    Fortunately, there's a simple workaround for this - just select all (Ctrl-A), hit delete to wipe the file clean,
    and then undo (Ctrl-Z). You'll get your source
    file back, and the file should be (re)parsed correctly. It looks like there is some kind of incremental parsing bug. If you disagree
    with what the IDE error message is telling you, go ahead and try this workaround.

    Here's an example. The editor is telling me I have an invalid assignment -- huh? There's no assignment there!



    If I select all, delete, paste, I get this - all better:



    An annoying bug, but once you know about it it's pretty trivial to work around it.





  • At first I thought code completion was really broken. Let's say I wanted to insert a 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!

    Turns out there's another workaround for this. Just hit Ctrl-Space again! In the Java editor, we distinguish between
    completing only the imported classes and all available classes. If you for example have imported a class named "Video"
    in your class and you code complete on "V", it will not list "Vector" as a match (unless that class is also already imported) -
    it will only show the imported classes that match the V prefix. If you press Ctrl-Space a second time, you get to see all
    V matches. Of course, the code completion dialog tells you this - it says "Imported Items; Press Ctrl-Space Again for All Items" right
    there in the list.

    However, this never seems to bite me when coding Java, because it does something else: If there is no match, it will proceed to do
    the all-items completion on its own - so most people don't have to think about it. The JavaFX editor on the other hand does not do this
    so you end up typing a prefix you know exist, complete, and - nothing.



    The workaround is simple - just press Ctrl-Space a second time when this happens, and voila - the class shows up and gets imported
    as well. Of course - the message at the bottom of the semi-empty code completion window says as much, but since you don't usually
    have to pay attention to this in Java (because it auto imports when there isn't a prefix match) you might have missed it:







  • Import Management. At first I would try to just type "DropShadow { }" - and the editor would complain that it doesn't
    know what I'm talking about. Alt-Shift-i, which imports the symbol under the caret doesn't do anything.
    But it turns out that Cmd-Shift-i, Fix All Imports, DOES work. So use that one instead. It doesn't give you the dialog
    you get in Java showing all the matches; instead it works its way sequentially through all missing symbols.



    P.S. Fix Imports also cleans up unused imports.





  • The Preview Panel seems to be a bit hit or miss. I loved using it, but I would occasionally get lots of exceptions from it,
    so now I only use it for simple scenegraph experiments and tend to just run instead to test stuff - it's been fast enough.





  • The main thing I'm missing is keyboard navigation among occurrences. As you (hopefully) know, Ctrl-Up and Ctrl-Down lets you
    cycle through the yellow occurrences of a symbol when you're editing Java, JavaScript, Ruby, etc. This is really handy since
    it gives you instant "find usages" within a file - just click on a symbol and ctrl-down to cycle through the references.
    JavaFX has mark occurrences - but unfortunately they're missing the small code to iterate this through the keyboard.
    I thought I could just add that trivially along with the toggle-comment code plugin above, but unlike toggle comment which
    took 3 minutes to write, I couldn't see a simple (30 minutes or less) way to get access to the occurrences highlights from
    the outside, so I instead fired
    off an e-mail to the FX editor team - I'm crossing my fingers that they can get this in the next version!





Monday, April 27, 2009

Nice touch, Skype!

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


I work from home, so I rely heavily on Instant Messaging and IRC to communicate with my co-workers, and for video conferencing I use Skype.



I sometimes make typing mistakes. And if the typo is particularly embarrassing, to the extent that I want to fix it to show that I know better,
I usually write something like this:


12:00 I agre.
12:00 s/agre/agree/

Anybody with vi experience or even sed experience will recognize the second line as a search/replace command, so I'm really saying "I said agre but I meant agree". It's reflex at this point - I'll do it for the most minor accident.



I usually only use Skype for video conferencing, not instant messaging. But I just discovered, by accident, that Skype does something wonderful. Instead of showing my substitution command, it applies it to the previous line, instantly, on both sides of the conversation! Look at this:



Ugh, typo, reflexively type s/foo/bar



Voila:



Instead of adding my correction command to the log for the viewer to interpret, it just edited the previous command in place. If I can type this quickly enough, perhaps the reader won't notice!



Chatzilla, Adium, Others - Please please please do this too!



P.S. On the topic of terminal conventions.... I like using ^H's as a "just kidding" device:


12:00 Ok, I'll slap^H^H^H^H tell him about it.

Anyone who's logged into terminals with wrong tty settings will recognize the ^H's as failed backspaces... And I don't want IM clients processing these :)


Friday, April 24, 2009

Catchup

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


A lot of stuff is happening these days, so here are some quickies... is this what people use Twitter for?



  • My brother is visiting me these days. He's in town for the MySQL conference, where he presented his work on memcached. He's also a huge fan of Solaris, so I'm now running OpenSolaris on my desktop machine. It's fun to see how user friendly the (always powerful) operating system has gotten. And his blog entries like this and this take me back to my first job at Sun - working on the Solaris debugger UI. Good memories.







  • Yesterday was "Take Your Daughters and Sons to Work Day", so I brought my kids down to the Santa Clara campus. They had a great time. After "working" in an office while I was on my laptop, we walked around the campus, they met my boss, and I'm sure the highlight for them was having lunch in the Sun cafeteria - which even had a special kids menu for the day. In our walk through some of the buildings we came across a pool table where they got to try pool for the first time.





  • I had the honor of being interviewed on the PlanetCast a week or two ago. That's the third episode of the podcast, but do yourself a favor and listen to the first two - with John Rose on the DaVinci Machine Project, and James Gosling on Java and JavaFX. I've had to drive down to the Valley almost every day the last couple of weeks for meetings, so the timing of my discovery of the PlanetCast couldn't have been better!








  • My friend Carl Quinn just got his Tesla - an all electric super sporty car. He's waited two years or so since he ordered it and they're just now coming off the assembly line. When we got together for a podcast recording session Wednesday night he brought the car, and took each of us for a spin around the block. Wow! It felt like like getting a ride in a fighter jet - but while the acceleration force was amazing, unlike a jet the all electric motor is unbelievably silent. I can't wait for cars like these to get to mass market! There are some pictures of our rides on Jackie's blog, and Joe has a lot more pictures and even some video.




  • The Ruby support in NetBeans 6.7 is coming along nicely. Erno just announced that preliminary Ruby 1.9 support is in the builds now. More details on that in his blog entry. And in another blog entry he's describing work he and Martin did recently to improve the type inference support in NetBeans. Here's some Ruby 1.9 goodness:






  • Finally, we're using JIRA as the issue tracker for the JavaFX project, so I've been using Cubeon for NetBeans a lot recently to handle querying and updating issues from within the IDE. I don't have Eclipse envy, but I'm impressed by their Mylyn project which looks both nice and useful, so I definitely welcome task oriented flow into NetBeans as well. In addition to connecting to repositories like Bugzilla, JIRA and Trac, Cubeon adds some basic support for tasks (e.g. when you "activate" one task, all breakpoints you set in the debugger get grouped and associated with this task and so on), so I'll be playing more with that. I'm using a daily snapshot rather than the most recent published version, and I'm pretty happy with it. I'll probably have more to say about this in another blog entry as I get more experience with it.










Tuesday, April 7, 2009

Add Effects to the right Container!

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


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.* !