Tuesday, June 29, 2010

Don't Use Implicit Return Types

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.


JavaFX, like Scala, is a fully statically typed language. However, unlike Java, it allows you to omit type declarations in many places, since it can infer it. Coupled with the fact that you can use expressions as statements, and that the last expression in a function will be the return value, this lets you write really simple and clear code.


def s = "Hello";
def len = s.length();
function product(a: Number, b: Number) {
a * b
}


The function above shows an "Implicit Return Type": The compiler figures out the return type, which in this case will be a Number, and that is the signature computed for the function.

Unfortunately, this can sometimes lead to trouble! Here's a real-world example:

public function clearSelection() {
selected = null;
}


This function clears the selection in a node. The intention of the developer was probably for this function to have a "void" return type. But that is not the return type! The last statement is an expression, an assignment, which has the type of the left hand side, which is actually a node.
So the return type here is a Node! And it could easily have leaked an implementation class too.

This may not seem like a big deal here, but what if a subclass wanted to override this function? It would try this:


override function clearSelection() {
super.clearSelection();
moreStuff();
}


And this would fail compilation, with a surprising error message:

File.fx:1: incompatible types
found : void
required: Node
override function clearSelection() {
1 error


That's right, your subclasses will now need to deal with this return type too! If it's an implementation class, they're in trouble!

There are other reasons implicit return types are bad too. Here's a function specifying a desired padding for a node:


public function padding() {
5
}


The user may have intended for this to be a Number, but since the default is "5" instead of "5.0", the implied type here is Integer, which means that subclasses will need to round their desired padding to an integer. And this is not always a good thing - see the pixel considerations article.



For all of the above reasons, our Coding Conventions Document states that you should not use implicit types, at least not for any non-private API. That includes package, protected and public functions. However, it's a simple mistake to make. We've all made it! For that reason, to help track these down, I've created a quickfix for NetBeans which identifies and fixes these problems. Here's what happens if you look at a function like the one described above:



The light bulb and underline warns you that there is a problem here. Clicking on the light bulb, or pressing Alt+Enter when the caret is on that line, shows this info:



It's telling you that you have an implicit return for a public function, and it's offering to insert the actual, current return type of the function. It's also offering to make the function Void.

Pressing return will fix the function:



There are certain return types you cannot express in JavaFX script - such as returns including generics signatures. The quickfix won't warn about those since there is nothing you can do.




You can find the module on the Plugin Center here. Hopefully it will be as useful to you as it has been to me!

P.S. We discussed this topic (implicit return types in JavaFX and Scala) for a while on the latest
Java Posse Podcast episode.


Thursday, June 17, 2010

NetBeans 6.9 Released

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.



NetBeans 6.9 has been released.

There are important improvements for everyone here - whether you're a Java developer, JavaFX developer, Ruby developer, PHP developer, C++ developer, ... or all of the above :-)

Since I spend most of my time writing JavaFX and Java code, by far the biggest improvement in NetBeans 6.9 for me is the JavaFX support. While there is still room for improvement, editing works pretty well now. In particular, the source code formatter works well on most source files and constructs, so I've used it to reformat some of our large and complicated source files, though to be on the safe side I've checked the diffs carefully before checking in (and turned on whitespace diffing in the version control). I occasionally have to make manual tweaks, but it's really helpful in cleaning up poorly formatted source files. And Go To Declaration now works reliably! The debugger still needs work. Apparently this needs some help from the compiler so hopefully the combination of JavaFX 1.3.1 and NetBeans 6.9.1 will address that.

One huge improvement in 6.9 is the reduction of scanning delays. In addition to performance fixes in that area, there are two life saver features:


  1. Running is no longer blocked when a scan is in progress. Even if it's scanning, running starts immediately. This used to drive me crazy!
  2. I can turn off some of the extra aggressive scanning! There is an option for this now, so I can turn off automatic timestamp checking and instead perform scanning manually if I should need it:



    (In case it's not obvious -- I'm talking about the checkbox at the bottom of the above dialog.)

    If you turn off automatic scanning, you can invoke it explicitly:





There are many other new features, and I'll get back to some of them in some other posts, but for now I'll leave you with a link:
Git Plugin compatible with NetBeans 6.9.


Thursday, May 20, 2010

LCD Subpixel Rendering

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.


While I'm on the topic of pixels -- here's another tip. This one is both Mac OSX and NetBeans (well, Swing) specific.



Subpixel rendering, an antialiasing technique, makes text look much sharper (wikipedia article).
Subpixel rendering was added to Java 6, so the NetBeans source editor looks great on Windows and Linux provided you are running Java 6. Antialiasing was never an issue on Macs, where the JDK used its own native graphics renderer which had subpixel rendering all along - until now!!

Here's NetBeans on Linux and Windows:



Let's zoom in. Notice the "strange" colors at the perimiter of the font strokes; they look strange here but oh-so-good at the proper resolution on an LCD:



Unfortunately, when Apple released Java 6 on the Mac, they switched the default graphics renderer over from their own "Quartz" renderer to the standard JDK one. That shouldn't be a problem, since Java already renders LCD text, right? Wrong! For reasons I don't know, subpixel rendering is NOT working on the Mac with the standard renderer. Therefore, by default, NetBeans text looks blurry (because it is only grayscale antialiased) on Macs.

This is easy to "fix". Just switch the rendering back to Quartz. You can do that with the following flag, added to the netbeans.conf config file:


-J-Dapple.awt.graphics.UseQuartz=true

The -J flag just tells the NetBeans launcher that the rest of the flag is a flag for the Java interpreter, and the -D flag says set the system property apple.awt.graphics.UseQuartz to true. Therefore, in your own Swing applications you can do the same thing, just drop the -J flag.

(The config file is in a place like /Applications/NetBeans/NetBeans 6.9 Beta.app/Contents/Resources/NetBeans/etc/netbeans.conf and you would add these flags to the netbeans_default_options line.)

Here is a before-versus-after screenshot; this will only make visual sense to you if you're viewing this on an LCD screen!



The subpixel rendering text is on the left.

Here's a zoomed in view, which shows the default (non-LCD renderered text):



And here's what you get when you turn on Quartz:



I presume Apple turned off Quartz by default in Java 6 for a reason. Does anyone know what it is? The JavaFX Release Notes mention some memory leaks. I've been using the flag to turn LCD text back on since I switched to Java 6 on the Mac a year ago, and it doesn't seem to have any adverse effects for normal NetBeans usage (mostly text oriented; I don't do UML editing etc).

More importantly, does anybody know why subpixel rendering from the JDK doesn't work on the Mac since it works everywhere else? Is there a way to trick it to work with rendering hints etc?

P.S. Speaking of launcher arguments - I have one other customization too. I add -J-d32. This tells the JDK that I want a 32-bit VM. I haven't measured personally what this buys me, but I saw that Charlie Nutter recommended it for NetBeans usage, and he certainly knows his way about VM tuning parameters!


Tuesday, May 11, 2010

Bay Area JUG Roundup 2010

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.



If you live in the San Francisco bay area, I hope you can come to the Bay Area Java User Group Roundup 2010 tomorrow night! It is going to be held at the Oracle conference center, and both beer and dinner will be provided. There will be an update on the java.net migration, and the Java Posse are going to record a live podcast. Note - you need to sign up in advance so visit the event details page.

Hope to see you there!



Monday, May 10, 2010

Pixel Considerations

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.


Antialiasing makes lines and shapes look smooth - though sometimes at the expense of sharpness. What if you're trying to draw a horizontal or vertical line where you don't need antialiasing? You might be under the impression that if you position your shapes at round integer positions, you will avoid antialiasing.
But it's not quite that simple - so avoid trying to be smart with layout code like this:


...
label.layoutX = (width - labelWidth) / 2 as Integer;
....

The idea here is that when you're placing something in the middle you might end up with a fractional value, say 42.5, and so you added the "as Integer" to round things to a whole number to avoid introducing antialiasing.

Well, this may have exactly the opposite effect! Take a look at the following picture, which shows two rectangles. Both rectangles have a stroke width of 1.0, and one of them is positioned at a round integer, and the other one is positioned at 0.5.



Here's a zoomed in view which makes things clearer:



Obviously, the rectangle on the left is blurry because antialiasing is attempting to show the line as being somewhere in the middle between them. The rectangle
on the right on the other hand is clear and crisp because the lines overlap EXACTLY with the pixel grid the line is rendered into.

Here's the thing though: The rectangle on the left is the one that was positioned at round integers, and the rectangle on the right is the one positioned
at round integer + 0.5 !

So should you run out and ensure that all your horizontal and vertical edges are positioned at 0.5? No. The key here is the stroke width. Take a look at the following figure, where I have position rectangles with different stroke widths (1, 2, 3) and different pixel positions (0, 0.25, 0.5).



Zoomed in:





As you can see, whether you match the pixel grid perfectly depends on the stroke width and the pixel positions. This actually makes sense. Think of your pixel grid as having x coordinates at the boundaries of each pixel. In other words, "0.0" is the left edge of the first pixel, and 1.0 is the right edge of the first pixel. The line position has to be the center of the stroke. So if you want to have a line of thickness 1, then that line will run exactly through the pixel, so we must position its center at x=0.5. When the stroke width increases to 2 however, the center will be in the middle (e.g. 1), and so we should position it at a round number. And so on.

When you're dealing with large shapes this isn't a big deal. But if you're trying to paint a grid (like the one below), a pattern, or small controls (like disclosure arrows - which is how I came to look into this), it can pay off.



By the way -- on OSX there's a nice screen zoom (hold the Option key and then do a two-fingered drag on the trackpad up or down) which makes it easy to zoom in and look at the pixels for anything on the screen. But unfortunately it doesn't show pixels as square, it does more blending, so it's much harder to tell what's going on at the individual pixel level. Get an image editor which lets you zoom in with clear pixel boundaries, or even a screen magnifying lens. Here's how the builtin screen zoom looks - as you can see it's not as clear as the pixel zooms above:



UPDATE: Marius taught me in the comments that you can turn off the OSX zoom smoothing in the Universal Access options. Sweet! I can now instantly check the pixels without going to an intermediate screenshot! Thanks!

Finally: Jonathan Giles from the JavaFX controls team has been doing a great job aggregating and summarizing interesting FX articles each week -- highly recommended if you're doing anything with JavaFX.


Thursday, April 29, 2010

nbgit for NetBeans 6.9 beta

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.


My brother was asking me for a version of nbgit (git support for NetBeans) that works with NetBeans 6.9 beta. I've uploaded one here. By the way, look at the Options wiki page, and especially the sections on Custom Actions, for useful configuration tips for nbgit.



Wednesday, April 28, 2010

IDE tip: Go To Implementation

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.


One of the best parts of using an IDE instead of an editor is "Go To Declaration". When you hold the Control key (or the Command key on Macs), identifiers under the mouse turn into hyperlinks and when you click on the hyperlink you jump to the declaration point of say the method call.
You can also just hover over the hyperlink, and a tooltip will pop up and show you the signature of the identifier - the fully qualified type name, method arguments, and so on.

But what if the thing you are pointing at is an interface? Or an abstract class? Good Java programming style dictates that you should prefer interfaces over implementation types, so your code will typically only know about the interface or abstract type, and when you jump to the declaration, you go to the boring interface method definition, rather the interesting bits in the implementation!

This is what the Go To Implementation feature is for. And I have a confession to make: I didn't start using this until recently. At the recent IDE tips roundup session, somebody asked whether NetBeans supported Go To Implementation. By instinct I went to Google and looked for a NetBeans plugin to do it, and found one. Unfortunately, it was old and only worked with older versions of NetBeans. Uh oh. Then on a whim I decided to look in the Navigate context menu in NetBeans - and lo and behold, it's right there!



And you don't need to use a context menu to access this feature. The trick is to use a second modifier key to the normal ctrl-click on the identifier! In addition to the control key (or command on Macs), also hold the Alt key (Option on Macs).

Here's how it works. First, let's say you want to go to the actionPerformed implementation. You ctrl-click the identifier:



...and that takes you into the abstract method declaration. (In this specific case, the method is in a read-only file inside a .jar file, which is why NetBeans marks the whole file in gray)



That's not what we want. Go back to the previous editor location (Ctrl-left.) This time, hold both the Control and Alt keys (or Command and Option on Macs) when you click. When you do that you get this dialog:



This dialog has focus and you can use the arrow keys to navigate and press enter -- or just click with the mouse. As soon as you pick a specific override of this method, you jump to it:



That's all there is to it. It's doubly embarrassing that I didn't remember this feature, since I should know the implementation of it very well. You see, I shamelessly lifted most of the implementation of it for the language-infrastructure work I did to support Go To Declaration in Ruby, JavaScript etc:



P.S. I've updated the wiki page with a clarification that it's built in now.

P.S.2: Until recent builds, Go To Implementation in NetBeans only worked for interfaces, not methods extending abstract classes. So use 6.9.