Lines 11-17
Link Here
|
11 |
* Microsystems, Inc. All Rights Reserved. |
11 |
* Microsystems, Inc. All Rights Reserved. |
12 |
*/ |
12 |
*/ |
13 |
package org.openide.text; |
13 |
package org.openide.text; |
14 |
|
14 |
import javax.swing.event.ChangeEvent; |
|
|
15 |
import javax.swing.event.ChangeListener; |
15 |
import org.openide.ErrorManager; |
16 |
import org.openide.ErrorManager; |
16 |
import org.openide.awt.UndoRedo; |
17 |
import org.openide.awt.UndoRedo; |
17 |
import org.openide.cookies.EditorCookie; |
18 |
import org.openide.cookies.EditorCookie; |
Lines 19-24
Link Here
|
19 |
import org.openide.util.Mutex; |
20 |
import org.openide.util.Mutex; |
20 |
import org.openide.util.NbBundle; |
21 |
import org.openide.util.NbBundle; |
21 |
import org.openide.util.Task; |
22 |
import org.openide.util.Task; |
|
|
23 |
import org.openide.util.WeakSet; |
22 |
import org.openide.util.actions.SystemAction; |
24 |
import org.openide.util.actions.SystemAction; |
23 |
import org.openide.windows.CloneableOpenSupport; |
25 |
import org.openide.windows.CloneableOpenSupport; |
24 |
import org.openide.windows.CloneableTopComponent; |
26 |
import org.openide.windows.CloneableTopComponent; |
Lines 29-35
Link Here
|
29 |
|
31 |
|
30 |
import java.awt.BorderLayout; |
32 |
import java.awt.BorderLayout; |
31 |
import java.awt.Component; |
33 |
import java.awt.Component; |
|
|
34 |
import java.awt.Container; |
32 |
import java.awt.Dimension; |
35 |
import java.awt.Dimension; |
|
|
36 |
import java.awt.Insets; |
33 |
import java.awt.Rectangle; |
37 |
import java.awt.Rectangle; |
34 |
|
38 |
|
35 |
import java.io.IOException; |
39 |
import java.io.IOException; |
Lines 37-44
Link Here
|
37 |
import java.io.ObjectInput; |
41 |
import java.io.ObjectInput; |
38 |
import java.io.ObjectOutput; |
42 |
import java.io.ObjectOutput; |
39 |
import java.io.ObjectStreamException; |
43 |
import java.io.ObjectStreamException; |
|
|
44 |
import java.util.Arrays; |
45 |
import java.util.Collections; |
46 |
import java.util.HashSet; |
47 |
import java.util.Iterator; |
48 |
import java.util.Set; |
40 |
|
49 |
|
41 |
import javax.swing.Action; |
50 |
import javax.swing.Action; |
|
|
51 |
import javax.swing.BoundedRangeModel; |
42 |
import javax.swing.JEditorPane; |
52 |
import javax.swing.JEditorPane; |
43 |
import javax.swing.JScrollPane; |
53 |
import javax.swing.JScrollPane; |
44 |
import javax.swing.JToolBar; |
54 |
import javax.swing.JToolBar; |
Lines 50-56
Link Here
|
50 |
import javax.swing.text.Document; |
60 |
import javax.swing.text.Document; |
51 |
import javax.swing.text.EditorKit; |
61 |
import javax.swing.text.EditorKit; |
52 |
|
62 |
|
53 |
|
|
|
54 |
/** Cloneable top component to hold the editor kit. |
63 |
/** Cloneable top component to hold the editor kit. |
55 |
*/ |
64 |
*/ |
56 |
public class CloneableEditor extends CloneableTopComponent implements CloneableEditorSupport.Pane { |
65 |
public class CloneableEditor extends CloneableTopComponent implements CloneableEditorSupport.Pane { |
Lines 162-167
Link Here
|
162 |
super.componentShowing(); |
171 |
super.componentShowing(); |
163 |
initialize(); |
172 |
initialize(); |
164 |
} |
173 |
} |
|
|
174 |
|
175 |
private static final int PANE_COUNT = 2; |
176 |
QuietEditorPane[] panes = new QuietEditorPane[PANE_COUNT]; |
177 |
Component[] comps = new Component[PANE_COUNT]; |
165 |
|
178 |
|
166 |
/** Performs needed initialization */ |
179 |
/** Performs needed initialization */ |
167 |
private void initialize() { |
180 |
private void initialize() { |
Lines 179-268
Link Here
|
179 |
Document doc = support.getDocument(); |
192 |
Document doc = support.getDocument(); |
180 |
|
193 |
|
181 |
setLayout(new BorderLayout()); |
194 |
setLayout(new BorderLayout()); |
|
|
195 |
|
196 |
JScrollPane[] scrolls = new JScrollPane[PANE_COUNT]; |
197 |
|
198 |
for (int i=0; i < PANE_COUNT; i++) { |
182 |
|
199 |
|
183 |
final QuietEditorPane pane = new QuietEditorPane(); |
200 |
final QuietEditorPane pane = new QuietEditorPane(); |
184 |
|
201 |
panes[i] = pane; |
185 |
pane.getAccessibleContext().setAccessibleName( |
|
|
186 |
NbBundle.getMessage(CloneableEditor.class, "ACS_CloneableEditor_QuietEditorPane", this.getName()) |
187 |
); |
188 |
pane.getAccessibleContext().setAccessibleDescription( |
189 |
NbBundle.getMessage( |
190 |
CloneableEditor.class, "ACSD_CloneableEditor_QuietEditorPane", |
191 |
this.getAccessibleContext().getAccessibleDescription() |
192 |
) |
193 |
); |
194 |
|
202 |
|
195 |
this.pane = pane; |
203 |
pane.getAccessibleContext().setAccessibleName( |
196 |
|
204 |
NbBundle.getMessage(CloneableEditor.class, "ACS_CloneableEditor_QuietEditorPane", this.getName()) |
197 |
// Init action map: cut,copy,delete,paste actions. |
205 |
); |
198 |
javax.swing.ActionMap am = getActionMap(); |
206 |
pane.getAccessibleContext().setAccessibleDescription( |
|
|
207 |
NbBundle.getMessage( |
208 |
CloneableEditor.class, "ACSD_CloneableEditor_QuietEditorPane", |
209 |
this.getAccessibleContext().getAccessibleDescription() |
210 |
) |
211 |
); |
199 |
|
212 |
|
200 |
//#43157 - editor actions need to be accessible from outside using the TopComponent.getLookup(ActionMap.class) call. |
213 |
this.pane = pane; |
201 |
// used in main menu enabling/disabling logic. |
|
|
202 |
javax.swing.ActionMap paneMap = pane.getActionMap(); |
203 |
am.setParent(paneMap); |
204 |
|
214 |
|
205 |
//#41223 set the defaults befor the custom editor + kit get initialized, giving them opportunity to |
215 |
// Init action map: cut,copy,delete,paste actions. |
206 |
// override defaults.. |
216 |
javax.swing.ActionMap am = getActionMap(); |
207 |
paneMap.put(DefaultEditorKit.cutAction, getAction(DefaultEditorKit.cutAction)); |
|
|
208 |
paneMap.put(DefaultEditorKit.copyAction, getAction(DefaultEditorKit.copyAction)); |
209 |
paneMap.put("delete", getAction(DefaultEditorKit.deleteNextCharAction)); // NOI18N |
210 |
paneMap.put(DefaultEditorKit.pasteAction, getAction(DefaultEditorKit.pasteAction)); |
211 |
|
217 |
|
212 |
pane.setEditorKit(support.cesKit()); |
218 |
//#43157 - editor actions need to be accessible from outside using the TopComponent.getLookup(ActionMap.class) call. |
|
|
219 |
// used in main menu enabling/disabling logic. |
220 |
javax.swing.ActionMap paneMap = pane.getActionMap(); |
221 |
am.setParent(paneMap); |
222 |
|
223 |
//#41223 set the defaults befor the custom editor + kit get initialized, giving them opportunity to |
224 |
// override defaults.. |
225 |
paneMap.put(DefaultEditorKit.cutAction, getAction(DefaultEditorKit.cutAction)); |
226 |
paneMap.put(DefaultEditorKit.copyAction, getAction(DefaultEditorKit.copyAction)); |
227 |
paneMap.put("delete", getAction(DefaultEditorKit.deleteNextCharAction)); // NOI18N |
228 |
paneMap.put(DefaultEditorKit.pasteAction, getAction(DefaultEditorKit.pasteAction)); |
229 |
|
230 |
pane.setEditorKit(support.cesKit()); |
231 |
|
232 |
pane.setDocument(doc); |
233 |
|
234 |
if (doc instanceof NbDocument.CustomEditor) { |
235 |
NbDocument.CustomEditor ce = (NbDocument.CustomEditor) doc; |
236 |
customComponent = ce.createEditor(pane); |
237 |
|
238 |
if (customComponent == null) { |
239 |
throw new IllegalStateException( |
240 |
"Document:" + doc // NOI18N |
241 |
+" implementing NbDocument.CustomEditor may not" // NOI18N |
242 |
+" return null component" |
243 |
); // NOI18N |
244 |
} |
213 |
|
245 |
|
214 |
pane.setDocument(doc); |
246 |
comps[i] = support.wrapEditorComponent(customComponent); |
|
|
247 |
add(comps[i], i == 0 ? BorderLayout.EAST : BorderLayout.WEST); |
248 |
} else { // not custom editor |
249 |
|
250 |
// remove default JScrollPane border, borders are provided by window system |
251 |
JScrollPane noBorderPane = new JScrollPane(pane); |
252 |
pane.setBorder(null); |
253 |
comps[i] = support.wrapEditorComponent(noBorderPane); |
254 |
add(comps[i], i == 0 ? BorderLayout.EAST : BorderLayout.WEST); |
255 |
} |
215 |
|
256 |
|
216 |
if (doc instanceof NbDocument.CustomEditor) { |
257 |
if (doc instanceof NbDocument.CustomToolbar && customToolbar != null) { |
217 |
NbDocument.CustomEditor ce = (NbDocument.CustomEditor) doc; |
258 |
NbDocument.CustomToolbar ce = (NbDocument.CustomToolbar) doc; |
218 |
customComponent = ce.createEditor(pane); |
259 |
customToolbar = ce.createToolbar(pane); |
|
|
260 |
|
261 |
if (customToolbar == null) { |
262 |
throw new IllegalStateException( |
263 |
"Document:" + doc // NOI18N |
264 |
+" implementing NbDocument.CustomToolbar may not" // NOI18N |
265 |
+" return null toolbar" |
266 |
); // NOI18N |
267 |
} |
219 |
|
268 |
|
220 |
if (customComponent == null) { |
269 |
Border b = (Border) UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N |
221 |
throw new IllegalStateException( |
270 |
customToolbar.setBorder(b); |
222 |
"Document:" + doc // NOI18N |
271 |
add(customToolbar, BorderLayout.NORTH); |
223 |
+" implementing NbDocument.CustomEditor may not" // NOI18N |
|
|
224 |
+" return null component" |
225 |
); // NOI18N |
226 |
} |
272 |
} |
227 |
|
273 |
|
228 |
add(support.wrapEditorComponent(customComponent), BorderLayout.CENTER); |
274 |
pane.setWorking(QuietEditorPane.ALL); |
229 |
} else { // not custom editor |
|
|
230 |
|
231 |
// remove default JScrollPane border, borders are provided by window system |
232 |
JScrollPane noBorderPane = new JScrollPane(pane); |
233 |
pane.setBorder(null); |
234 |
add(support.wrapEditorComponent(noBorderPane), BorderLayout.CENTER); |
235 |
} |
236 |
|
275 |
|
237 |
if (doc instanceof NbDocument.CustomToolbar) { |
276 |
// set the caret to right possition if this component was deserialized |
238 |
NbDocument.CustomToolbar ce = (NbDocument.CustomToolbar) doc; |
277 |
if (cursorPosition != -1) { |
239 |
customToolbar = ce.createToolbar(pane); |
278 |
Caret caret = pane.getCaret(); |
240 |
|
279 |
|
241 |
if (customToolbar == null) { |
280 |
if (caret != null) { |
242 |
throw new IllegalStateException( |
281 |
caret.setDot(cursorPosition); |
243 |
"Document:" + doc // NOI18N |
282 |
} |
244 |
+" implementing NbDocument.CustomToolbar may not" // NOI18N |
|
|
245 |
+" return null toolbar" |
246 |
); // NOI18N |
247 |
} |
283 |
} |
248 |
|
|
|
249 |
Border b = (Border) UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N |
250 |
customToolbar.setBorder(b); |
251 |
add(customToolbar, BorderLayout.NORTH); |
252 |
} |
284 |
} |
253 |
|
285 |
this.pane = panes[0]; |
254 |
pane.setWorking(QuietEditorPane.ALL); |
286 |
support.ensureAnnotationsLoaded(); |
255 |
|
287 |
} |
256 |
// set the caret to right possition if this component was deserialized |
288 |
|
257 |
if (cursorPosition != -1) { |
289 |
public void addNotify() { |
258 |
Caret caret = pane.getCaret(); |
290 |
super.addNotify(); |
259 |
|
291 |
if (!attached) { |
260 |
if (caret != null) { |
292 |
SwingUtilities.invokeLater(new R()); |
261 |
caret.setDot(cursorPosition); |
293 |
} |
|
|
294 |
} |
295 |
|
296 |
private class R implements Runnable { |
297 |
public void run() { |
298 |
JScrollPane[] p = new JScrollPane[panes.length]; |
299 |
for (int i=0; i < panes.length; i++) { |
300 |
if (panes[i] != null) { |
301 |
JScrollPane pane = (JScrollPane) |
302 |
SwingUtilities.getAncestorOfClass(JScrollPane.class, panes[i]); |
303 |
p[i] = pane; |
304 |
if (p[i] == null) { |
305 |
return; |
306 |
} |
307 |
} |
308 |
} |
309 |
new CA (p, false); |
310 |
new CA (p, true); |
311 |
} |
312 |
} |
313 |
|
314 |
private boolean attached = false; |
315 |
|
316 |
private class CA implements ChangeListener { |
317 |
JScrollPane[] p; |
318 |
BoundedRangeModel[] mdls; |
319 |
boolean vert; |
320 |
public CA (JScrollPane[] p, boolean vert) { |
321 |
this.vert = vert; |
322 |
this.p = p; |
323 |
for (int i=0; i < p.length; i++) { |
324 |
if (p[i] == null) { |
325 |
return; |
326 |
} |
327 |
} |
328 |
init(); |
329 |
attached = true; |
330 |
} |
331 |
|
332 |
private void init() { |
333 |
mdls = new BoundedRangeModel[p.length]; |
334 |
int val = 0; |
335 |
int ext = 0; |
336 |
for (int i=0; i < p.length; i++) { |
337 |
mdls[i] = vert ? p[i].getVerticalScrollBar().getModel() : |
338 |
p[i].getHorizontalScrollBar().getModel(); |
339 |
if (vert) { |
340 |
if (i == 0) { |
341 |
val = mdls[i].getValue(); |
342 |
ext = mdls[i].getExtent(); |
343 |
} else { |
344 |
val += ext; |
345 |
mdls[i].setValue(val); |
346 |
} |
347 |
} |
348 |
mdls[i].addChangeListener(this); |
262 |
} |
349 |
} |
263 |
} |
350 |
} |
264 |
|
351 |
|
265 |
support.ensureAnnotationsLoaded(); |
352 |
public void stateChanged(ChangeEvent e) { |
|
|
353 |
int idx = Arrays.asList(mdls).indexOf(e.getSource()); |
354 |
for (int i=0; i < mdls.length; i++) { |
355 |
if (i != idx) { |
356 |
int val = mdls[idx].getValue(); |
357 |
if (vert) { |
358 |
mdls[i].setValue(val + (mdls[idx].getExtent() * (i - idx))); |
359 |
} else { |
360 |
mdls[i].setValue(val); |
361 |
} |
362 |
} |
363 |
} |
364 |
} |
365 |
} |
366 |
|
367 |
|
368 |
public void doLayout() { |
369 |
if (PANE_COUNT != 1) { |
370 |
Component[] c = getComponents(); |
371 |
Component tb = null; |
372 |
Dimension tbDim = customToolbar == null ? new Dimension (0,0) : |
373 |
customToolbar.getPreferredSize(); |
374 |
Insets ins = getInsets(); |
375 |
int left = ins.left; |
376 |
int x = left; |
377 |
int top = ins.top + tbDim.height; |
378 |
int height = getHeight() - (top + ins.bottom); |
379 |
int w = (getWidth() - ins.left + ins.right) / PANE_COUNT; |
380 |
for (int i=0; i < PANE_COUNT; i++) { |
381 |
if (comps[i] != null) { |
382 |
comps[i].setBounds(x, top, w, height); |
383 |
} |
384 |
x += w; |
385 |
} |
386 |
if (customToolbar != null) { |
387 |
customToolbar.setBounds (ins.top, ins.left, tbDim.width, tbDim.height); |
388 |
} |
389 |
} else { |
390 |
super.doLayout(); |
391 |
} |
266 |
} |
392 |
} |
267 |
|
393 |
|
268 |
protected CloneableTopComponent createClonedObject() { |
394 |
protected CloneableTopComponent createClonedObject() { |
Lines 441-446
Link Here
|
441 |
* @see #componentDeactivated */ |
567 |
* @see #componentDeactivated */ |
442 |
protected void componentActivated() { |
568 |
protected void componentActivated() { |
443 |
support.setLastSelected(this); |
569 |
support.setLastSelected(this); |
|
|
570 |
if (!attached) { |
571 |
System.err.println("DOING IT"); |
572 |
SwingUtilities.invokeLater(new R()); |
573 |
} |
444 |
} |
574 |
} |
445 |
|
575 |
|
446 |
/** Updates the name and tooltip of this <code>CloneableEditor</code> |
576 |
/** Updates the name and tooltip of this <code>CloneableEditor</code> |