NetBeans platform development with JRebel even more simplified
Many things in the JRebel universe have changed in the last months. Several new versions of JRebel were released, Zeroturnaround acquired Javeleon [1] and the JRebel-Plugin for NetBeans IDE got better and better.
Especially the support for developing NetBeans platform/RCP applications has been improved. In my posts [2], [3], [4] I showed you how to configure JRebel to reload your changes within NB platform/NB IDE modules. These are mostly obsolete. The whole process has been simplified, the number of manual steps have been reduced. For example: you don’t need to modify any property-file anymore to tell NetBeans to load the JRebel as javaagent.
So if you want to use JRebel to “instantly reload” your compiled changes to a fixed- (or locally compiled bleeding-edge-dev-) version of NetBeans IDE (or your own target platform) you have to follow these simple steps:
- install the JRebel-NetBeans-Plugin from the plugin portal and register your license, if not already done
- open your module (or open a module from the checkout sources of NB IDE)
- generate a
rebel.xmlin the source folder of the module – let the JRebel-plugin do this for you (right click on the project node, then “Generate rebel.xml“) - make sure that the JRebel icon in the toolbar is checked (this is important, because this tells the plugin to add the
-javaagentargument to command line of the next run/debug) - run the module (you will see the JRebel headers in the output window, which means JRebel is loaded, and the target platform with your module activated will be opened)
- make your changes to the code, compile via
F9(this includes saving – that’s the trick) - go back to the previously started instance of the target platform, repeat your actions and the changes in code are reloaded instantly (Please note that reloads of changes to layer.xml or additions to bundle.properties aren’t supported. In this case you still have to “
build” and “run” the module again.)
This makes it much easier (at least for me) and I hope this simplicity will also attract other developers to write plugins or even to contribute to NB IDE development.
Tested with NB7.3/7.4dev, JRebel-NB-Plugin 1.5.1 and JRebel 5.2.2.
[1] http://www.prweb.com/releases/2013/3/prweb10543831.htm
[2] http://wp.me/pIpWO-64
[3] http://wp.me/pIpWO-5M
[4] http://wp.me/pIpWO-4n
NetBeans IDE: Additional hints plugin to simplify the work with String literals
Recently I wrote some Java hints, which simplify the work with String literals. Users of Eclipse or Intellij IDEA may recognize some of them.
New hints:
- Replace ‘+’ with ‘MessageFormat.format()’
- Replace ‘+’ with ‘new StringBuilder().append()’
- Replace ‘+’ with ‘String.format()’
- Join literals
- Copy joined literals to clipboard
- Split the String on linebreaks
Here some use-cases:
Use-case 1: “Simplify concatenation”
"Hello " + "world" can be replaced by "Hello world"
Use-case 2: “Join for localization”
When localizing your application, you often have to struggle with concatenated Strings like the following:
"Info: only " + number + " entries found"
With the help of the hints such terms can be easily replaced by
String.format("Info: only %s entries found", number) //or
MessageFormat.format("Info: only {0} entries found", number)
The generated joined literals can now be extracted more easily by the Internationalization wizard/tooling.
Use-case 3: “Developing test-cases for hints”
Copy joined literals to clipboard vs. pasting from clipboard

Join literals vs. Split on linebreaks

The plugin is compatible to NetBeans 7.2 (and above) and verified, thus it can be installed directly from your IDE. Or you can download it from [1] and install it manually.
The sourcecode is available at [2]. The infrastructure code is based on code from the “I18N Checker” plugin from Jan Lahoda [3]. Feel free to file issues or enhancements at [2].
[2] http://plugins.netbeans.org/plugin/47589/additional-hints
[3] https://github.com/markiewb/nb-additional-hints
[3] http://hg.netbeans.org/main/contrib/file/tip/editor.hints.i18n
NetBeans IDE: Improved documents tabs in nightly builds
NetBeans 7.3 is only some days old, but the NB devs are not tired to continue making NetBeans IDE even better. There are already many visible changes in the current nightly dev builds regarding usability.
For example: Documents tabs were rewritten from the scratch – see [1]. Kudos to Stanislav Aubrecht. There are highly configurable now and the UI looks very clean.
Notable features
- you can have a tab row for each of your open projects, even with coloring
- you can show the parent folder of the current file in the tab. This feature seems to be requested by PHP devs, who work with many opened files equally named index.php from different folders at the same time. Those can be distinguished now.
- status label decorators from the version system are applied to tab too
- the documents dropdown is now grouped by project
It looks very promising. Stay tuned for more useful enhancements in the next version!
NetBeans IDE: Custom hints
Another mostly unnoticed but powerful feature of NetBeans is the possibility of creating custom hints.
Custom hints (a.k.a custom inspections or quickfixes in other IDEs) are available since NetBeans 7.1. They match patterns in Java code and can provide a transformation. This enables you to create small refactorings based on the AST without coding. A typical usecase is the type-safe migration of API – instead of the error-prone plain text-based “search and replace” approach.
You can create your own hint in a special DSL as described in [1]. Geertjan already blogged several times about this topic at [2] and [3]. Yes, the UI for creating/enabling the hints is not very intuitive, but it works.
The best thing is the integration in the editor:
Your custom hints
- are available in the Java editor like the “standard” hints

