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 241991
Collapse All | Expand All

(-)a/openide.text/src/org/openide/text/CloneableEditorSupport.java (-9 / +21 lines)
Lines 180-186 Link Here
180
    private UndoRedo.Manager undoRedo;
180
    private UndoRedo.Manager undoRedo;
181
181
182
    /** lines set for this object */
182
    /** lines set for this object */
183
    private Line.Set lineSet;
183
    private Line.Set[] lineSet = new Line.Set[] { null };
184
184
185
    /** Helper variable to prevent multiple cocurrent printing of this
185
    /** Helper variable to prevent multiple cocurrent printing of this
186
     * instance. */
186
     * instance. */
Lines 196-202 Link Here
196
    private Set<ChangeListener> listeners;
196
    private Set<ChangeListener> listeners;
197
197
198
    /** last selected editor pane. */
198
    /** last selected editor pane. */
199
    private transient Reference<Pane> lastSelected;
199
    private transient Reference<Pane> lastSelected[] = new Reference[] { null };
200
200
201
    /** The time of the last save to determine the real external modifications */
201
    /** The time of the last save to determine the real external modifications */
202
    private long lastSaveTime;
202
    private long lastSaveTime;
Lines 905-921 Link Here
905
905
906
        return null;
906
        return null;
907
    }
907
    }
908
909
    @Override
910
    protected void redirectedOpen(CloneableOpenSupport redirectedTo) {
911
        super.redirectedOpen(redirectedTo);
912
        // synchronize last selected field for correct getRecentPane query
913
        if (redirectedTo instanceof CloneableEditorSupport) {
914
            CloneableEditorSupport other = ((CloneableEditorSupport)redirectedTo);
915
            this.lastSelected = other.lastSelected;
916
            this.openClose = other.openClose;
917
            this.lineSet = other.lineSet;
918
        }
919
    }
908
    
920
    
909
    /** Returns the lastly selected Pane or null
921
    /** Returns the lastly selected Pane or null
910
     */
922
     */
911
    final Pane getLastSelected() {
923
    final Pane getLastSelected() {
912
        Reference<Pane> r = lastSelected;
924
        Reference<Pane> r = lastSelected[0];
913
925
914
        return (r == null) ? null : r.get();
926
        return (r == null) ? null : r.get();
915
    }
927
    }
916
928
917
    final void setLastSelected(Pane lastSelected) {
929
    final void setLastSelected(Pane lastSelected) {
918
        this.lastSelected = new WeakReference<Pane>(lastSelected);
930
        this.lastSelected[0] = new WeakReference<Pane>(lastSelected);
919
    }
931
    }
920
932
921
    //
933
    //
Lines 1639-1657 Link Here
1639
    */
1651
    */
1640
    Line.Set updateLineSet(boolean clear) {
1652
    Line.Set updateLineSet(boolean clear) {
1641
        synchronized (getLock()) {
1653
        synchronized (getLock()) {
1642
            if ((lineSet != null) && !clear) {
1654
            if ((lineSet[0] != null) && !clear) {
1643
                return lineSet;
1655
                return lineSet[0];
1644
            }
1656
            }
1645
1657
1646
            if ((getDoc() == null) ||
1658
            if ((getDoc() == null) ||
1647
                (openClose.getDocumentStatusLA() == DocumentStatus.RELOADING))
1659
                (openClose.getDocumentStatusLA() == DocumentStatus.RELOADING))
1648
            {
1660
            {
1649
                lineSet = new EditorSupportLineSet.Closed(CloneableEditorSupport.this);
1661
                lineSet[0] = new EditorSupportLineSet.Closed(CloneableEditorSupport.this);
1650
            } else {
1662
            } else {
1651
                lineSet = new EditorSupportLineSet(CloneableEditorSupport.this,getDoc());
1663
                lineSet[0] = new EditorSupportLineSet(CloneableEditorSupport.this,getDoc());
1652
            }
1664
            }
1653
1665
1654
            return lineSet;
1666
            return lineSet[0];
1655
        }
1667
        }
1656
    }
1668
    }
