Monday Mar 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!

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
public void paint(Graphics g)
Graphics2D g2d = (Graphics2D) g;

Now we can just change

var textPane = new JTextPane();


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:


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 Mar 16, 2009

NetBeans Screenshot of the Week 42: JavaScript Native Interface

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 Mar 12, 2009

Java Posse Roundup 2009

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.

Wednesday Mar 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!

Tuesday Jan 13, 2009

NetBeans Screenshot of the Week #41: Type Assertions

Python and Ruby are dynamically typed languages. We have a lot of heuristics in our editors to figure out the types - tracking assignments, analyzing your database migrations, etc - to help code completion, go to declaration and other IDE features work correctly. And Martin Krauskopf, who owns the Ruby editor now, has been improving the type inference for Ruby a lot lately.

However, there are cases where we just can't help. What if you're writing a brand new method you haven't called from anywhere, and you're trying to access methods on one of your parameters? We don't know the type of the parameter. In that case, NetBeans will provide "fallback code completion" - it will list ALL methods across ALL known classes in your project, libraries and current platform.

If you're looking for the documentation or parameters for a specific method - that's useful - after typing 2-3 characters you've typically narrowed the result set down to a handful of methods and you can pick the one you're looking for.

But what if you're not sure what the method is called? That exact scenario happened to me a couple of days ago. I was writing some Python code to do some string manipulation, and not being very familiar with Python I wanted to know what the equivalent of Java's indexOf method was in Python. I knew that the parameter in my method was a String, but I didn't have a way of telling the IDE that. I applied my usual workaround of adding a line above the current call:

x = ""

and then I could invoke x. to see the methods available for a String. However, that's definitely not a good way to do it. What if I forget to remove my fake assignment? (Yep, I did that too. I couldn't figure out why my code wasn't working until I debugged and realized I was clearing out the parameter with a bogus assignment... Doh!)

The "obvious" solution for this is supporting type assertions. We've had those for a long time in the Ruby editor
(picture), and obviously for JavaScript using the @type and @param {type} syntax. And the PHP editor just added support for type assertions as well (more here and here).

I've just added this for the Python editor as well. But I've gone one step further which I think makes the feature much more obvious, and easy to use. In code completion, if the editor detects that you are attempting to complete on a simple variable (as opposed to for example a complicated expression), and the type of that variable cannot be resolved, then we add a new special code completion item at the top of the list. Here's what it says (and a more detailed explanation in the documentation popup):

As soon as you press enter, the IDE will insert a special comment referencing the variable you were completing on, and automatically invoke code completion again to complete on the type statement:

The contents of this list has two parts: First, it lists the pseudo-types for many of the core builtin types, like ints, strings, lists and tuples. After that it will list all the known types in the system, such as the user and library classes. If you select one of these and try code completing the original expression again, you can now see that the type resolver knows what to do:

A couple of notes about this. First, note that the type assertions are just comments in your source. You can delete them - they are merely an aid to the IDE. Not only code completion uses these - go to declaration for example will also be more accurate if it is explicitly told the type of a variable it cannot figure out. You can also use multiple type assertions within a method in case the variable type changes during the method. This isn't the case with Ruby yet; the type assertions apply to parameters only, at the method level. But Martin has promised to look into this for Ruby as well so hopefully there will be full parity between the two editors shortly!

P.S. Just like in the PHP editor, mark occurrences and instant rename are type-assertion-aware:

Monday Jan 05, 2009

NetBeans Screenshot of the Week #40: Python Test Runner UI

In the 7.0 builds, we have a dedicated unit test runner for Python now. Running a file as a test, or running the test project action, will open a test runner with the output docked on its right hand side, instead of just the output window (click for full size screenshot):

Here's the test runner itself:

What you want to see in the output is a single green line which says "All n Tests Passed", where n is hopefully a large number. But when one or more of the tests fail, you see something like the above. Running the Next Error action (Cmd-.) will jump to the next failed test, just like it normally jumps to the next error in the current output window, or the next task in the tasklist.

One thing to notice (and this is new in 7.0) is that we now include the failure message right there in the test summary for each test, so you don't have to drill into an individual test to see the failure message. You can also hover over a test and any output from that test is shown in a tooltip. You can also right click on tests and select "Run Again" to run just one specific test over again.

This is the same window as the one we have for Ruby. In fact, Erno, who wrote the Ruby test runner, has modularized the code now such that it's the same implementation for both languages - we just have language specific plugins to actually hook into the various testing frameworks. Currently, for Python we support the two builtin testing frameworks: unittest and doctest. The above screenshot showed a regular unittest run. Here's a doctest:

One important thing to note is that you don't have to instrument your code with any test running code. As long as you place doctests in your docstrings, or as long as you have any classes extending unittest.TestCase, the test runner will find them. All you have to do is run Test Project:

and when you have done that, both unittests and doctests are found and included in the same test run - here's both failing doctests and unit tests:

Once again, kudos to Erno for writing the excellent test runner support! And as usual, let us know of any problems.

P.S. Jean-Yves Mengant has also done some excellent work recently. In addition to some cool new quickfixes in the Python editor for NetBeans, he has just integrated a multithreaded debugger for Python!

Friday Jan 02, 2009

Ruby Code Coverage in the builds now

I've checked the Ruby code coverage code into the trunk now, so if you grab a recent daily 7.0 build, it should be there. I found a Windows-specific bug in the Python code coverage code as well, so grab a new build if you're on that platform.

I've had some fun with Java2D lately. Instead of the ugly coverage bars I showed in my screenshots a couple of weeks ago, the coverage bars now have proper gradients, drop shadows behind the text etc.:

Another thing I added is a bar in the editor footer (while code coverage is enabled) which lists the coverage percentage for the current file, along with actions to quickly run the tests again, or bring up the coverage report, or clear the results, or finish the coverage mode. As well as warn you when your data is older than your code.

And finally, I updated the built-in and extra color themes to also have color definitions for the coverage highlights. Here's the Dark Pastels color theme with coverage data enabled:

Please let me know of any problems while this code is still fresh in my mind :)

Wednesday Dec 31, 2008

Happy New Year!

My music teacher in middle school had a great tradition. Every New Years Eve, at midnight, he would lift his stereo speakers up to his open windows, and on full blast, play ABBA's "Happy New Year" for the neighborhood.

I'm going to do the same thing here, on my little corner of the internet. Enjoy!

