This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 20439
Collapse All | Expand All

(-)src/org/openide/text/CloneableEditorSupport.java (-9 / +21 lines)
Lines 143-148 Link Here
143
    
143
    
144
    /** lines set for this object */
144
    /** lines set for this object */
145
    private Line.Set lineSet;
145
    private Line.Set lineSet;
146
    /** Lock used when for updating lineSet. */
147
    private final Object LOCK_LINE_SET = new Object();
146
148
147
    /** position manager */
149
    /** position manager */
148
    private PositionRef.Manager positionManager;
150
    private PositionRef.Manager positionManager;
Lines 958-974 Link Here
958
    * @return the set
960
    * @return the set
959
    */
961
    */
960
    Line.Set updateLineSet (boolean clear) {
962
    Line.Set updateLineSet (boolean clear) {
961
        if (lineSet != null && !clear) {
963
        synchronized(LOCK_LINE_SET) {
962
            return lineSet;
964
            if(lineSet != null && !clear) {
963
        }
965
                return lineSet;
966
            }
964
967
965
        if (doc == null) {
968
            Line.Set oldSet = lineSet;
966
            lineSet = new EditorSupportLineSet.Closed (CloneableEditorSupport.this);
969
967
        } else {
970
            if (doc == null) {
968
            lineSet = new EditorSupportLineSet (CloneableEditorSupport.this, doc);
971
                lineSet = new EditorSupportLineSet.Closed(CloneableEditorSupport.this);
969
        }
972
            } else {
973
                lineSet = new EditorSupportLineSet(CloneableEditorSupport.this, doc);
974
            }
970
975
971
        return lineSet;
976
            if(oldSet != null) {
977
                synchronized(oldSet.lines) {
978
                    lineSet.lines.putAll(oldSet.lines);
979
                }
980
            }
981
982
            return lineSet;
983
        }
972
    }
984
    }
973
985
974
986
(-)src/org/openide/text/DocumentLine.java (-65 / +55 lines)
Lines 14-21 Link Here
14
package org.openide.text;
14
package org.openide.text;
15
15
16
import java.io.*;
16
import java.io.*;
17
import java.util.*;
17
import java.util.ArrayList;
18
import java.lang.ref.*;
18
import java.util.Iterator;
19
import java.util.List;
19
import java.util.WeakHashMap;
20
import java.util.WeakHashMap;
20
import javax.swing.text.*;
21
import javax.swing.text.*;
21
import javax.swing.event.*;
22
import javax.swing.event.*;
Lines 23-28 Link Here
23
24
24
import org.openide.*;
25
import org.openide.*;
25
import org.openide.loaders.*;
26
import org.openide.loaders.*;
27
import org.openide.util.WeakSet;
26
import org.openide.util.WeakListener;
28
import org.openide.util.WeakListener;
27
import org.openide.util.Task;
29
import org.openide.util.Task;
28
import org.openide.util.RequestProcessor;
30
import org.openide.util.RequestProcessor;
Lines 80-86 Link Here
80
82
81
    /** Init listeners
83
    /** Init listeners
82
    */
84
    */
83
    private void init () {
85
    void init () {
84
        listener = new LR ();
86
        listener = new LR ();
85
        pos.getCloneableEditorSupport ().addChangeListener (WeakListener.change (listener, pos.getCloneableEditorSupport ()));
87
        pos.getCloneableEditorSupport ().addChangeListener (WeakListener.change (listener, pos.getCloneableEditorSupport ()));
86
    }
88
    }
Lines 272-278 Link Here
272
    /** Register line.
274
    /** Register line.
273
    */
275
    */
274
    Object readResolve() throws ObjectStreamException {
276
    Object readResolve() throws ObjectStreamException {
275
        return Set.registerLine (this);
277
//        return Set.registerLine (this);
278
        //Set.registerPendingLine(this);
279
        return this.pos.getCloneableEditorSupport().getLineSet().registerLine(this);
276
    }
280
    }
277
281
278
    
282
    