1657
1669
(-)a/openide.text/test/unit/src/org/openide/text/CloneableEditorSupportRedirectorTest.java (-58 / +62 lines)
Lines 39-45 Link Here
39
import java.lang.ref.WeakReference;
39
import java.lang.ref.WeakReference;
40
import java.util.Arrays;
40
import java.util.Arrays;
41
import javax.swing.SwingUtilities;
41
import javax.swing.SwingUtilities;
42
import javax.swing.text.BadLocationException;
43
import javax.swing.text.Document;
42
import javax.swing.text.Document;
44
import javax.swing.text.EditorKit;
43
import javax.swing.text.EditorKit;
45
import junit.framework.Test;
44
import junit.framework.Test;
Lines 50-65 Link Here
50
import org.openide.util.Lookup;
49
import org.openide.util.Lookup;
51
import org.openide.util.lookup.AbstractLookup;
50
import org.openide.util.lookup.AbstractLookup;
52
import org.openide.util.lookup.InstanceContent;
51
import org.openide.util.lookup.InstanceContent;
52
import org.openide.windows.CloneableOpenSupport;
53
import org.openide.windows.CloneableOpenSupportRedirector;
53
54
54
/**
55
/**
55
 *
56
 * @author Vladimir Voskresensky
56
 * @author Jaroslav Tulach
57
 * @author Jaroslav Tulach
57
 */
58
 */
