How to use the diff view in my own application/plugin
Show non-editable diff for files
@ActionID(category = "Tools", id = "org.my.diff.DiffViewerAction")
@ActionRegistration(asynchronous = true, displayName = "#CTL_DiffViewerAction")
@ActionReference(path = "Menu/Tools", position = 0)
@Messages("CTL_DiffViewerAction=Open Diff Viewer")
public final class DiffViewerAction implements ActionListener {
@Override
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() {
@Override
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);
tc.open();
tc.requestActive();
} catch (IOException ex) {
}
}
});
}
}
or
String contentType = fo.getMIMEType();
DiffView view = Diff.getDefault().createDiff(
StreamSource.createSource("Before", "Before", contentType, new StringReader(beforeText)),
StreamSource.createSource("After", "After", contentType, new StringReader(afterText))
);
Component diffViewComponent = view.getComponent();
See
Show editable diff for a FileObject and an arbitrary base source
You have to an editable StreamSource for your FileObject to create a editable diff viewer.
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.
package de.markiewb.netbeans.sample.editablediff;
//...
@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
* https://bz.apache.org/netbeans/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 https://bz.apache.org/netbeans/show_bug.cgi?id=223703.