KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > versioning > diff > DiffSidebar


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.versioning.diff;
20
21 import org.netbeans.editor.*;
22 import org.netbeans.editor.Utilities;
23 import org.netbeans.api.editor.fold.FoldHierarchy;
24 import org.netbeans.api.editor.fold.FoldHierarchyListener;
25 import org.netbeans.api.editor.fold.FoldHierarchyEvent;
26 import org.netbeans.api.diff.Difference;
27 import org.netbeans.api.diff.Diff;
28 import org.netbeans.api.diff.StreamSource;
29 import org.netbeans.api.diff.DiffView;
30 import org.netbeans.spi.diff.DiffProvider;
31 import org.netbeans.modules.editor.errorstripe.privatespi.MarkProvider;
32 import org.netbeans.modules.versioning.spi.OriginalContent;
33 import org.openide.ErrorManager;
34 import org.openide.awt.UndoRedo;
35 import org.openide.windows.TopComponent;
36 import org.openide.util.Lookup;
37 import org.openide.util.RequestProcessor;
38 import org.openide.util.HelpCtx;
39 import org.openide.util.NbBundle;
40 import org.openide.util.lookup.Lookups;
41
42 import javax.swing.*;
43 import javax.swing.event.DocumentListener JavaDoc;
44 import javax.swing.event.DocumentEvent JavaDoc;
45 import javax.swing.text.*;
46 import java.awt.event.*;
47 import java.awt.*;
48 import java.beans.PropertyChangeListener JavaDoc;
49 import java.beans.PropertyChangeEvent JavaDoc;
50 import java.util.*;
51 import java.util.List JavaDoc;
52 import java.util.logging.Logger JavaDoc;
53 import java.util.logging.Level JavaDoc;
54 import java.io.*;
55 import java.text.ChoiceFormat JavaDoc;
56 import java.text.MessageFormat JavaDoc;
57
58 /**
59  * Left editor sidebar showing changes in the file against the base version.
60  *
61  * @author Maros Sandor
62  */