58
public class CloneableEditorSupportRedirectorTest extends NbTestCase
59
public class CloneableEditorSupportCOSRedirectorTest extends NbTestCase
59
implements CloneableEditorSupport.Env {
60
implements CloneableEditorSupport.Env {
60
61
61
    public static Test suite() {
62
    public static Test suite() {
62
        return GraphicsEnvironment.isHeadless() ? new TestSuite() : new TestSuite(CloneableEditorSupportRedirectorTest.class);
63
        return GraphicsEnvironment.isHeadless() ? new TestSuite() : new TestSuite(CloneableEditorSupportCOSRedirectorTest.class);
63
    }
64
    }
64
65
65
    static {
66
    static {
Lines 71-88 Link Here
71
72
72
    
73
    
73
    // Env variables
74
    // Env variables
74
    private String content = "";
75
    private StringBuilder content = new StringBuilder("");
75
    private boolean valid = true;
76
    private boolean valid = true;
76
    private boolean modified = false;
77
    private boolean modified = false;
77
    /** if not null contains message why this document cannot be modified */
78
    private String cannotBeModified;
79
    private java.util.Date date = new java.util.Date ();
78
    private java.util.Date date = new java.util.Date ();
80
    private java.util.List<PropertyChangeListener> propL = new java.util.ArrayList<PropertyChangeListener>();
79
    private java.util.List<PropertyChangeListener> propL = new java.util.ArrayList<PropertyChangeListener>();
81
    private java.beans.VetoableChangeListener vetoL;
80
    private java.beans.VetoableChangeListener vetoL;
82
81
83
    
82
    
84
    
83
    
85
    public CloneableEditorSupportRedirectorTest(String testName) {
84
    public CloneableEditorSupportCOSRedirectorTest(String testName) {
86
        super(testName);
85
        super(testName);
87
    }
86
    }
88
    
87
    
Lines 94-121 Link Here
94
        red = Lookup.getDefault().lookup(Redirector.class);
93
        red = Lookup.getDefault().lookup(Redirector.class);
95
        assertNotNull(red);
94
        assertNotNull(red);
96
95
97
        CloneableEditorSupportRedirectorTest t = new CloneableEditorSupportRedirectorTest("");
96
        CloneableEditorSupportCOSRedirectorTest t = new CloneableEditorSupportCOSRedirectorTest("");
97
        t.content = content;
98
        red.master = support;
98
        red.master = support;
99
        InstanceContent slave = new InstanceContent();
99
        InstanceContent slave = new InstanceContent();
100
        red.slave = new CES(t, new AbstractLookup (slave));
100
        red.slave = new CES(t, new AbstractLookup (slave));
101
        slave.add(red.master);
101
        slave.add(red.master);
102
        red.master.open();
103
        red.slave.open();        
102
    }
104
    }
103
    
105
104
    public void testSameDocument() throws Exception {
106
    @Override
107
    protected void tearDown() throws Exception {
108
        super.tearDown(); 
109
        red.master.close();
110
        red.slave.close();     
111
        content.delete(0, content.length());
112
    }
113
        
114
    public void testSameDocument() throws Exception {    
105
        javax.swing.text.Document doc = red.slave.openDocument ();
115
        javax.swing.text.Document doc = red.slave.openDocument ();
106
        assertNotNull (doc);
116
        assertNotNull (doc);
107
        
117
        
108
        assertSame(doc, red.master.getDocument());
118
        assertSame(doc, red.master.getDocument());
109
        
119
        
110
        String s = doc.getText (0, doc.getLength ());
120
        String s = doc.getText (0, doc.getLength ());
111
        assertEquals ("Same text as in the stream", content, s);
121
        assertEquals ("Same text as in the stream", content.toString(), s);
112
        
122
        
113
        assertFalse ("No redo", red.slave.getUndoRedo ().canRedo ());
123
        assertFalse ("No redo", red.slave.getUndoRedo ().canRedo ());
114
        assertFalse ("No undo", red.slave.getUndoRedo ().canUndo ());
124
        assertFalse ("No undo", red.slave.getUndoRedo ().canUndo ());
115
    }
125
    }
116
    
126
    
117
    public void testLineLookupIsPropagated () throws Exception {
127
    public void testLineLookupIsPropagated () throws Exception {
118
        content = "Line1\nLine2\n";
128
        content.append("Line1\nLine2\n");
119
        Integer template = new Integer (1);
129
        Integer template = new Integer (1);
120
        ic.add (template); // put anything into the lookup
130
        ic.add (template); // put anything into the lookup
121
        
131
        
Lines 137-143 Link Here
137
    
147
    
138
    
148
    
139
    public void testGetInputStream () throws Exception {
149
    public void testGetInputStream () throws Exception {
140
        content = "goes\nto\nInputStream";
150
        content.append("goes\nto\nInputStream");
141
        String added = "added before\n";
151
        String added = "added before\n";
142
        javax.swing.text.Document doc = red.master.openDocument ();
152
        javax.swing.text.Document doc = red.master.openDocument ();
143
        assertNotNull (doc);
153
        assertNotNull (doc);
Lines 149-186 Link Here
149
    }
159
    }
150
    
160
    
151
    public void testGetInputStreamWhenClosed () throws Exception {
161
    public void testGetInputStreamWhenClosed () throws Exception {
152
        content = "basic\ncontent";
162
        content.append("basic\ncontent");
153
        compareStreamWithString(red.master.getInputStream(), content);
163
        compareStreamWithString(red.master.getInputStream(), content);
154
        compareStreamWithString(red.slave.getInputStream(), content);
164
        compareStreamWithString(red.slave.getInputStream(), content);
155
        // we should be doing this with the document still closed 
165
        // we should be doing this with the document still closed 
156
        assertNull("The document is supposed to be still closed", red.master.getDocument ());
166
        assertNull("The document is supposed to be still closed", red.master.getDocument ());
157
    }
167
    }
158
    
168
    
159
    public void testDocumentCannotBeModified () throws Exception {
160
        content = "Ahoj\nMyDoc";
161
        cannotBeModified = "No, you cannot modify this document in this test";
162
        
163
        javax.swing.text.Document doc = red.master.openDocument ();
164
        assertNotNull (doc);
165
        
166
        assertFalse ("Nothing to undo", red.master.getUndoRedo ().canUndo ());
167
        
168
        // this should not be allowed
169
        try {
170
            doc.insertString (0, "Kuk", null);
171
            fail("Modification should not proceed");
172
        } catch (BadLocationException ex) {
173
            // Expected
174
        }
175
        
176
        String s = doc.getText (0, doc.getLength ());
177
        assertEquals ("The document is now the same as at the begining", content, s);
178
        
179
        assertEquals ("Message has been shown to user in status bar", cannotBeModified, org.openide.awt.StatusDisplayer.getDefault ().getStatusText ());
180
    }
181
    
182
    public void testDocumentCanBeGarbageCollectedWhenClosed () throws Exception {
169
    public void testDocumentCanBeGarbageCollectedWhenClosed () throws Exception {
183
        content = "Ahoj\nMyDoc";
170
        content.append("Ahoj\nMyDoc");
184
        javax.swing.text.Document doc = red.master.openDocument ();
171
        javax.swing.text.Document doc = red.master.openDocument ();
185
        assertNotNull (doc);
172
        assertNotNull (doc);
186
        
173
        
Lines 226-239 Link Here
226
        assertEquals("Wrong default EditorKit", "org.openide.text.CloneableEditorSupport$PlainEditorKit", kit.getClass().getName());
213
        assertEquals("Wrong default EditorKit", "org.openide.text.CloneableEditorSupport$PlainEditorKit", kit.getClass().getName());
227
    }
214
    }
228
    
215
    
229
    private void compareStreamWithString(InputStream is, String s) throws Exception{
216
    private void compareStreamWithString(InputStream is, CharSequence s) throws Exception{
230
        int i;
217
        int i;
231
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
218
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
232
        while ((i = is.read()) != -1) {
219
        while ((i = is.read()) != -1) {
233
            baos.write(i);
220
            baos.write(i);
234
        }
221
        }
235
        byte b1[] = baos.toByteArray();
222
        byte b1[] = baos.toByteArray();
236
        byte b2[] = s.getBytes();
223
        byte b2[] = s.toString().getBytes();
237
        assertTrue("Same bytes as would result from the string: " + s, Arrays.equals(b1, b2));
224
        assertTrue("Same bytes as would result from the string: " + s, Arrays.equals(b1, b2));
238
    }
225
    }
239
    
226
    
Lines 270-282 Link Here
270
    }
257
    }
271
    
258
    
272
    public java.io.InputStream inputStream() throws java.io.IOException {
259
    public java.io.InputStream inputStream() throws java.io.IOException {
273
        return new java.io.ByteArrayInputStream (content.getBytes ());
260
        return new java.io.ByteArrayInputStream (content.toString().getBytes ());
274
    }
261
    }
275
    public java.io.OutputStream outputStream() throws java.io.IOException {
262
    public java.io.OutputStream outputStream() throws java.io.IOException {
276
        class ContentStream extends java.io.ByteArrayOutputStream {
263
        class ContentStream extends java.io.ByteArrayOutputStream {
277
            public void close () throws java.io.IOException {
264
            public void close () throws java.io.IOException {
278
                super.close ();
265
                super.close ();
279
                content = new String (toByteArray ());
266
                content.append(new String (toByteArray ()));
280
            }
267
            }
281
        }
268
        }
282
        
269
        
Lines 292-307 Link Here
292
    }
279
    }
293
280
294
    public void markModified() throws java.io.IOException {
281
    public void markModified() throws java.io.IOException {
295
        if (cannotBeModified != null) {
282
//        if (cannotBeModified != null) {
296
            final String notify = cannotBeModified;
283
//            final String notify = cannotBeModified;
297
            IOException e = new IOException () {
284
//            IOException e = new IOException () {
298
                public String getLocalizedMessage () {
285
//                public String getLocalizedMessage () {
299
                    return notify;
286
//                    return notify;
300
                }
287
//                }
301
            };
288
//            };
302
            Exceptions.attachLocalizedMessage(e, cannotBeModified);
289
//            Exceptions.attachLocalizedMessage(e, cannotBeModified);
303
            throw e;
290
//            throw e;
304
        }
291
//        }
305
        
292
        
306
        modified = true;
293
        modified = true;
307
    }
294
    }
Lines 315-320 Link Here
315
        public CES (Env env, Lookup l) {
302
        public CES (Env env, Lookup l) {
316
            super (env, l);
303
            super (env, l);
317
        }
304
        }
305
306
        @Override
307
        protected boolean asynchronousOpen() {
308
            return true;
309
        }
318
        
310
        
319
        protected String messageName() {
311
        protected String messageName() {
320
            return "Name";
312
            return "Name";
Lines 339-350 Link Here
339
    }
331
    }
340
332
341
    
333
    
342
    public static final class Redirector extends CloneableEditorSupportRedirector {
334
    public static final class Redirector extends CloneableOpenSupportRedirector {
343
        CES master;
335
        CES master;
344
        CES slave;
336
        CES slave;
345
    
337
346
        protected CloneableEditorSupport redirect(Lookup ces) {
338
        @Override
347
            return ces.lookup(CloneableEditorSupport.class);
339
        protected CloneableOpenSupport redirect(CloneableOpenSupport.Env env) {
340
            if (env == slave.cesEnv()) {
341
                return master;
342
            }
343
            return null;
348
        }
344
        }
345
346
        @Override
347
        protected void opened(CloneableOpenSupport.Env env) {
348
        }
349
350
        @Override
351
        protected void closed(CloneableOpenSupport.Env env) {
352
        }
353
    }
349
}
354
}
350
}
(-)a/openide.windows/src/org/openide/windows/CloneableOpenSupport.java (+24 lines)
Lines 97-102 Link Here
97
        CloneableOpenSupport redirect = CloneableOpenSupportRedirector.findRedirect(this);