My kids have recently discovered ABBA through the Mamma Mia movie. Now they want to listen
to ABBA when we're driving around. No, don't pity me - it's a lot better than what they usually
want to listen to (I'm looking at you, Hannah Montana!). And besides, having grown up
in Norway I'm an ABBA fan at heart. When I was in 4th grade, all the girls in my class
liked ABBA, all the boys in my class liked Kiss, and then there was me - I sided with
the girls. And I'm still not ashamed of it. Despite some of their ridiculous outfits,
ABBA created some timeless melodies and had great sound production values that hold
up to this day.

Tuesday Dec 23, 2008

VirtualBox Rocks!

In order to get code coverage to work seamlessly in the presence of the Rake build tool, I had to do some pretty ugly tricks - a lot of path manipulation that surely won't work on Windows. Rather than just getting bug reports, I'll need to debug through it to find the troublespots and fix them.

I don't have a Windows machine. I have a Solaris desktop box, and a Mac laptop. And since I don't have any short term plans to go in to the office (I work from home most of the time) I don't want to wait to look into this until my next chance to stop by a computer lab with Windows machines.

So, I decided to dust off the VirtualBox instance I installed and tested a while back. Back then, it worked fine - but was a bit painful to use. Actually, it was my fault. I never went and "finished" my installation. Turns out, after installing Windows on the virtual machine, there is some additional software shipped with VirtualBox that can be installed into Windows to make things work more smoothly.
For example, a special mouse driver makes the Mac mouse also work as the Windows mouse. There's support to share file systems. This is a huge benefit. I simply mapped my working source tree that I have already checked out, edited and built, as a new Windows drive! I didn't have to go and install Mercurial, Python, check out the whole NeBeans source tree, build it, etc. I could simply open up drive Z:, and run the NetBeans IDE from within Windows!

Another cool thing these special tools add is "seamless mode". I'm running the Windows applications running as if they are regular Mac applications on my Mac desktop! So I can debug through my Windows instance of NetBeans while at the same time having my Mac mail and instant messaging programs part of the screen. Look at the below screenshot (click for full size) -- I have the Mac doc on the left, and the Windows doc on the bottom - as well as a mixture of Mac and Windows (uhm) windows on the desktop!

There's my mailtool again... Last year I posted a screenshot showing how I had 13,000 unread mails, but plans to finally catch up. I guess I didn't put that high enough up on my priority list. The above screenshot shows how I'm up to 56,000 unread mails now. Ugh. Oh well, at least the number of unread mails addressed directly to me is decreasing.

Wow. Installation was flawless. It's working beautifully. And it's free. And it's open source. Wow. Oh, and it runs on many other platforms as well.

As I wrote this blog entry I looked up the VirtualBox home page to I could link to it, and I discovered a news blurb:

New Dec 17, 2008

VirtualBox 2.1.0 released!

Sun today released VirtualBox 2.1.0, a major update with exciting new features: among them better 64-bit support, hardware virtualization on the Mac, 3D acceleration, easier networking on Windows and Linux plus full VMDK/VHD support including snapshots. See the ChangeLog for a detailed list of changes.

I just installed it and took it for a quick spin, and things are looking great.

P.S. One little tip: Installing the Guest Additions into Windows is easy - there's a menu item in the Device menu, "Install Guest Additions...". I tried it, and it popped up an installer inside Windows. But since I was in the middle of applying service packs to Windows, I dismissed it so I could deal with it after my service pack upgrade reboot. But when I tried it later, it didn't work! Uh oh, is this incompatible with service pack 3 I wonder? Nope, it's much simpler than that. What "Install Guest Additions..." does, is mount a new CD-ROM into Windows. I'm guessing Service Pack 3 turns off auto-run! Probably a security thing. So all I had to do was open the computer folder, and click on the CD-ROM there to run the installer.

Oh, one other tip: The default RAM allocated to the virtual machine is pretty small: 512Mb. In the Settings for the machine you can crank it up bigger - I set it to 2 Gb. That makes the machine run quite a bit faster under load since it's not continually swapping to disk for virtual memory.

Thursday Dec 18, 2008

JavaOne Submissions Due

The deadline for submitting talks for JavaOne 2009 is almost here. I was on one of the review committees last year, and saw many common patterns for rejected talks. I wrote these up in a blog entry last year - "Why Your JavaOne Submission Was Rejected. You might want to skim through it again while reviewing your submissions one final time!

Also, there's a new book about develping Ruby and Rails code with NetBeans, written by Chris Kutler and Brian Leonard. I reviewed some of the content and it looked very good. There are a lot of books on Ruby and Rails, but this book really shows you how to do things effectively with NetBeans. Mastering your tools is one of the best gifts you can give yourself as a developer (or as a craftsman of any craft, I think). I gave this advice a while back when I was interviewed for the JavaOne daily newspaper. Highlights from these interviews were recently compiled in this article, containing advice for students from a variety of developers. When this article was discussed on DZone I was surprised to see some people still talk about IDEs as something to be avoided until you know what you're doing. I think precisely when you are new to Java should you use an IDE to help you explore IDEs, to pinpoint errors are you're typing code rather when you try to run javac from the command line etc. The same goes for Ruby, Python, PHP, and so on. The IDEs let you explore APIs using code completion and go to declaration, they present important operations in project and execution menus, quickfixes and semantic warnings pinpoint errors in your code, and so on. If you're still writing code with Notepad, you're missing out.

Tuesday Dec 16, 2008

NetBeans Screenshot of the Week #39: Ruby Code Coverage, Python Code Coverage

Here's a new feature for NetBeans 7.0: Code Coverage support!

First a screenshot:

There are a couple of key points about the code coverage support:

  • It is fully integrated into the IDE, and especially the editor. You don't get read-only views of your files with coverage information; the files themselves include coverage highlights. You can view and edit the code directly, use your normal IDE navigation commands to jump around, and so on.
  • Enabling and disabling code coverage is trivial. There is no need to modify your build files, run special rake targets etc. Just select the menu checkbox to enable coverage in the new Code Coverage project menu, and then continue as before - run unit tests, run files, run the tests in your project - and the results are updated live as soon as the executed process finishes.

I didn't think a screenshot really described this feature well, so I recorded a couple of quick sessions where I use the feature:

Here's a couple more images if you have problems loading the videos:

<script type="text/javascript">
digg_url = '';
<script src="" type="text/javascript"></script>

The Python version is already in the 7.0 builds. The Ruby support isn't integrated yet; it probably needs some tweaking to make it work on Windows.

Friday Nov 28, 2008

NetBeans Screenshot of the Week #38: E4X Support

As part of the JavaScript 1.7 work,
I also beefed up the E4X support. E4X allows you to embed XML objects
directly in your JavaScript source. Here's some simple E4X JavaScript:

We've had E4X support in NetBeans in both NetBeans 6.1 and 6.5. But now, in NetBeans 7.0, semantic highlighting is E4X aware, such that the source code looks like this instead:

The whole XML document declaration has a faint purple background, element names are blue and document content is bolded.
(The green here, as for all JavaScript code in NetBeans, indicates variables in global scope.)

Another new E4X feature is formatting/pretty printing. If you press Alt-Shift-F to format the above source, the E4X is
reformatted and indented:

In addition, the navigator window shows the logical structure of the XML document as well. Clicking in the source
will expand and select the corresponding item in the navigator, and conversely double clicking in the navigator
warps the source to the corresponding location in the XML declaration:

Finally, there's some primitive support in code completion for the XML document:

Tuesday Nov 25, 2008

NetBeans Screenshot of the Week #37: JavaScript 1.7 Support

I just checked in support for JavaScript 1.7. This means that NetBeans will no longer give you syntax errors if you try to use the new language. Here are some screenshots. First, let's open a file using JavaScript 1.7 constructs:

Obviously the file is using yield which is not recognized as a keyword, and in particular, this is just a syntax error - the parser was expecting a semicolon. But there's a little lightbulb... let's see what it says (type Alt-Enter or click on the lightbulb):

Let's select the option to change the active language to 1.7. I could also open the JavaScript options dialog directly and set it to 1.7 as shown here:

After applying the language change, the editor immediately re-lexes and reparses the file according to the new language. The errors are gone, and yield is now a proper keyword:

Similarly, the let keyword can be used, as well as destructuring assignments, generators and iterators, etc. (See New In JavaScript 1.7 for more information).

If you place the caret on function definitions, it will highlight all exit points, and this includes yields now.

This work isn't done; I'd like it to be smarter about generators, and there may be some issues with scope handling. But at least the editor doesn't get in your way with false error messages now - you can start writing JavaScript 1.7 clean code. (This is with NetBeans 7.0 dev).

In related news, I just heard from Tom Enebo that a lot of Ruby 1.9 language features are now supported by the JRuby trunk parser, so hopefully we can soon start fully supporting Ruby 1.9 features in NetBeans as well.

Friday Nov 14, 2008

NetBeans Screenshot of the Week #36: Python Code Completion

Here are some screenshots of the code completion working for Python.
First, let's try it from an import statement:

Note that the documentation for the module is shown. Next, let's
try completing on imported symbols - again we've got the documentation:

I'm writing a unit test, extending TestCase. Now let's try overriding
some methods - completion after typing def:

Obviously, invoking methods on self. will show the inherited
methods - and their documentation:

Here's completion in my function (not on self) showing
the local variables, imported symbols and builtins. Notice that deprecated
methods are marked with strikethrough (and deprecated modules are in imports
as well, though I didn't show that above).

Notice also that the documentation here looks better - it has links,
colors, etc. This is because NetBeans supports the reStructuredText
Docstring Format (see PEP 287).
System libraries are being documented in this way now, so more of the
documentation will start looking like this.

When NetBeans finds embedded code, it will also syntax highlight the
code fragments in the documentation:

You can use this in your own documentation as well obviously.
Here's a file where I have restructured text. As I'm writing it,
I can -immediately- preview the text myself by just pressing
Ctrl-Shift-Space (Show Documentation - for those who don't know, you
can do this on regular code as well if you want to just get the documentation
for the code at the caret, rather than completion alternatives up to
the caret prefix.)

Here's a final example - completion after raise (or
exception) will show completion for all Error

I'll be quiet or about a week now -- I'm going on vacation! Not great
timing given the release date, but this has been planned since February...

Thursday Nov 13, 2008

NetBeans Screenshot of the Week #35: Support for Python's __all__ Variable

Let's start with a pretty simple module - an import, a function, and a couple of classes:

(Notice by the way the semantic highlighting here - the unused parameters and variables are marked with a slight grey underline,
method names in bold, parameters in orange. More on that another day.)

Now let's go to a different file and import this module. Code completion is context dependent and shows us
which symbols are being exported by the given module. We see not only our functions and classes, the imported symbol sys
is also being defined by module, meaning that if you do from compl4 import \* you would have sys defined as well:

Python has a way to deal with this: You can specify a variable named __all__, which lets you define exactly what the public API for
this module should be (more details).

Let's go in and define the names we want exported by our module. I will add __all__ = [ "Bar " ] somewhere in the file, to specify that only Bar should be exported:

Look at the file outline / navigator on the left hand side. As soon as I typed in the __all__ line,
the icons changed to show me that only the Bar class and its method are now "public"; there are little
lock icons on everything else! Let's see what code completion offers when we try to import this module again:

Yep, only the public API is exported now. Let's append to the __all__ list to export the func function:

You don't have to rely on icons to tell you if something is wrong though. Let's say I've forgotten all about this, and I decided
to rename my Bar class:

NetBeans checks that all the symbols you declare in your __all list actually exist, and points out any discrepancies. Here, the public Bar class no longer exists since we renamed it.

Here's another little bug I came across related to this. I was checking the __all__ handling on various library files,
in this case Notice how in the navigator, all the functions are public, except one...

Sure enough, the code looks like it's registering this conditionally added method... Do you spot the problem? There's a dot missing!
As soon as we add it, we get this:

Of course, this last bug was already detected by the
unresolved symbol detector...


Tor Norbye


« February 2015