63 class DiffSidebar extends JComponent implements DocumentListener JavaDoc, ComponentListener, PropertyChangeListener JavaDoc, FoldHierarchyListener {
64     
65     private static final int BAR_WIDTH = 9;
66     
67     private final JTextComponent textComponent;
68
69     private final EditorUI editorUI;
70     private final FoldHierarchy foldHierarchy;
71     private final BaseDocument document;
72     
73     private boolean annotated;
74     private Difference [] currentDiff;
75     private DiffMarkProvider markProvider;
76
77     private Color colorAdded = new Color(150, 255, 150);
78     private Color colorChanged = new Color(160, 200, 255);
79     private Color colorRemoved = new Color(255, 160, 180);
80     private Color colorBorder = new Color(102, 102, 102);
81     
82     private final OriginalContent originalContent;
83
84     private int originalContentSerial;
85     private int originalContentBufferSerial = -1;
86     private String JavaDoc originalContentBuffer;
87
88     private RequestProcessor.Task refreshDiffTask;
89
90     public DiffSidebar(JTextComponent target, OriginalContent content) {
91         this.textComponent = target;
92         this.originalContent = content;
93         this.editorUI = Utilities.getEditorUI(target);
94         this.foldHierarchy = FoldHierarchy.get(editorUI.getComponent());
95         this.document = editorUI.getDocument();
96         this.markProvider = new DiffMarkProvider();
97         setToolTipText(""); // NOI18N
98
refreshDiffTask = DiffSidebarManager.getInstance().createDiffSidebarTask(new RefreshDiffTask());
99         setMaximumSize(new Dimension(BAR_WIDTH, Integer.MAX_VALUE));
100     }
101
102     JTextComponent getTextComponent() {
103         return textComponent;
104     }
105
106     Difference[] getCurrentDiff() {
107         return currentDiff;
108     }
109
110     public String JavaDoc getToolTipText(MouseEvent event) {
111         Difference diff = getDifferenceAt(event);
112         return getShortDescription(diff);
113     }
114
115     static String JavaDoc getShortDescription(Difference diff) {
116         if (diff == null) return null;
117         int n;
118         switch (diff.getType()) {
119             case Difference.ADD:
120                 n = diff.getSecondEnd() - diff.getSecondStart() + 1;
121                 return MessageFormat.format(new ChoiceFormat JavaDoc(NbBundle.getMessage(DiffSidebar.class, "TT_LinesAdded")).format(n), n);
122             case Difference.CHANGE:
123                 n = diff.getFirstEnd() - diff.getFirstStart() + 1;
124                 return MessageFormat.format(new ChoiceFormat JavaDoc(NbBundle.getMessage(DiffSidebar.class, "TT_LinesChanged")).format(n), n);
125             case Difference.DELETE:
126                 n = diff.getFirstEnd() - diff.getFirstStart() + 1;
127                 return MessageFormat.format(new ChoiceFormat JavaDoc(NbBundle.getMessage(DiffSidebar.class, "TT_LinesDeleted")).format(n), n);
128             default:
129                 throw new IllegalStateException JavaDoc("Unknown difference type: " + diff.getType()); // NOI18N
130
}
131     }
132
133     protected void processMouseEvent(MouseEvent event) {
134         super.processMouseEvent(event);
135         Difference diff = getDifferenceAt(event);
136         if (diff == null) return;
137         if (event.getID() == MouseEvent.MOUSE_CLICKED) {
138             onClick(event, diff);
139         }
140     }
141     
142     private void onClick(MouseEvent event, Difference diff) {
143         Point p = new Point(event.getPoint());
144         SwingUtilities.convertPointToScreen(p, this);
145         Point p2 = new Point(p);
146         SwingUtilities.convertPointFromScreen(p2, textComponent);
147         showTooltipWindow(new Point(p.x - p2.x, p.y), diff);
148     }
149
150     private void showTooltipWindow(Point p, Difference diff) {
151         DiffActionTooltipWindow ttw = new DiffActionTooltipWindow(this, diff);
152         ttw.show(new Point(p.x, p.y));
153     }
154     
155     private Difference getDifferenceAt(MouseEvent event) {
156         if (currentDiff == null) return null;
157         int line = getLineFromMouseEvent(event);
158         if (line == -1) return null;
159         Difference diff = getDifference(line + 1);
160         if (diff == null) {
161             // delete annotations (arrows) are rendered between lines
162
diff = getDifference(line);
163             if (diff != null && diff.getType() != Difference.DELETE) diff = null;
164         }
165         return diff;
166     }
167
168     void onDiff(Difference diff) {
169         try {
170             DiffView view = Diff.getDefault().createDiff(new SidebarStreamSource(true), new SidebarStreamSource(false));
171             JComponent c = (JComponent) view.getComponent();
172             DiffTopComponent tc = new DiffTopComponent(c);
173             tc.setName(originalContent.getWorkingCopy().getName() + " [Diff]");
174             tc.open();
175             tc.requestActive();
176             view.setCurrentDifference(getDiffIndex(diff));
177         } catch (IOException e) {
178             ErrorManager.getDefault().notify(e);
179         }
180     }
181
182     private int getDiffIndex(Difference diff) {
183         for (int i = 0; i < currentDiff.length; i++) {
184             if (diff == currentDiff[i]) return i;
185         }
186         return -1;
187     }
188
189     void onRollback(Difference diff) {
190         try {
191             if (diff.getType() == Difference.ADD) {
192                 int start = Utilities.getRowStartFromLineOffset(document, diff.getSecondStart() - 1);
193                 int end = Utilities.getRowStartFromLineOffset(document, diff.getSecondEnd());
194                 document.remove(start, end - start);
195             } else if (diff.getType() == Difference.CHANGE) {
196                 int start = Utilities.getRowStartFromLineOffset(document, diff.getSecondStart() - 1);
197                 int end = Utilities.getRowStartFromLineOffset(document, diff.getSecondEnd());
198                 document.replace(start, end - start, diff.getFirstText(), null);
199             } else {
200                 int start = Utilities.getRowStartFromLineOffset(document, diff.getSecondStart());
201                 document.insertString(start, diff.getFirstText(), null);
202             }
203             refreshDiff();
204         } catch (BadLocationException e) {
205             ErrorManager.getDefault().notify(e);
206         }
207     }
208
209     boolean canRollback(Difference diff) {
210         if (!(document instanceof GuardedDocument)) return true;
211         int start, end;
212         if (diff.getType() == Difference.DELETE) {
213             start = end = Utilities.getRowStartFromLineOffset(document, diff.getSecondStart());
214         } else {
215             start = Utilities.getRowStartFromLineOffset(document, diff.getSecondStart() - 1);
216             end = Utilities.getRowStartFromLineOffset(document, diff.getSecondEnd());
217         }
218         MarkBlockChain mbc = ((GuardedDocument) document).getGuardedBlockChain();
219         return (mbc.compareBlock(start, end) & MarkBlock.OVERLAP) == 0;
220     }
221     
222     void onPrevious(Difference diff) {
223         diff = currentDiff[getDiffIndex(diff) - 1];
224         Point location = scrollToDifference(diff);
225         showTooltipWindow(location, diff);
226         textComponent.repaint();
227     }
228
229     void onNext(Difference diff) {
230         diff = currentDiff[getDiffIndex(diff) + 1];
231         Point location = scrollToDifference(diff);
232         showTooltipWindow(location, diff);
233         textComponent.repaint();
234     }
235
236     private Point scrollToDifference(Difference diff) {
237         int lineStart = diff.getSecondStart() - 1;
238         int lineEnd = diff.getSecondEnd() - 1;
239         if (diff.getType() == Difference.DELETE) {
240             lineEnd = lineStart;
241         }
242         try {
243             int visibleBorder = editorUI.getLineHeight() * 5;
244             int startOffset = Utilities.getRowStartFromLineOffset((BaseDocument) textComponent.getDocument(), lineStart);
245             int endOffset = Utilities.getRowStartFromLineOffset((BaseDocument) textComponent.getDocument(), lineEnd);
246             Rectangle startRect = textComponent.getUI().modelToView(textComponent, startOffset);
247             Rectangle endRect = textComponent.getUI().modelToView(textComponent, endOffset);
248             Rectangle visibleRect = new Rectangle(startRect.x - visibleBorder, startRect.y - visibleBorder,
249                                                   startRect.x, endRect.y - startRect.y + endRect.height + visibleBorder * 2);
250             textComponent.scrollRectToVisible(visibleRect);
251             
252             Point p = new Point(endRect.x, endRect.y + endRect.height + 1);
253             SwingUtilities.convertPointToScreen(p, textComponent);
254             return p;
255         } catch (BadLocationException e) {
256             Logger.getLogger(DiffSidebar.class.getName()).log(Level.WARNING, "scrollToDifference", e); // NOI18N
257
}
258         return null;
259     }
260     
261     String JavaDoc getMimeType() {
262         if (textComponent instanceof JEditorPane) {
263             return ((JEditorPane) textComponent).getContentType();
264         }
265         return "text/plain"; // NOI18N
266
}
267
268     private static class DiffTopComponent extends TopComponent {
269         
270         private JComponent diffView;
271
272         public DiffTopComponent() {
273         }
274
275         public DiffTopComponent(JComponent c) {
276             this.diffView = c;
277             setLayout(new BorderLayout());
278             c.putClientProperty(TopComponent.class, this);
279             add(c, BorderLayout.CENTER);
280 // getAccessibleContext().setAccessibleName(NbBundle.getMessage(DiffTopComponent.class, "ACSN_Diff_Top_Component")); // NOI18N
281
// getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(DiffTopComponent.class, "ACSD_Diff_Top_Component")); // NOI18N
282
}
283
284         public UndoRedo getUndoRedo() {
285             UndoRedo undoredo = (UndoRedo) diffView.getClientProperty(UndoRedo.class);
286             return undoredo == null ? UndoRedo.NONE : undoredo;
287         }
288         
289         public int getPersistenceType(){
290             return TopComponent.PERSISTENCE_NEVER;
291         }
292
293         protected String JavaDoc preferredID(){
294             return "DiffSidebarTopComponent"; // NOI18N
295
}
296
297         public HelpCtx getHelpCtx() {
298             return new HelpCtx(getClass());
299         }
300     }
301
302     private int getLineFromMouseEvent(MouseEvent e){
303         int line = -1;
304         if (editorUI != null) {
305             try{
306                 JTextComponent component = editorUI.getComponent();
307                 BaseTextUI textUI = (BaseTextUI)component.getUI();
308                 int clickOffset = textUI.viewToModel(component, new Point(0, e.getY()));
309                 line = Utilities.getLineOffset(document, clickOffset);
310             }catch (BadLocationException ble){
311                 Logger.getLogger(DiffSidebar.class.getName()).log(Level.WARNING, "getLineFromMouseEvent", ble); // NOI18N
312
}
313         }
314         return line;
315     }
316
317     public void setSidebarVisible(boolean visible) {
318         if (visible) {
319             showSidebar();
320         } else {
321             hideSidebar();
322         }
323     }
324
325     private void showSidebar() {
326         annotated = true;
327
328         document.addDocumentListener(this);
329         textComponent.addComponentListener(this);
330         editorUI.addPropertyChangeListener(this);
331         foldHierarchy.addFoldHierarchyListener(this);
332         originalContent.addPropertyChangeListener(this);
333
334         refreshDiff();
335         revalidate(); // resize the component
336
}
337
338     private void hideSidebar() {
339         annotated = false;
340
341         originalContent.removePropertyChangeListener(this);
342         foldHierarchy.removeFoldHierarchyListener(this);
343         editorUI.removePropertyChangeListener(this);
344         textComponent.removeComponentListener(this);
345         document.removeDocumentListener(this);
346
347         refreshDiff();
348         revalidate();
349     }
350
351     private Reader getDocumentReader() {
352         JTextComponent component = editorUI.getComponent();
353         if (component == null) return null;
354
355         Document doc = component.getDocument();
356         try {
357             return new StringReader(doc.getText(0, doc.getLength()));
358         } catch (BadLocationException e) {
359             return null;
360         }
361     }
362     
363     private void refreshDiff() {
364         refreshDiffTask.schedule(50);
365     }
366         
367     MarkProvider getMarkProvider() {
368         return markProvider;
369     }
370
371     private static void copyStreamsCloseAll(Writer writer, Reader reader) throws IOException {
372         char [] buffer = new char[2048];
373         int n;
374         while ((n = reader.read(buffer)) != -1) {
375             writer.write(buffer, 0, n);
376         }
377         writer.close();
378         reader.close();
379     }
380
381     static void copyStreamsCloseAll(OutputStream writer, InputStream reader) throws IOException {
382         byte [] buffer = new byte[2048];
383         int n;
384         while ((n = reader.read(buffer)) != -1) {
385             writer.write(buffer, 0, n);
386         }
387         writer.close();
388         reader.close();
389     }
390     
391     public Dimension getPreferredSize() {
392         Dimension dim = textComponent.getSize();
393         dim.width = annotated ? BAR_WIDTH : 0;
394         return dim;
395     }
396     
397     public void paintComponent(Graphics g) {
398         super.paintComponent(g);
399
400         Rectangle clip = g.getClipBounds();
401         if (clip.y >= 16) {
402             // compensate for scrolling: marks on bottom/top edges are not drawn completely while scrolling
403
clip.y -= 16;
404             clip.height += 16;
405         }
406
407         JTextComponent component = editorUI.getComponent();
408         if (component == null) return;
409
410         BaseTextUI textUI = (BaseTextUI)component.getUI();
411         View rootView = Utilities.getDocumentView(component);
412         if (rootView == null) return;
413
414         g.setColor(backgroundColor());
415         g.fillRect(clip.x, clip.y, clip.width, clip.height);
416
417         Difference [] paintDiff = currentDiff;
418         if (paintDiff == null || paintDiff.length == 0) return;
419         
420         try{
421             int startPos = textUI.getPosFromY(clip.y);
422             int startViewIndex = rootView.getViewIndex(startPos,Position.Bias.Forward);
423             int rootViewCount = rootView.getViewCount();
424
425             if (startViewIndex >= 0 && startViewIndex < rootViewCount) {
426                 // find the nearest visible line with an annotation
427
Rectangle rec = textUI.modelToView(component, rootView.getView(startViewIndex).getStartOffset());
428                 int y = (rec == null) ? 0 : rec.y;
429                 int [] yCoords = new int[3];
430
431                 int clipEndY = clip.y + clip.height;
432                 Element rootElem = textUI.getRootView(component).getElement();
433
434                 View view = rootView.getView(startViewIndex);
435                 int line = rootElem.getElementIndex(view.getStartOffset());
436                 line++; // make it 1-based
437
if (line == 1 && paintDiff[0].getSecondStart() == 0 && paintDiff[0].getType() == Difference.DELETE) {
438                     g.setColor(getColor(paintDiff[0]));
439                     yCoords[0] = y - editorUI.getLineAscent() / 2;
440                     yCoords[1] = y;
441                     yCoords[2] = y + editorUI.getLineAscent() / 2;
442                     g.fillPolygon(new int [] { 0, BAR_WIDTH, 0 }, yCoords, 3);
443                 }
444                 
445                 for (int i = startViewIndex; i < rootViewCount; i++){
446                     view = rootView.getView(i);
447                     line = rootElem.getElementIndex(view.getStartOffset());
448                     line++; // make it 1-based
449
Difference ad = getDifference(line);
450                     if (ad != null) {
451                         g.setColor(getColor(ad));
452                         if (ad.getType() == Difference.DELETE) {
453                             yCoords[0] = y + editorUI.getLineAscent();
454                             yCoords[1] = y + editorUI.getLineAscent() * 3 / 2;
455                             yCoords[2] = y + editorUI.getLineAscent() * 2;
456                             g.fillPolygon(new int [] { 2, BAR_WIDTH, 2 }, yCoords, 3);
457                             g.setColor(colorBorder);
458                             g.drawLine(2, yCoords[0], 2, yCoords[2] - 1);
459                         } else {
460                             g.fillRect(3, y, BAR_WIDTH - 3, editorUI.getLineHeight());
461                             g.setColor(colorBorder);
462                             g.drawLine(2, y, 2, y + editorUI.getLineHeight());
463                             if (ad.getSecondStart() == line) {
464                                 g.drawLine(2, y, BAR_WIDTH - 1, y);
465                             }
466                             if (ad.getSecondEnd() == line) {
467                                 g.drawLine(2, y + editorUI.getLineHeight(), BAR_WIDTH - 1, y + editorUI.getLineHeight());
468                             }
469                         }
470                     }
471                     y += editorUI.getLineHeight();
472                     if (y >= clipEndY) {
473                         break;
474                     }
475                 }
476             }
477         } catch (BadLocationException ble){
478             ErrorManager.getDefault().notify(ble);
479         }
480     }
481
482     private Color getColor(Difference ad) {
483         if (ad.getType() == Difference.ADD) return colorAdded;
484         if (ad.getType() == Difference.CHANGE) return colorChanged;
485         return colorRemoved;
486     }
487
488     private Difference getDifference(int line) {
489         if (line < 0) return null;
490         for (int i = 0; i < currentDiff.length; i++) {
491             Difference difference = currentDiff[i];
492             if (line < difference.getSecondStart()) return null;
493             if (difference.getType() == Difference.DELETE && line == difference.getSecondStart()) return difference;
494             if (line <= difference.getSecondEnd()) return difference;
495         }
496         return null;
497     }
498
499     private Color backgroundColor() {
500         if (textComponent != null) {
501             return textComponent.getBackground();
502         }
503
504         return Color.WHITE;
505     }
506
507     public void insertUpdate(DocumentEvent JavaDoc e) {
508         refreshDiff();
509     }
510
511     public void removeUpdate(DocumentEvent JavaDoc e) {
512         refreshDiff();
513     }
514
515     public void changedUpdate(DocumentEvent JavaDoc e) {
516         refreshDiff();
517     }
518
519     public void componentResized(ComponentEvent e) {
520         revalidate();
521     }
522
523     public void componentMoved(ComponentEvent e) {
524     }
525
526     public void componentShown(ComponentEvent e) {
527     }
528
529     public void componentHidden(ComponentEvent e) {
530     }
531
532     public void propertyChange(PropertyChangeEvent JavaDoc evt) {
533         String JavaDoc id = evt.getPropertyName();
534         if (EditorUI.COMPONENT_PROPERTY.equals(id)) { // NOI18N
535
if (evt.getNewValue() == null){
536                 hideSidebar();
537             }
538         } else if (OriginalContent.PROP_CONTENT_CHANGED.equals(id)) {
539             originalContentSerial++;
540             refreshDiff();
541         }
542     }
543
544     public void foldHierarchyChanged(FoldHierarchyEvent evt) {
545         repaint();
546     }
547
548     /**
549      * Integration provider for the error stripe.
550      */

551     private class DiffMarkProvider extends MarkProvider {
552
553         private List JavaDoc<DiffMark> marks;
554
555         public DiffMarkProvider() {
556             marks = getMarksForDifferences();
557         }
558
559         public List JavaDoc getMarks() {
560             return marks;
561         }
562
563         void refresh() {
564             List JavaDoc<DiffMark> oldMarks = marks;
565             marks = getMarksForDifferences();
566             firePropertyChange(PROP_MARKS, oldMarks, marks);
567         }
568
569         private List JavaDoc<DiffMark> getMarksForDifferences() {
570             if (currentDiff == null) return Collections.emptyList();
571             List JavaDoc<DiffMark> marks = new ArrayList<DiffMark>(currentDiff.length);
572             for (int i = 0; i < currentDiff.length; i++) {
573                 Difference difference = currentDiff[i];
574                 marks.add(new DiffMark(difference, getColor(difference)));
575             }
576             return marks;
577         }
578     }
579
580     /**
581      * RP task to compute new diff after a change in the document or a change in the base text.
582      */

583     public class RefreshDiffTask implements Runnable JavaDoc {
584
585         public void run() {
586             computeDiff();
587             repaint();
588             markProvider.refresh();
589         }
590
591         private void computeDiff() {
592             if (!annotated) {
593                 currentDiff = null;
594                 return;
595             }
596             fetchOriginalContent();
597             if (originalContentBuffer == null) {
598                 currentDiff = null;
599                 return;
600             }
601             Reader working = getDocumentReader();
602             if (working == null) {
603                 // TODO: what to do in this case? let's keep the old dirrerence set for now
604
return;
605             }
606             DiffProvider diff = Lookup.getDefault().lookup(DiffProvider.class);
607             if (diff == null) {
608                 currentDiff = null;
609                 return;
610             }
611             try {
612                 currentDiff = diff.computeDiff(new StringReader(originalContentBuffer), working);
613             } catch (IOException e) {
614                 currentDiff = null;
615             }
616         }
617
618         private void fetchOriginalContent() {
619             int serial = originalContentSerial;
620             if (originalContentBuffer != null && originalContentBufferSerial == serial) return;
621             originalContentBufferSerial = serial;
622
623             Reader r = originalContent.getText();
624             if (r == null) return;
625
626             StringWriter w = new StringWriter(2048);
627             try {
628                 copyStreamsCloseAll(w, r);
629                 originalContentBuffer = w.toString();
630             } catch (IOException e) {
631                 // ignore, we will show no diff
632
}
633         }
634     }
635     
636     private class SidebarStreamSource extends StreamSource {
637
638         private final boolean isFirst;
639
640         public SidebarStreamSource(boolean isFirst) {
641             this.isFirst = isFirst;
642         }
643
644         public boolean isEditable() {
645             return !isFirst;
646         }
647
648         public Lookup getLookup() {
649             if (isFirst) return super.getLookup();
650             return Lookups.fixed(document);
651         }
652
653         public String JavaDoc getName() {
654             return originalContent.getWorkingCopy().getName();
655         }
656
657         public String JavaDoc getTitle() {
658             if (isFirst) {
659                 return NbBundle.getMessage(DiffSidebar.class, "LBL_DiffPane_Original"); // NOI18N
660
} else {
661                 return NbBundle.getMessage(DiffSidebar.class, "LBL_DiffPane_WorkingCopy"); // NOI18N
662
}
663         }
664
665         public String JavaDoc getMIMEType() {
666             return getMimeType();
667         }
668
669         public Reader createReader() throws IOException {
670             return isFirst ? new StringReader(originalContentBuffer) : getDocumentReader();
671         }
672
673         public Writer createWriter(Difference[] conflicts) throws IOException {
674             return null;
675         }
676     }
677 }
678
Popular Tags