Friday Jan 04, 2013

Getting Started with Diff Viewer from Scratch

Let's get started creating an application from scratch integrating the NetBeans Diff Viewer. Create a new application:

Give it a name and store it somewhere:

Create a new module:

Give it a name and store it somewhere:

Give it a unique identifier and display name:

Right-click the application, choose Properties, go to Libraries, and select "Diff" from the "ide" cluster and then click the Resolve button to include the related modules:

Create a new Action:

Let it always be enabled:

Specify the locations where the Action will be invoked:

Provide class name, display name, and icon:

Right-click the module and specify that you want to add a dependency:

Add a dependency on the Diff module:

Do the same as the above for the Window System module.

Define the Action as follows, replacing the hardcoded files with your own:


import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.SwingUtilities;
import org.netbeans.api.diff.Diff;
import org.netbeans.api.diff.DiffView;
import org.netbeans.api.diff.StreamSource;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.util.NbBundle.Messages;

        category = "Tools",
        id = "")
        asynchronous = true,
        displayName = "#CTL_DiffViewerAction")
        path = "Menu/Tools", 
        position = 0)
@Messages("CTL_DiffViewerAction=Open Diff Viewer")
public final class DiffViewerAction implements ActionListener {

    public void actionPerformed(ActionEvent e) {
        StreamSource local = StreamSource.createSource("name1",
                "title1", "text/html", new File("C:/tutorials/nbm-google.html"));
        StreamSource remote = StreamSource.createSource("name2",
                "title2", "text/html", new File("C:/tutorials/72/nbm-google.html"));
        diff(local, remote);

    public void diff(final StreamSource local, final StreamSource remote) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {
                    DiffView view = Diff.getDefault().createDiff(local, remote);
                    TopComponent tc = new TopComponent();
                    tc.setDisplayName("Diff Viewer");
                    tc.setLayout(new BorderLayout());
                    tc.add(view.getComponent(), BorderLayout.CENTER);
                } catch (IOException ex) {

Alternatively, let's assume that the files we want to diff are within the module, for some reason, rather than externally on disk. This is how the "actionPerformed" above would be rewritten:

public void actionPerformed(ActionEvent e) {
    StreamSource ss1 = null;
    StreamSource ss2 = null;
    InputStreamReader ir1 = null;
    InputStreamReader ir2 = null;
    try {
        ir1 = new InputStreamReader(FileUtil.getConfigFile("files/one").getInputStream());
        ir2 = new InputStreamReader(FileUtil.getConfigFile("files/two").getInputStream());
        ss1 = StreamSource.createSource("name1", "title1", "text/html", ir1);
        ss2 = StreamSource.createSource("name2", "title2", "text/html", ir2);
    } catch (FileNotFoundException ex) {
    diff(ss1, ss2);

And here are the related layer elements:

<folder name="files">
    <file name="one" url="file1.html"/> 
    <file name="two" url="file2.html"/> 

The above assumes the layer.xml is in the same package as the two files "file1.html" and "file2.html".

Run the application and go to the Tools menu to invoke the Action:

You'll see this:

Go back to the Project Properties dialog of the application and include these two modules from the "ide" cluster:

Clean the application. Build the application. Run the application. Invoke the Action. You'll see the Diff Viewer, as below, diffing the two files you passed in:


Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.


« January 2013 »