Lines 623-634 Link Here
623
    */
627
    */
624
    public static abstract class Set extends Line.Set {
628
    public static abstract class Set extends Line.Set {
625
        /** listener on document changes */
629
        /** listener on document changes */
626
        private LineListener listener;
630
        private final LineListener listener;
627
        /** all lines in the set or null */
631
        /** all lines in the set or null */
628
        private java.util.List list;
632
        private java.util.List list;
629
        /** map to hold all existing lines (Line, Reference (Line)) */
630
        private static WeakHashMap allLines = new WeakHashMap (37);
631
633
634
        
632
        /** Constructor.
635
        /** Constructor.
633
        * @param doc document to work on
636
        * @param doc document to work on
634
        */
637
        */
Lines 640-691 Link Here
640
            listener = new LineListener (doc, support);
643
            listener = new LineListener (doc, support);
641
        }
644
        }
642
645
646
        
643
        /** Find the line given as parameter in list of all lines attached to this set
647
        /** Find the line given as parameter in list of all lines attached to this set
644
         * and if the line exist in the list, notify it about being edited. */
648
         * and if the line exist in the list, notify it about being edited. */
645
        boolean fireLineChanged(Line comparingLine, DocumentEvent p0) {
649
        void linesChanged(int startLineNumber, int endLineNumber, DocumentEvent p0) {
646
            Reference ref = (Reference)allLines.get (comparingLine);
650
            List changedLines = getLinesFromRange(startLineNumber, endLineNumber);
647
            if (ref == null) {
648
                return false;
649
            }
650
            Line line = (Line)ref.get ();
651
            
651
            
652
            if(line == null) {
652
            for(Iterator it = changedLines.iterator(); it.hasNext(); ) {
653
                return false;
653
                Line line = (Line)it.next();
654
                
655
                line.firePropertyChange(Annotatable.PROP_TEXT, null, null);
656
657
                // revalidate all parts attached to this line
658
                // that they are still part of the line
659
                if(line instanceof DocumentLine) {
660
                    ((DocumentLine)line).notifyChange(p0, this, listener.doc);
661
                }
654
            }
662
            }
655
            
656
            line.firePropertyChange(Annotatable.PROP_TEXT, null, null);
657
658
            // revalidate all parts attached to this line
659
            // that they are still part of the line
660
            if (line instanceof DocumentLine)
661
                ((DocumentLine)line).notifyChange(p0, this, listener.doc);
662
            
663
            return true;
664
        }
663
        }
665
        
664
        
666
        /** Find the line given as parameter in list of all lines attached to this set
665
        /** Find the line given as parameter in list of all lines attached to this set
667
         * and if the line exist in the list, notify it about being moved. */
666
         * and if the line exist in the list, notify it about being moved. */
668
        boolean fireLineMoved(Line comparingLine) {
667
        void linesMoved(int startLineNumber, int endLineNumber) {
669
            Reference ref = (Reference)allLines.get (comparingLine);
668
            List movedLines = getLinesFromRange(startLineNumber, endLineNumber);
670
            if (ref == null) {
671
                return false;
672
            }
673
            Line line = (Line)ref.get ();
674
            
669
            
675
            if(line == null) {
670
            for(Iterator it = movedLines.iterator(); it.hasNext(); ) {
676
                return false;
671
                Line line = (Line)it.next();
672
                line.firePropertyChange(Line.PROP_LINE_NUMBER, null, null);
673
674
                // notify all parts attached to this line
675
                // that they were moved
676
                if (line instanceof DocumentLine) {
677
                    ((DocumentLine)line).notifyMove();
678
                } 
677
            }
679
            }
678
            
679
            line.firePropertyChange(Line.PROP_LINE_NUMBER, null, null);
680
            
681
            // notify all parts attached to this line
682
            // that they were moved
683
            if (line instanceof DocumentLine)
684
                ((DocumentLine)line).notifyMove();
685
686
            return true;
687
        }
680
        }
688
        
681
        
