Geertjan's Blog

  • July 17, 2006

Cursing... Because of NetBeans Cursors!

Geertjan Wielenga
Product Manager
Cursors are a drag... Especially in NetBeans, sometimes. Here's what I'd like to have happen in my Music NotePad: whenever I drag something, anything, I want the cursor to change to a hand. By default, that does not happen! "So," you might think, "there's probably a property you set somewhere and then the drag cursor changes to whatever you specify." Well, if you think that, you're just plain wrong. There's not a drag cursor, there are several drag cursors.

For example, how would one turn the cursor within a TopComponent into a hand? Well, here the JDK can help you. When you implement DragGestureListener, there's a useful method call within dragGestureRecognized called startDrag. This is what mine looks like:

dragGestureEvent.startDrag( Cursor.getPredefinedCursor(Cursor.HAND_CURSOR), t );

The t is the transferable. The bit before it is the cursor. Now, when I drag a note in the Music Sheet, the cursor becomes a hand.

But that's only one of several places where I would expect there to be a hand instead of the default cursor. Here, for the uninitiated, are the others (just shout if there are more):

  • When dragging a TopComponent to a different position within the windowing system.
  • When dragging an item in a tree view to another place within the tree view.
  • When dragging an item from the Component Palette into a TopComponent.

To change the cursors in the above situations into a hand, I've downloaded the NetBeans sources, tweaked some of the files (to be discussed below), rebuilt the IDE, and assigned it as the NetBeans Platform for the Music NotePad. I guess I could also have put the tweaked files into the module suite's branding folder, but I haven't tried that yet. (One thing that went wrong, and got me pretty stuck for a while is that when I rebuilt the IDE, the build folders weren't cleaned and somehow not overwritten either. Only once I inspected the contents of the build folders did I discover that they hadn't been overwritten with the new files. So I manually deleted them, rebuilt the sources, and then all was well.)

By the way, rebuilding the IDE is remarkably easy. Just download the NetBeans sources as an archive file from netbeans.org, then go to its nbbuild folder and run ant build-platform. Get some coffee, because it'll take a while. Subsequently, you'd rarely need to rebuild the whole IDE again, because you can just rebuild the individual module(s) that you've tweaked. Then, in the IDE, go to the module suite's Project Properties dialog box and assign the NetBeans Platform as the suite's platform. Then, whenever you build the suite (or the module, if you haven't got a suite), the modules in your customized platform, rather than those in the development IDE platform, will be used.

Anyway, if you want the other three areas listed above to also use a hand when you drag an item, take a look at the following:

  • Go to core\\src\\org\\netbeans\\core\\resources, if you want a hand to appear when you move TopComponents around. In that folder, you will find the following files—topComponentDragCopy.gif, topComponentDragCopyNo.gif, topComponentDragMove.gif, and topComponentDragMoveNo.gif. These are the files that contain the default icons that you see when you drag TopComponents around. Just replace them! And then rebuild the IDE. Or put them in the appropriate place in the suite's branding folder.

  • Go to openide\\explorer\\src\\org\\openide\\resources, if you want a hand to appear when you drag nodes (for example, in the Projects window). When you get there, you will find the following files—cursorscopysingle.gif, cursorsmovesingle.gif, cursorsnone.gif, and cursorsunknownsingle.gif. Change these files, rebuild the IDE (or stick them in the right spot in the suite's branding folder) and you will see a hand (assuming you replaced the originals with hands) when you move nodes around.

  • Go to core\\palette\\src\\org\\netbeans\\modules\\palette\\ui\\dndsupport.java if you want the Component Palette to give you a hand when you move/copy an item somewhere. Within that file you will find the following line:

    dge.startDrag( null, t );

    Again, as discussed at the start of this blog entry, the first parameter is the cursor and the second is the transferable. The null will give you the default cursor. So change the null as follows...

    dge.startDrag( Cursor.getPredefinedCursor(Cursor.HAND_CURSOR), t );

    And then rebuild the IDE (or put the file in the right place in the suite's branding folder). And then you will have your own drag cursor!

Maybe you're reading this while thinking to yourself: "What's the big deal? It's just a cursor. What's all the fuss about?" Well, let pictures speak words. This is the default cursor, dragging a note from the Component Palette onto the Music Sheet:

And this is the same note, now being dragged by my "hand" cursor:

There's a pretty big difference—now the note isn't obscured by the cursor anymore. However, back to the start of this story—wouldn't it be nice if somehow or another it would be easier to set the cursor for all the different areas at once? But, I guess that's one of the side effects of a modular system—each module writer implements the cursor in a different way—some in the code, some via icons. And those that use icons put them in a variety of different places. Perhaps every module writer should provide a very detailed "map" of his/her module. If I'd had that, maybe I wouldn't have had to spend as much time as I did doing nothing more than changing a cursor. Or maybe all drags should, by default, make use of a "hand" cursor? That would make sense to me, anyway. Or isn't there a way that different modules can share the same resources? It shouldn't have to be this hard. Then again, now that I have it, and have worked it out myself (after a small hint from Jesse to look in core/palette) it looks pretty good. And the difficulty in finding it makes the finding all the more worthwhile.

Finally, two very small yet useful tips relating to this area. If you want a page with useful cursors (including hands), click here. And, if you need an editor for cursors (for free, for 30 days), click here. And now... happy cursoring!

Join the discussion

Comments ( 4 )
  • Trey Spiva Monday, July 17, 2006
    I am wondering why go thought all of the pain of modifing the NetBeans source? Why not just have your top component supply the cursor?
    In the Music NotePad application you got the current cursor and annotated it with the note that was being dragged. Instead you could just supply a new cursor image.
  • Geertjan Monday, July 17, 2006
    Yes, that's what I've done in the Music Sheet. But what about the Component Palette? There's no way of changing the cursor other than changing the source code.
  • Tom Palmer Monday, July 17, 2006
    Um. Is there a guarantee that the cursors always look exactly like this? Also, that hand looks like a pointy/hyperlinky hand, not a dragging hand. And I guess the JavaDocs don't exactly overflow with semantic intent, either:
  • Geertjan Tuesday, July 18, 2006
    Hi Tom. I tink you're right about this being a hyperlinky hand and not the traditional selection hand. However, my main point was to have a drag cursor that is DISTINCT from the default, so what it is is not relevant, so long as it isn't the default. But, if I can find an icon showing the more traditional drag icon, I'll use that instead. And I don't know whether the cursors always look exactly like this, but I don't see why not -- do you mean cros platform stuff or are you referring to something else. (By the way I like your semantic intent comment. That Javadoc link you've got there is a pretty good example of something, not sure what exactly.)
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.