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


Monday, March 23, 2009

JavaFX Text Component

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.


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



Monday, March 16, 2009

NetBeans Screenshot of the Week 42: JavaScript Native Interface

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.


At the Roundup last week I talked to
Robert Cooper, who's doing a lot of interesting work with GWT (Google Web Toolkit). In GWT (which compiles Java to JavaScript), you can embed JavaScript directly within the Java files inside comments with special markers. Robert mentioned that IntelliJ has a nice feature for GWT programmers where your native JavaScript snippets get JavaScript highlighting etc.



I figured that would be a trivial thing to add to NetBeans with our language embedding infrastructure. Sure enough, the patch just adds 13 lines of code. Here's a screenshot - showing JavaScript (regular expressions etc) inside Java code (with packages etc) - it's inside comments that start and end with -{ and }-:




If you want this functionality in your own 7.0 build, just download this module nbm, or apply the patch to your own build.


Thursday, March 12, 2009

Java Posse Roundup 2009

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 just got back from the Java Posse Roundup 2009. It was our third year (blog entries from 2007, 2008), and therefore I can add "as usual" when I state that it was a wonderful time.



This year's topic was "developer productivity", which is obviously a passion of mine, so I found all the technical sessions thoroughly enjoyable. We recorded all of them so they will be released slowly through the regular podcast channel.



I was able to redeem myself from last year's skiing disaster but not falling doesn't make very compelling video...



Another highlight is the lightning talks. This year we had two hours of lightning talks every night. We'll be releasing those on a quicker schedule as YouTube videos in our
YouTube channel. I can recommend Barry Hawkins' talk as a starter. The nice thing about lightning talks are that they are short so go ahead, give it a try!



In order to enforce the 5 minute rule for lightning talks, we wrote a little timer app, as seen in this picture:




The laptop on the left is running our downcounter. It starts at 5 minutes, and when it gets down to 0 it plays a sound effect which politely asks the user to, ehm, stop. We wrote this app as a collaboration on the first day of the conference, during the language dojos. We had 3-4 sites where different people studied Scala, Groovy, Python, Fan and JavaFX, according to their interests. In the JavaFX group we played around with the language in the morning, and then decided to build something real - the countdown timer. We needed a sound effect to play when the timer expires, so we held up one of our conference audio recorders and all at once yelled "Shut Up!" into it. In the room next door Dick Wall had just started talking about Scala, and our brief recording session apparently caused some confusion...



P.S. There are a lot of pictures from the Roundup on flickr.
The below are by Joe Nuxoll.



Crested Butte, Colorado by night:



The first day of the Open Conference we held a languages-on-the-JVM dojo. This is a picture of those of us playing with JavaFX:



The lightning talks schedule for the Tuesday night:



On Thursday we had a progressive dinner where each household served one course for the other participants. Carl made Indian Style chicken wings and Ido is getting ready to serve:



Dick and Dianne talking during the progressive dinner.