682
        /** Gets the lines with line number whitin the range inclusive.
683
         * @return <code>List</code> of lines from range inclusive */
684
        private List getLinesFromRange(int startLineNumber, int endLineNumber) {
685
            List linesInRange = new ArrayList(10);
686
687
            synchronized(lines) {
688
                for(Iterator it = lines.keySet().iterator(); it.hasNext(); ) {
689
                    Line line = (Line)it.next();
690
                    int lineNumber = line.getLineNumber();
691
                    if(startLineNumber <= lineNumber
692
                    && lineNumber <= endLineNumber) {
693
                        linesInRange.add(line);
694
                    }
695
                }
696
            }
697
            
698
            return linesInRange;
699
        }
700
689
        /* Returns an unmodifiable set of Lines sorted by their
701
        /* Returns an unmodifiable set of Lines sorted by their
690
        * line numbers that contains all lines holded by this
702
        * line numbers that contains all lines holded by this
691
        * Line.Set.
703
        * Line.Set.
Lines 714-723 Link Here
714
        public Line getOriginal (int line) throws IndexOutOfBoundsException {
726
        public Line getOriginal (int line) throws IndexOutOfBoundsException {
715
            int newLine = listener.getLine (line);
727
            int newLine = listener.getLine (line);
716
            int offset = NbDocument.findLineOffset (listener.doc, newLine);
728
            int offset = NbDocument.findLineOffset (listener.doc, newLine);
717
            //      System.out.println("Then: " + line + " now: " + newLine + " offset: " + offset); // NOI18N
718
            Line ll = registerLine (createLine (offset));
719
729
720
            return ll;
730
            return this.registerLine(createLine(offset));
721
        }
731
        }
722
732
723
        /* Creates current line.
733
        /* Creates current line.
Lines 727-736 Link Here
727
        */
737
        */
728
        public Line getCurrent (int line) throws IndexOutOfBoundsException {
738
        public Line getCurrent (int line) throws IndexOutOfBoundsException {
729
            int offset = NbDocument.findLineOffset (listener.doc, line);
739
            int offset = NbDocument.findLineOffset (listener.doc, line);
730
            //      System.out.println("Then: " + line + " now: " + newLine + " offset: " + offset); // NOI18N
731
            Line ll = registerLine (createLine (offset));
732
740
733
            return ll;
741
            return this.registerLine(createLine(offset));
734
        }
742
        }
735
743
736
        /** Creates a {@link Line} for a given offset.
744
        /** Creates a {@link Line} for a given offset.
Lines 739-762 Link Here
739
        */
747
        */
740
        protected abstract Line createLine (int offset);
748
        protected abstract Line createLine (int offset);
741
749
742
        /** Registers the line.
743
        * @param l line to register
744
        * @return the line l or line previously registered
745
        */
746
        static synchronized Line registerLine (Line l) {
747
            Reference ref = (Reference)allLines.get (l);
748
            Line prev = ref == null ? null : (Line)ref.get ();
749
            if (prev == null) {
750
                if (l instanceof DocumentLine)
751
                    ((DocumentLine)l).init ();
752
                allLines.put (l, new WeakReference (l));
753
                return l;
754
            } else {
755
                return prev;
756
            }
757
758
759
        }
760
    }
750
    }
761
751
762
752
(-)src/org/openide/text/EditorSupportLineSet.java (-3 / +2 lines)
Lines 125-131 Link Here
125
        */
125
        */
126
        public java.util.List getLines () {
126
        public java.util.List getLines () {
127
            if (delegate != null) {
127
            if (delegate != null) {
128
                return delegate.getLines ();
128
                return delegate.getLines();
129
            }
129
            }
130
            // PENDING
130
            // PENDING
131
            return new java.util.ArrayList ();
131
            return new java.util.ArrayList ();
Lines 159-166 Link Here
159
            // obj can be null, sorry...
159
            // obj can be null, sorry...
160
            DataObject obj = support.getDataObjectHack ();
160
            DataObject obj = support.getDataObjectHack ();
161
            
161
            
162
            Line l = registerLine (new SupportLine (obj, ref, support));
162
            return this.registerLine(new SupportLine(obj, ref, support));
163
            return l;
164
        }
163
        }