97
        CloneableOpenSupport redirect = CloneableOpenSupportRedirector.findRedirect(this);
98
        if (redirect != null) {
98
        if (redirect != null) {
99
            redirect.open();
99
            redirect.open();
100
            this.redirectedOpenImpl(redirect);
100
            return;
101
            return;
101
        }
102
        }
102
        //Bugfix #10688 open() is now run in AWT thread
103
        //Bugfix #10688 open() is now run in AWT thread
Lines 246-251 Link Here
246
    */
247
    */
247
    protected abstract String messageOpened();
248
    protected abstract String messageOpened();
248
249
250
    private void redirectedOpenImpl(CloneableOpenSupport redirectedTo) {
251
        // there is a common patern in user code:
252
        // CloneableEditorSupport ces = ...;
253
        // ces.edit();
254
        // JEditorPane[] panes = ces.getOpenedPanes();
255
        // if (panes != null) panes[0].setPosition(offset);
256
        // in case when redirection has happened during edit() call
257
        // 'ces' instance returns null for getOpenedPanes
258
        // but we want panes to be available for 'ces' instance after redirection;
259
        // remember editors from redirected instance to have correct opened panes
260
        // for this instance as well
261
        this.allEditors = redirectedTo.allEditors;
262
//        this.env = redirect.env;
263
        redirectedOpen(redirectedTo);
264
    }
265
    
266
    /**
267
     * notify that other redirected cos was opened instead of this one.
268
     * @param redirectedTo redirected instance which was opened instead of this one
269
     */
270
    protected void redirectedOpen(CloneableOpenSupport redirectedTo) {
271
    }
272
249
    /** Abstract interface that is used by CloneableOpenSupport to
273
    /** Abstract interface that is used by CloneableOpenSupport to
250
    * talk to outside world.
274
    * talk to outside world.
251
    */
275
    */

Return to bug 241991