StatusDisplayer.getDefault().setStatusText("hello world");
And that's all, nothing more than that, apart from declaring the dependency on UI Utilities API. And now you'll get your message displayed in the IDE's status bar:
OutputWriter writer;
InputOutput io = IOProvider.getDefault().getIO("Hello Output", false);
writer = io.getOut();
writer.println("hello world");
The above would give you a "Hello Output" tab with the content of the println statement:
(Maybe it's just me, but I think that NetBeans IDE 6, thus far, on JDK 6 under Ubuntu Linux doesn't always look very nice by default. The screenshot above is a case in point. Probably I need to experiment with look and feels or something.)
However, what is interesting about this approach is that you can add a NetBeans API OutputListener to the println, which will result in hyperlinks being created in the Output window. (I've blogged about the OutputListener quite a lot in this blog, so just do a search if you want more info.) So, here's something slightly more complex than the example above:
OutputWriter writer;
InputOutput io = IOProvider.getDefault().getIO("Hello World Output", false);
writer = io.getOut();
writer.println("Click me: ");
writer.println(dObj.getPrimaryFile().getPath(), new HelloOutputListener(dObj));
So, the only difference between the above snippet and the previous snippet is that I now have the path to my file, retrieved from the data object, and an OutputListener. That's a whole separate class, which in this case receives the data object and, when the link in the Output window is clicked, the related file opens:
class HelloOutputListener implements OutputListener {
DataObject dObj;
public HelloOutputListener(DataObject dObj) {
this.dObj = dObj;
}//Specify what should happen when the hyperlink is selected:
public void outputLineSelected(OutputEvent arg0) {
}//Specify what should happen when the hyperlink is clicked:
public void outputLineAction(OutputEvent arg0) {
OpenCookie open = (OpenCookie) dObj.getCookie(OpenCookie.class);
open.open();
}//Specify what should happen when the hyperlink is cleared from the Output window:
public void outputLineCleared(OutputEvent arg0) {
}
}
And here is the result in the Output window which, when clicked, opens the specified file:
Again, be aware that this class is from an API that is on shaky footing, although I hope that whenever it is deprecated it will be replaced by some kind of alternative, but here's the code that makes the above possible:
//Get the data object:
DataObject dObj = (DataObject) activatedNodes[0].getCookie(DataObject.class);
//Get the file:
File f = FileUtil.toFile(dObj.getPrimaryFile());
//Get the editor:
JTextComponent editor = EditorRegistry.lastFocusedComponent();
//Get editor ui for editor:
EditorUI editorUI = Utilities.getEditorUI(editor);
//Get status bar for editor ui:
StatusBar statusBar = editorUI.getStatusBar();
//Add label to status bar,
//giving two strings, the first is the default length of the cell,
//and the second is the maximum length, which here is the same as the content:
JLabel cell = statusBar.addCell("My Cell", new java.lang.String[]{f.toString()});
cell.setText(f.toString());
There's lots you can do with that status bar. For example, let's add a JTextField instead of a JLabel. This means we must get the panel from the status bar and then we can simply add whatever we like (within reason, given the space that we have available) to that panel:
JTextField cell = new JTextField();
cell.setText(f.toString());
JPanel panel = statusBar.getPanel();
panel.add(cell);
And now we have a JTextField instead of a JLabel:
NotifyDescriptor d = new NotifyDescriptor.Message("Hello...", NotifyDescriptor.INFORMATION_MESSAGE);
DialogDisplayer.getDefault().notify(d);
So, what's the difference between DialogDisplayer and JOptionPane? I just phoned up Jarda Tulach to ask him. The answer is: "Better integration with the NetBeans Platform." For example, some actions are automatically disabled when the DialogDisplayer is shown, unlike with JOptionPane which doesn't know anything about the NetBeans Platform, and in addition the open Help window functions better in this case.
So, these are some handy approaches to communicating with the user (and yourself). [In the latter case, i.e., when communicating with yourself, you probably should be using the Debugger or the Profiler, by the way.] Of the above, I use the StatusDisplayer most frequently, because it is just one line and easy to remember. Also, using DialogDisplayer or JOptionPane means you have to click the OK button (potentially two zillion times, which is no fun). In the latter case, using the Output window (or System.out, of course) is a good choice. (By the way, I've found that I can only use System.out on Ubuntu Linux when I start the IDE from a terminal window. Then System.out prints to the terminal window.) The Output window is, of course, especially interesting when you're creating some kind of debugging tool for the user, with error messages appearing in the Output window, which can then be clicked to jump to the place where the error occurred in the editor. Using the editor's status bar is quite fun but, again, remember that the future of that approach is unclear.
Are there other ways of communicating with the user (and yourself)? Maybe you could print to a file outside the IDE, for example. But that's not an approach specific to the NetBeans APIs. You could also print messages to a TopComponent, which wouldn't be hard at all. Just create a TopComponent, add a JTextArea, and then whenever you need to communicate something, just use setText() on the JTextArea. Couldn't be much simpler. Basically you'd then have your own Output window.
In other news. Still investigating the different testing tools, will blog about these soon. But, nothing that I'll write about is not already available right now on the very good http://testtools.netbeans.org/ page.
Hi. I have a question about StatusDisplayer.getDefault().setStatusText("hello world"); What can I do if StatusBar of main window not visible.
In my case I'm using the OutputListener but I think I'm filling memory since I'm adding one each 3 seconds (as I receive output from a device). Some of those are duplicate messages. Basically unless something changes they'll be the same (up to 20 duplicaes per minute).
Any idea on how to reduce the memory consumption?