165
164
166
165
(-)src/org/openide/text/Line.java (-1 / +38 lines)
Lines 14-20 Link Here
14
package org.openide.text;
14
package org.openide.text;
15
15
16
import java.io.*;
16
import java.io.*;
17
import java.lang.ref.Reference;
18
import java.lang.ref.WeakReference;
17
import java.util.Date;
19
import java.util.Date;
20
import java.util.Map;
21
import java.util.WeakHashMap;
18
22
19
import org.openide.filesystems.FileObject;
23
import org.openide.filesystems.FileObject;
20
import org.openide.loaders.DataObject;
24
import org.openide.loaders.DataObject;
Lines 258-263 Link Here
258
        /** date when the object has been created */
262
        /** date when the object has been created */
259
        private Date date;
263
        private Date date;
260
264
265
        /** <code>Map</code> which contains all lines as keys and 
266
         * values weakReferences on itself. There woudl be better use
267
         * set but there is missing get method, returning equal object.
268
         * belonging to this <code>Line.Set</code>.
269
         * @see DocumentLine#hashCode 
270
         * @see DocumentLine#equals 
271
         * @see #registerLine */
272
        final java.util.Map lines = new WeakHashMap(10);
273
        
274
261
        /** Create a new snapshot. Remembers the date when it was created. */
275
        /** Create a new snapshot. Remembers the date when it was created. */
262
        public Set () {
276
        public Set () {
263
            date = new Date ();
277
            date = new Date ();
Lines 297-301 Link Here
297
        */
311
        */
298
        public abstract Line getCurrent (int line) throws IndexOutOfBoundsException;
312
        public abstract Line getCurrent (int line) throws IndexOutOfBoundsException;
299
313
300
    }
314
        /** Registers the line to this <code>Line.Set</code>.
315
         * @param line <code>Line</code> to register
316
         * @return registered <code>Line</code>. <em>Note:</em> the retruned
317
         * <code>Line</code> could be different (identityHashCode not equal)
318
         * from the one passed in */
319
        Line registerLine(Line line) {
320
            synchronized(lines) {
321
                Reference r = (Reference)lines.get(line);
322
                Line in = (r != null ? (Line)r.get() : null);
323
                
324
                if(in == null) {
325
                    if(line instanceof DocumentLine) {
326
                        ((DocumentLine)line).init();
327
                    }
328
329
                    lines.put(line, new WeakReference(line));
330
                    in = line;
331
                }
332
                
333
                return in;
334
            }
335
        }
336
337
    } // End of class Line.Set.
301
}
338
}
(-)src/org/openide/text/LineListener.java (-42 / +17 lines)
Lines 35-46 Link Here
35
    private int lines;
35
    private int lines;
36
    /** operations on lines */
36
    /** operations on lines */
37
    private LineStruct struct;
37
    private LineStruct struct;
38
    /** "fake" line used only for comparing with other lines. Check how DocumentLine.equal()
38
39
     * works. This line is used for comparing with lines in DocumentLine.Set.allLines array. This is
39
    
40
     * more hack than regular solution */
41
    private ComparingLine comparingLine = null;
42
    /** Support necessary for getting Set of lines*/
40
    /** Support necessary for getting Set of lines*/
43
    private CloneableEditorSupport support;
41
    CloneableEditorSupport support;
44
    
42
    
45
    /** Creates new LineListener */
43
    /** Creates new LineListener */
46
    public LineListener (StyledDocument doc, CloneableEditorSupport support) {
44
    public LineListener (StyledDocument doc, CloneableEditorSupport support) {
Lines 49-56 Link Here
49
        root = NbDocument.findLineRootElement (doc);
47
        root = NbDocument.findLineRootElement (doc);
50
        orig = lines = root.getElementCount ();
48
        orig = lines = root.getElementCount ();
51
        this.support = support;
49
        this.support = support;
52
        if (support != null)
53
            comparingLine = new ComparingLine();
54
        
50
        
55
        doc.addDocumentListener(WeakListener.document (this, doc));
51
        doc.addDocumentListener(WeakListener.document (this, doc));
56
    }
52
    }