- can be applied to a file/package/project or even all opened projects. It includes also a changes-preview. This is pretty useful to do apply transformations in a batch.

Here some very basic examples:
<!description="Convert to assertTrue/assertFalse"> org.junit.Assert.assertEquals(true, $any) => org.junit.Assert.assertTrue($any) ;; org.junit.Assert.assertEquals($msg, true, $any) => org.junit.Assert.assertTrue($msg, $any) ;; org.junit.Assert.assertEquals(false, $any) => org.junit.Assert.assertFalse($any) ;; org.junit.Assert.assertEquals($msg, false, $any) => org.junit.Assert.assertFalse($msg, $any) ;;
<!description="Remove dead if-branch">
if (false){
$statements$
}
=>
;;
<!description="Add extra parenthesis"> $a && $b => ($a) && ($b) ;; $a || $b => ($a) || ($b) ;;
<!description="Flip operands"> $a & $b => $b & $a ;; $a && $b => $b && $a ;; $a || $b => $b || $a ;;
<!description="Flip < >"> $a < $b => $b > $a ;; $a > $b => $b < $a ;;
Those patterns can also be used to code more advanced hints [5] [6].
Give it a try and share your patterns! Which selfmade hints do you use on a regular basis?
FYI: Intellj IDEA provides a similar feature called “structural replace” [7]
References:
[1] http://wiki.netbeans.org/JavaDeclarativeHintsFormat
[2] https://blogs.oracle.com/geertjan/entry/custom_declarative_hints_in_netbeans
[3] https://blogs.oracle.com/geertjan/entry/oh_no_override_oh_no
[4] https://blogs.oracle.com/geertjan/entry/oh_no_vector
[5] https://blogs.oracle.com/geertjan/entry/java_hint_in_netbeans_for
[6] https://blogs.oracle.com/geertjan/entry/netbeans_java_hints_quick_dirty
NetBeans IDE: Verification of plugins and update center URLs for non-verified plugins
You developed a cool NetBeans plugin? Now you want it be to be available via the official update center, so that it can be installed directly from the NetBeans IDE via the built-in Plugins Manager and gets more attention from the users?
Then you have to adhere to the verification and quality rules defined in [1] and [2]. You have to define a license, sign the package and so on. Your plugin will also be tested from several trusted community members and they give a go or a no-go. For some plugin developers this process seems to be too much overhead and too time-consuming. They do not request a verification and therefore their plugin is not available in the Plugins Manager from your IDE. That is a pity, because this way you miss many useful plugins (Geertjans plugins, Compare to clipboard, JVisualVM samples, …). For example there are only 67 of 136 plugins verified for NB 7.2.
Of course you could download the plugin manually from the plugin portal at [3] and install them manually, but this not very comfortable IMHO. It is also not reasonable for me to contact all the authors and beg them for getting their plugins verified. So i opened a ticket [4] for an update center which contains those non-verified plugins. And guess what. The NB team now provides such URLs:
- http://plugins.netbeans.org/nbpluginportal/updates/7.1/catalog-experimental.xml
- http://plugins.netbeans.org/nbpluginportal/updates/7.2/catalog-experimental.xml
- http://plugins.netbeans.org/nbpluginportal/updates/7.3/catalog-experimental.xml
As warning: Using these URLs you are going to install non-verified, experimental and non-quality-checked plugins, which could make your NetBeans IDE unstable/slow down or even crash. Only install plugins you know and trust. You can be sure that the NetBeans developers will not support any issues regarding these plugins.
You want to have more quality plugins available and don’t want to go this inofficial way of experimental update centers? So please encourage the authors of your favorite plugins to request a verification. Thank you!
[1] http://wiki.netbeans.org/FaqPluginRequirements
[2] http://wiki.netbeans.org/PluginPortalQualityCriteria
[3] http://plugins.netbeans.org/
[4] http://netbeans.org/bugzilla/show_bug.cgi?id=225104
NetBeans RCP: Editable diff viewer using custom base source
Some days ago Geertjan showed you how to create an editable diff viewer [1] . His approach was based on the integration of the standard “Diff to…”-action (org.netbeans.modules.diff.DiffAction), which requires the selection of nodes.
As a sequel i will show you today how to create a diff action too, BUT this time you are free to define the base you are comparing to. This hasn’t to be another node. Such base can be another file, a revision from source code management, text from a DB and so on. The base source will be shown on the left side and the modified (and editable) source (based on your Node/DataObject, where we attach our action to) will be shown on the right side of the diff window.
The following sample app will compare the given FileObject (from the Lookup) with its base. The base - in this very simplified example – is a String read from a file.
The main point is to implement your own editable StreamSource for the modified source. Return true from isEditable() and provide a Reader for your FileObject (from node of the modified source) in createReader(). That’s all. The rest of the sourcecode is only plain standard stuff like creating a diff control, adding this control to a new TopComponent and creating an action, which will open the TopComponent. Geertjan already blogged about it at [2].
@ActionID(category = "Edit", id = "de.markiewb.netbeans.sample.editablediff.EditableDiffAction")
@ActionRegistration(displayName = "#CTL_DiffAction")
@ActionReferences({
@ActionReference(path = "Editors/Popup")})
@Messages("CTL_DiffAction=Editable diff...")
public final class EditableDiffAction implements ActionListener {
private final FileObject file;
public EditableDiffAction(FileObject context) {
this.file = context;
}
@Override
public void actionPerformed(ActionEvent ev) {
final String baseText = getOriginalText(file);
final StreamSource base = StreamSource.createSource("name1", "base", file.getMIMEType(), new StringReader(baseText));
final StreamSource modified = EditableStreamSource.createEditableSource("name2", "modified", file.getMIMEType(), file);
openDiffWindow(file, modified, base, "Diff of " + file.getNameExt() + " to original");
}
public void openDiffWindow(final FileObject localFile, final StreamSource local, final StreamSource remote, final String title) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
final TopComponent tc = new TopComponent();
tc.setDisplayName(title);
tc.setLayout(new BorderLayout());
makeDiffWindowSaveable(tc, localFile);
tc.add(DiffController.createEnhanced(remote, local).getJComponent(), BorderLayout.CENTER);
tc.open();
tc.requestActive();
} catch (IOException ex) {
}
}
});
}
/**
* Put the node of dataObject of the fileObject into "globallookup". This
* allows saving via CTRL-S shortkey from within the editable diff TC. See
* http://netbeans.org/bugzilla/show_bug.cgi?id=223703
*
* @param tc
* @param fileObject
*/
private void makeDiffWindowSaveable(TopComponent tc, FileObject fileObject) {
if (tc != null) {
Node node;
try {
node = DataObject.find(fileObject).getNodeDelegate();
} catch (DataObjectNotFoundException e) {
node = new AbstractNode(Children.LEAF, Lookups.singleton(fileObject));
}
tc.setActivatedNodes(new Node[]{node});
}
}
public String getOriginalText(FileObject file) {
// TODO this is only a mockup
// TODO get original text from other sources like SCM, DB, template files..
try {
return file.asText("UTF-8").replace("public ", "public final ");
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
return "";
}
public static class EditableStreamSource extends StreamSource {
private String name, title, mimeType;
private FileObject fileObject;
private EditableStreamSource(String name, String title, String mimeType, FileObject fileObject) {
this.name = name;
this.title = title;
this.mimeType = mimeType;
this.fileObject = fileObject;
}
public static StreamSource createEditableSource(String name, String title, String mimeType, FileObject fileObject) {
return new EditableStreamSource(name, title, mimeType, fileObject);
}
@Override
public String getName() {
return this.name;
}
@Override
public String getTitle() {
return this.title;
}
@Override
public Lookup getLookup() {
return Lookups.fixed(fileObject);
}
@Override
public boolean isEditable() {
return fileObject.canWrite();
}
@Override
public String getMIMEType() {
return mimeType;
}
@Override
public Reader createReader() throws IOException {
return new FileReader(FileUtil.toFile(fileObject));
}
@Override
public Writer createWriter(Difference[] conflicts) throws IOException {
return null;
}
}
}
PS: There is a small trick to enable the “save”-action (Menubar File->Save / CTRL-S) for your new editable diff, which won’t get enabled after changing content in the right editor pane of the diff viewer by default. You have to associate your node to the TopComponent – see makeDiffWindowSaveable(). Thanks to Ondrej Vrabec for the solution – see [3].
The full source code of this sample is available at [4] and also documented at [5]
[1] https://blogs.oracle.com/geertjan/entry/how_to_create_an_editable
[2] https://blogs.oracle.com/geertjan/entry/netbeans_diff_api
[3] http://netbeans.org/bugzilla/show_bug.cgi?id=223703
[3] https://github.com/markiewb/nb-api-samples/tree/master/CustomEditableDiff
[4] http://wiki.netbeans.org/DevFaqEditorHowToAddDiffView




![example[1]](http://benkiew.files.wordpress.com/2013/01/example1.png?w=595&h=310)
Recent Comments