Lines 83-98 Link Here
83
        Line.Set set = support.getLineSet ();
79
        Line.Set set = support.getLineSet ();
84
        if (!(set instanceof DocumentLine.Set))
80
        if (!(set instanceof DocumentLine.Set))
85
            return;
81
            return;
86
        for (int i=lineNumber; i<=lineNumber+delta; i++) {
82
87
            comparingLine.setLineNumber(i);
83
        // Notify lineSet there was changed range of lines.
88
            ((DocumentLine.Set)set).fireLineChanged(comparingLine, p0);
84
        ((DocumentLine.Set)set).linesChanged(lineNumber, lineNumber+delta, p0);
89
        }
85
        
90
        if (delta > 0) {
86
        if (delta > 0) {
91
            // notify lines that there they were moved
87
            // Notify Line.Set there was moved range of lines.
92
            for (int i=lineNumber; i<elem; i++) {
88
            ((DocumentLine.Set)set).linesMoved(lineNumber, elem);
93
                comparingLine.setLineNumber(i);
94
                ((DocumentLine.Set)set).fireLineMoved(comparingLine);
95
            }
96
        }
89
        }
97
    }
90
    }
98
91
Lines 101-106 Link Here
101
94
102
    public void insertUpdate(javax.swing.event.DocumentEvent p0) {
95
    public void insertUpdate(javax.swing.event.DocumentEvent p0) {
103
        int elem = root.getElementCount ();
96
        int elem = root.getElementCount ();
97
        
104
        int delta = elem - lines;
98
        int delta = elem - lines;
105
        lines = elem;
99
        lines = elem;
106
100
Lines 112-149 Link Here
112
                delta
106
                delta
113
            );
107
            );
114
        }
108
        }
109
        
115
        if ( support == null)
110
        if ( support == null)
116
            return;
111
            return;
117
        Line.Set set = support.getLineSet ();
112
        Line.Set set = support.getLineSet ();
118
        if (!(set instanceof DocumentLine.Set))
113
        if (!(set instanceof DocumentLine.Set))
119
            return;
114
            return;
120
        comparingLine.setLineNumber(lineNumber);
115
        
121
        ((DocumentLine.Set)set).fireLineChanged(comparingLine, p0);
116
        // Nptify Line.Set there was changed range of lines.
117
        ((DocumentLine.Set)set).linesChanged(lineNumber, lineNumber, p0);
118
        
122
        if (delta > 0) {
119
        if (delta > 0) {
123
            // notify lines that there they were moved
120
            // Notify Line.Set there was moved range of lines.
124
            for (int i=lineNumber; i<elem; i++) {
121
            ((DocumentLine.Set)set).linesMoved(lineNumber, elem);
125
                comparingLine.setLineNumber(i);
126
                ((DocumentLine.Set)set).fireLineMoved(comparingLine);
127
            }
128
        }
129
    }
130
   
131
    /** This class allow to create fake lines. The instance of this class is
132
     * used only for one purpose: as key into DocumentLine.Set.allLines 
133
     * array to learn whether the Line for the given line number exist or 
134
     * not. See also how DocumentLine.equal works. */
135
    private class ComparingLine extends DocumentLine {
136
        private int lineNumber;
137
        public ComparingLine() {
138
            super(null, new PositionRef(support.getPositionManager (), 0, Position.Bias.Backward));
139
        }
140
        public int getLineNumber () {
141
            return lineNumber;
142
        }
143
        public int setLineNumber (int lineNumber) {
144
            return this.lineNumber = lineNumber;
145
        }
146
        public void show(int kind, int column) {
147
        }
122
        }
148
    }
123
    }
149
    
124
    

Return to bug 20439