Révision 2050
tmp/org.txm.chartsengine.rcp/src/org/txm/chartsengine/rcp/swt/SwingChartComposite.java (revision 2050) | ||
---|---|---|
42 | 42 |
|
43 | 43 |
/** |
44 | 44 |
* Base chart composite with Swing/AWT support. |
45 |
* This composite uses the SWT/AWT bridge to add some Swing/AWT chart component.
|
|
45 |
* This composite uses the SWT_AWT bridge to add some Swing/AWT chart components through an AWT Frame.
|
|
46 | 46 |
* |
47 | 47 |
* @author sjacquot |
48 | 48 |
* |
49 | 49 |
*/ |
50 |
// FIXME: SJ: this class contains a lot of tests to fix the SWT/AWT focus bugs and need a full clean up |
|
50 | 51 |
public abstract class SwingChartComposite extends ChartComposite { |
51 | 52 |
|
52 | 53 |
|
... | ... | |
100 | 101 |
// stops the conflict between AWT and SWT events that freezes the SWT Spinner, TextFields, etc. |
101 | 102 |
// (Progression query, Specificities chart banality, etc.) |
102 | 103 |
// see: http://forge.cbp.ens-lyon.fr/redmine/issues/2548 |
103 |
if(OSDetector.isFamilyUnix() |
|
104 |
//&& (chartEditor.getClass().getName().equals("org.txm.progression.rcp.editors.ProgressionEditor") //$NON-NLS-1$ |
|
105 |
// || chartEditor.getClass().getName().equals("org.txm.specificities.rcp.editors.SpecificitiesSelectionEditor") //$NON-NLS-1$ |
|
106 |
// || chartEditor.getClass().getName().equals("org.txm.ca.rcp.editors.CAFactorialMapChartEditor") //$NON-NLS-1$ |
|
107 |
// ) |
|
108 |
) { |
|
109 |
// Log.finest("SwingChartComposite.SwingChartComposite(): Temporary Linux bug workaround: AWT focusable window state set to false."); |
|
110 |
//this.frame.setFocusableWindowState(false); |
|
111 |
this.frame.setAutoRequestFocus(false); |
|
104 |
if(OSDetector.isFamilyUnix()) { |
|
105 |
this.frame.setAutoRequestFocus(false); |
|
112 | 106 |
} |
113 | 107 |
|
114 | 108 |
|
... | ... | |
117 | 111 |
this.rootPanel.setBackground(Color.WHITE); |
118 | 112 |
this.rootPanel.setBorder(new LineBorder(Color.WHITE, 1)); |
119 | 113 |
|
114 |
|
|
115 |
// Change the border of the root panel to show to user the chart is focused |
|
116 |
this.frame.addWindowFocusListener(new WindowFocusListener() { |
|
117 |
|
|
118 |
@Override |
|
119 |
public void windowLostFocus(WindowEvent e) { |
|
120 |
((JComponent) rootPanel).setBorder(new LineBorder(Color.WHITE, 1)); |
|
121 |
} |
|
122 |
|
|
123 |
@Override |
|
124 |
public void windowGainedFocus(WindowEvent e) { |
|
125 |
((JComponent) rootPanel).setBorder(new LineBorder(Color.GRAY, 1)); |
|
126 |
|
|
127 |
// FIXME: SJ: SWT/AWT focus bugs thread tests, need to wait to see how SWT/AWT bugs will be fixed before removing this |
|
128 |
// getDisplay().asyncExec(new Runnable() { |
|
129 |
// @Override |
|
130 |
// public void run() { |
|
131 |
// |
|
132 |
// //SwingChartComposite.this.notifyListeners(SWT.MouseDown, SWTChartsComponentsProvider.swingEventToSWT(chartEditor.getComposite(), swingComponent, e, SWT.MouseDown)); |
|
133 |
// |
|
134 |
// // FIXME: Debug |
|
135 |
//// System.out.println("SWTChartsComponentProvider.initializeAWTDelegationListeners(...).new MouseListener() {...}.mousePressed(...).new Runnable() {...}.run()"); |
|
136 |
// // Activate the editor part on AWT mouse pressed event |
|
137 |
// //SwingChartComposite.this.chartEditor.activate(); |
|
138 |
// //chartEditor.getShell().setFocus(); |
|
139 |
//// chartEditor.setFocus(); |
|
140 |
// //chartEditor.getParent().setFocus(); |
|
141 |
//// chartEditor.forceFocus(); |
|
142 |
// SwingChartComposite.this.chartEditor.setFocus(); |
|
143 |
// //notifyListeners(SWT.FocusIn, null); // Needed to force the composite listener to handle the focus event |
|
144 |
// } |
|
145 |
// }); |
|
146 |
// |
|
147 |
|
|
148 |
|
|
149 |
} |
|
150 |
}); |
|
151 |
|
|
152 |
|
|
120 | 153 |
// FIXME: SJ: temporary workaround to Linux focus bugs |
121 | 154 |
// part #1: release the focus at mouse exited on the rootPanel, needed for empty charts, eg. Progression |
122 | 155 |
// it breaks all the key events in charts (zoom, pan, selection, etc.) but |
... | ... | |
177 | 210 |
}); |
178 | 211 |
} |
179 | 212 |
|
180 |
// SJ: Workaround to fix a bug with some Java version and some OS where the focus of an embedded Swing component does not delegate to SWT, eg. the Part is not activated. |
|
181 |
// After some tests, doesn't seem to work on Linux and Mac |
|
182 |
// see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=377104 |
|
183 |
// see: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8203855 |
|
184 |
// this.frame.addWindowListener(new java.awt.event.WindowAdapter() { |
|
185 |
// @Override |
|
186 |
// public void windowActivated(java.awt.event.WindowEvent e) { |
|
187 |
// SwingChartComposite.this.getDisplay().asyncExec(new Runnable() { |
|
188 |
// @Override |
|
189 |
// public void run() { |
|
190 |
// if (Display.getCurrent().getFocusControl() == SwingChartComposite.this) { |
|
191 |
// Stack<Control> stack = new Stack<Control>(); |
|
192 |
// Control starter = SwingChartComposite.this; |
|
193 |
// Shell shell = SwingChartComposite.this.getShell(); |
|
194 |
// while (starter != null && !(starter instanceof Shell)) { |
|
195 |
// stack.push(starter.getParent()); |
|
196 |
// starter = starter.getParent(); |
|
197 |
// } |
|
198 |
// |
|
199 |
// Method m = null; |
|
200 |
// try { |
|
201 |
// // instead of calling the originally proposed |
|
202 |
// // workaround solution (below), |
|
203 |
// // |
|
204 |
// // Event event = new Event(); |
|
205 |
// // event.display = Display.getCurrent(); |
|
206 |
// // event.type = SWT.Activate; |
|
207 |
// // event.widget = stack.pop(); |
|
208 |
// // event.widget.notifyListeners(SWT.Activate, event); |
|
209 |
// // |
|
210 |
// // which should but does NOT set the active |
|
211 |
// // widget/control on the shell, we had |
|
212 |
// // to call the setActiveControl method directly. |
|
213 |
// // Updating the active control on the shell is |
|
214 |
// // important so that the last active |
|
215 |
// // control, when selected again, get the proper |
|
216 |
// // activation events fired. |
|
217 |
// |
|
218 |
// m = shell.getClass().getDeclaredMethod("setActiveControl", Control.class);// $NON-NLS-1$ |
|
219 |
// m.setAccessible(true); |
|
220 |
// while (!stack.isEmpty()) { |
|
221 |
// m.invoke(shell, stack.pop()); |
|
222 |
// } |
|
223 |
// |
|
224 |
// // force the Swing component focus |
|
225 |
// //setFocus(); |
|
226 |
// |
|
227 |
// } |
|
228 |
// catch (Exception e) { |
|
229 |
// Log.severe("** Embedded part was not able to set active control on Shell. This will result in other workbench parts not getting activated."); //$NON-NLS-1$ |
|
230 |
// Log.printStackTrace(e); |
|
231 |
// } |
|
232 |
// finally { |
|
233 |
// if (m != null) { |
|
234 |
// m.setAccessible(false); |
|
235 |
// } |
|
236 |
// } |
|
237 |
// } |
|
238 |
// } |
|
239 |
// }); |
|
240 |
// } |
|
241 |
// }); |
|
242 | 213 |
|
243 |
this.frame.addWindowListener(new WindowListener() { |
|
244 |
|
|
245 |
@Override |
|
246 |
public void windowOpened(WindowEvent e) { |
|
247 |
// TODO Auto-generated method stub |
|
248 |
|
|
249 |
} |
|
250 |
|
|
251 |
@Override |
|
252 |
public void windowIconified(WindowEvent e) { |
|
253 |
// TODO Auto-generated method stub |
|
254 |
|
|
255 |
} |
|
256 |
|
|
257 |
@Override |
|
258 |
public void windowDeiconified(WindowEvent e) { |
|
259 |
// TODO Auto-generated method stub |
|
260 |
|
|
261 |
} |
|
262 |
|
|
263 |
@Override |
|
264 |
public void windowDeactivated(WindowEvent e) { |
|
265 |
// TODO Auto-generated method stub |
|
266 |
Log.finest("SwingChartComposite.SwingChartComposite(...).new WindowListener() {...}.windowDeactivated()"); |
|
267 |
} |
|
268 |
|
|
269 |
@Override |
|
270 |
public void windowClosing(WindowEvent e) { |
|
271 |
// TODO Auto-generated method stub |
|
272 |
|
|
273 |
} |
|
274 |
|
|
275 |
@Override |
|
276 |
public void windowClosed(WindowEvent e) { |
|
277 |
// TODO Auto-generated method stub |
|
278 |
|
|
279 |
} |
|
280 |
|
|
281 |
@Override |
|
282 |
public void windowActivated(WindowEvent e) { |
|
283 |
// TODO Auto-generated method stub |
|
284 |
Log.finest("SwingChartComposite.SwingChartComposite(...).new WindowListener() {...}.windowActivated()"); |
|
285 |
} |
|
286 |
}); |
|
287 |
|
|
288 |
|
|
289 |
|
|
290 |
// FIXME: For Swing focus debug tests |
|
291 |
this.frame.addWindowFocusListener(new WindowFocusListener() { |
|
292 |
|
|
293 |
@Override |
|
294 |
public void windowLostFocus(WindowEvent e) { |
|
295 |
// TODO Auto-generated method stub |
|
296 |
Log.finest("SwingChartComposite.SwingChartComposite(...).new WindowFocusListener() {...}.windowLostFocus()"); |
|
297 |
|
|
298 |
// FIXME: For Swing focus debug tests |
|
299 |
//if(RCPPreferences.getInstance().getBoolean(TBXPreferences.EXPERT_USER)) { |
|
300 |
((JComponent) rootPanel).setBorder(new LineBorder(Color.WHITE, 1)); |
|
301 |
//((JComponent) rootPanel).setBorder(javax.swing.BorderFactory.createEmptyBorder()); |
|
302 |
//} |
|
303 |
|
|
304 |
|
|
305 |
} |
|
306 |
|
|
307 |
@Override |
|
308 |
public void windowGainedFocus(WindowEvent e) { |
|
309 |
// TODO Auto-generated method stub |
|
310 |
Log.finest("SwingChartComposite.SwingChartComposite(...).new WindowFocusListener() {...}.windowGainedFocus()"); |
|
311 |
|
|
312 |
// FIXME: For Swing focus debug tests |
|
313 |
//if(RCPPreferences.getInstance().getBoolean(TBXPreferences.EXPERT_USER)) { |
|
314 |
((JComponent) rootPanel).setBorder(new LineBorder(Color.GRAY, 1)); |
|
315 |
//} |
|
316 |
|
|
317 |
// // SWT thread |
|
318 |
// getDisplay().asyncExec(new Runnable() { |
|
319 |
// @Override |
|
320 |
// public void run() { |
|
321 |
// |
|
322 |
// //SwingChartComposite.this.notifyListeners(SWT.MouseDown, SWTChartsComponentsProvider.swingEventToSWT(chartEditor.getComposite(), swingComponent, e, SWT.MouseDown)); |
|
323 |
// |
|
324 |
// // FIXME: Debug |
|
325 |
//// System.out.println("SWTChartsComponentProvider.initializeAWTDelegationListeners(...).new MouseListener() {...}.mousePressed(...).new Runnable() {...}.run()"); |
|
326 |
// // Activate the editor part on AWT mouse pressed event |
|
327 |
// //SwingChartComposite.this.chartEditor.activate(); |
|
328 |
// //chartEditor.getShell().setFocus(); |
|
329 |
//// chartEditor.setFocus(); |
|
330 |
// //chartEditor.getParent().setFocus(); |
|
331 |
//// chartEditor.forceFocus(); |
|
332 |
// SwingChartComposite.this.chartEditor.setFocus(); |
|
333 |
// //notifyListeners(SWT.FocusIn, null); // Needed to force the composite listener to handle the focus event |
|
334 |
// } |
|
335 |
// }); |
|
336 |
// |
|
337 |
|
|
338 |
|
|
339 |
} |
|
340 |
}); |
|
341 |
|
|
342 |
|
|
343 |
|
|
344 |
this.frame.addFocusListener(new FocusListener() { |
|
345 |
|
|
346 |
@Override |
|
347 |
public void focusLost(FocusEvent e) { |
|
348 |
// TODO Auto-generated method stub |
|
349 |
Log.finest("SwingChartComposite.SwingChartComposite(...).new FocusListener() {...}.focusLost()"); |
|
350 |
} |
|
351 |
|
|
352 |
@Override |
|
353 |
public void focusGained(FocusEvent e) { |
|
354 |
// TODO Auto-generated method stub |
|
355 |
Log.finest("SwingChartComposite.SwingChartComposite(...).new FocusListener() {...}.focusGained()"); |
|
356 |
} |
|
357 |
}); |
|
358 |
|
|
359 |
|
|
360 |
// this.frame.addWindowFocusListener(new WindowFocusListener() { |
|
361 |
// |
|
362 |
// @Override |
|
363 |
// public void windowLostFocus(WindowEvent e) { |
|
364 |
// // TODO Auto-generated method stub |
|
365 |
// Log.finest("SwingChartComposite.SwingChartComposite(...).new WindowFocusListener() {...}.windowLostFocus()"); |
|
366 |
// |
|
367 |
// // Force the keep the focus if the ChartEditor has the focus |
|
368 |
// if(!SwingChartComposite.this.isDisposed()) { |
|
369 |
// SwingChartComposite.this.getDisplay().asyncExec(new Runnable() { |
|
370 |
// @Override |
|
371 |
// public void run() { |
|
372 |
// if (Display.getCurrent().getFocusControl() == SwingChartComposite.this) { |
|
373 |
// Log.finest("SwingChartComposite.SwingChartComposite(...).new WindowFocusListener() {...}.windowLostFocus(): force focus in chart component."); |
|
374 |
// requestFocusInChartComponent(); |
|
375 |
// } |
|
376 |
// } |
|
377 |
// }); |
|
378 |
// } |
|
379 |
// |
|
380 |
// |
|
381 |
// |
|
382 |
// // FIXME: For Swing focus debug tests |
|
383 |
// if(RCPPreferences.getInstance().getBoolean(TBXPreferences.EXPERT_USER)) { |
|
384 |
// ((JComponent) rootPanel).setBorder(javax.swing.BorderFactory.createEmptyBorder()); |
|
385 |
// } |
|
386 |
// |
|
387 |
// |
|
388 |
// } |
|
389 |
// |
|
390 |
// @Override |
|
391 |
// public void windowGainedFocus(WindowEvent e) { |
|
392 |
// |
|
393 |
// // FIXME: For Swing focus debug tests |
|
394 |
// if(RCPPreferences.getInstance().getBoolean(TBXPreferences.EXPERT_USER)) { |
|
395 |
// ((JComponent) rootPanel).setBorder(new LineBorder(Color.red, 1)); |
|
396 |
// } |
|
397 |
// |
|
398 |
// |
|
399 |
// // TODO Auto-generated method stub |
|
400 |
// Log.finest("SwingChartComposite.SwingChartComposite(...).new WindowFocusListener() {...}.windowGainedFocus()"); |
|
401 |
// |
|
402 |
// |
|
403 |
// SwingChartComposite.this.getDisplay().asyncExec(new Runnable() { |
|
404 |
// @Override |
|
405 |
// public void run() { |
|
406 |
// if ( |
|
407 |
// Display.getCurrent().getFocusControl() == SwingChartComposite.this |
|
408 |
// //&& |
|
409 |
// //SwingChartComposite.this.chartEditor.getContextActivationToken() == null |
|
410 |
//// SwingChartComposite.this.chartEditor != PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor() |
|
411 |
// ) { |
|
412 |
// |
|
413 |
// Log.finest("SwingChartComposite.SwingChartComposite(...).new WindowFocusListener() {...}.windowGainedFocus(): activate the EditorPart."); |
|
414 |
// |
|
415 |
// Stack<Control> stack = new Stack<Control>(); |
|
416 |
// Control starter = SwingChartComposite.this; |
|
417 |
// Shell shell = SwingChartComposite.this.getShell(); |
|
418 |
// while (starter != null && !(starter instanceof Shell)) { |
|
419 |
// stack.push(starter.getParent()); |
|
420 |
// starter = starter.getParent(); |
|
421 |
// } |
|
422 |
// |
|
423 |
// Method m = null; |
|
424 |
// try { |
|
425 |
// // instead of calling the originally proposed |
|
426 |
// // workaround solution (below), |
|
427 |
// // |
|
428 |
//// Event event = new Event(); |
|
429 |
//// event.display = Display.getCurrent(); |
|
430 |
//// event.type = SWT.Activate; |
|
431 |
//// event.widget = stack.pop(); |
|
432 |
//// event.widget.notifyListeners(SWT.Activate, event); |
|
433 |
// // |
|
434 |
// // which should but does NOT set the active |
|
435 |
// // widget/control on the shell, we had |
|
436 |
// // to call the setActiveControl method directly. |
|
437 |
// // Updating the active control on the shell is |
|
438 |
// // important so that the last active |
|
439 |
// // control, when selected again, get the proper |
|
440 |
// // activation events fired. |
|
441 |
// |
|
442 |
// //PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().activate(SwingChartComposite.this.chartEditor); |
|
443 |
// |
|
444 |
// m = shell.getClass().getDeclaredMethod("setActiveControl", Control.class);// $NON-NLS-1$ |
|
445 |
// m.setAccessible(true); |
|
446 |
// while (!stack.isEmpty()) { |
|
447 |
// m.invoke(shell, stack.pop()); |
|
448 |
// } |
|
449 |
// |
|
450 |
// // force the Swing component focus |
|
451 |
// //setFocus(); |
|
452 |
// |
|
453 |
// } |
|
454 |
// catch (Exception e) { |
|
455 |
// Log.severe("** Embedded part was not able to set active control on Shell. This will result in other workbench parts not getting activated."); //$NON-NLS-1$ |
|
456 |
// Log.printStackTrace(e); |
|
457 |
// } |
|
458 |
// finally { |
|
459 |
// if (m != null) { |
|
460 |
// m.setAccessible(false); |
|
461 |
// } |
|
462 |
// } |
|
463 |
// } |
|
464 |
// } |
|
465 |
// }); |
|
466 |
// |
|
467 |
// } |
|
468 |
// }); |
|
469 |
|
|
470 |
|
|
471 |
|
|
472 | 214 |
} |
473 | 215 |
|
474 | 216 |
|
... | ... | |
787 | 529 |
} |
788 | 530 |
}); |
789 | 531 |
|
532 |
|
|
533 |
// internal method to help tracking the focus events of frame and components to fix SWT/AWT bridge focus bugs |
|
534 |
// this.debug_initSWTAWTBridgeFocusBugsTests(); |
|
535 |
|
|
536 |
|
|
537 |
|
|
538 |
|
|
539 |
|
|
540 |
} |
|
541 |
|
|
542 |
|
|
543 |
// FIXME: SJ: some code here should be moved to the parent class ChartComposite |
|
544 |
@Override |
|
545 |
public void loadChart() { |
|
546 |
|
|
547 |
// loads the chart from the result |
|
548 |
Object chart = this.chartEditor.getChart(); |
|
549 |
|
|
550 |
if(chart != null) { |
|
551 |
|
|
552 |
// creates components if they not exist |
|
553 |
if(this.chartComponent == null) { |
|
554 |
|
|
555 |
// recreates the chart if not of right type |
|
556 |
if(this.chartEditor.getResult().isChartDirty()) { |
|
557 |
try { |
|
558 |
this.chartEditor.getResult().clearLastRenderingParameters(); |
|
559 |
this.chartEditor.getResult().compute(); |
|
560 |
} |
|
561 |
catch (Exception e) { |
|
562 |
e.printStackTrace(); |
|
563 |
} |
|
564 |
} |
|
565 |
|
|
566 |
this.createChartComponent(); |
|
567 |
|
|
568 |
this.rootPanel.add((Component) this.chartComponent); |
|
569 |
|
|
570 |
this.frame.setVisible(true); |
|
571 |
} |
|
572 |
this.loadChart(this.chartEditor.getChart()); |
|
573 |
} |
|
574 |
} |
|
575 |
|
|
576 |
|
|
577 |
|
|
578 |
|
|
579 |
|
|
580 |
@Override |
|
581 |
public void copyChartViewToClipboard() { |
|
582 |
|
|
583 |
int w = ((Component) this.chartComponent).getWidth(); |
|
584 |
int h = ((Component) this.chartComponent).getHeight(); |
|
585 |
final BufferedImage bufferedImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); |
|
586 |
Graphics2D g = bufferedImg.createGraphics(); |
|
587 |
|
|
588 |
|
|
589 |
((Component) this.chartComponent).paint(g); |
|
590 |
|
|
591 |
Transferable img = new Transferable() { |
|
592 |
|
|
593 |
@Override |
|
594 |
public boolean isDataFlavorSupported(DataFlavor flavor) { |
|
595 |
return DataFlavor.imageFlavor.equals(flavor); |
|
596 |
} |
|
597 |
|
|
598 |
@Override |
|
599 |
public DataFlavor[] getTransferDataFlavors() { |
|
600 |
return new DataFlavor[] {DataFlavor.imageFlavor}; |
|
601 |
} |
|
602 |
|
|
603 |
@Override |
|
604 |
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { |
|
605 |
if(!DataFlavor.imageFlavor.equals(flavor)) { |
|
606 |
throw new UnsupportedFlavorException(flavor); |
|
607 |
} |
|
608 |
return bufferedImg; |
|
609 |
} |
|
610 |
|
|
611 |
}; |
|
612 |
|
|
613 |
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(img, null); |
|
614 |
|
|
615 |
} |
|
616 |
|
|
617 |
|
|
618 |
|
|
619 |
@Override |
|
620 |
public EventCallBackHandler getMouseCallBackHandler() { |
|
621 |
return super.getMouseCallBackHandler((Component) this.chartComponent); |
|
622 |
} |
|
623 |
|
|
624 |
|
|
625 |
@Override |
|
626 |
public EventCallBackHandler getKeyCallBackHandler() { |
|
627 |
return super.getKeyCallBackHandler((Component) this.chartComponent); |
|
628 |
} |
|
629 |
|
|
630 |
|
|
631 |
/** |
|
632 |
* Converts an AWT event to SWT event. Also stores the Swing tool tip source text of the specified Swing component in the SWT event to give it to the SWT composite listener in <code>ChartComposite</code>. |
|
633 |
* @param swtComposite |
|
634 |
* @param swingComponent |
|
635 |
* @param e |
|
636 |
* @param eventType |
|
637 |
* @return |
|
638 |
*/ |
|
639 |
// FIXME : SJ: this method is incomplete and not used ATM but may becomes useful later, need to wait to see how the SWT/AWT focus bugs will be fixed |
|
640 |
public static org.eclipse.swt.widgets.Event swingEventToSWT(Composite swtComposite, JComponent swingComponent, AWTEvent e, int eventType) { |
|
641 |
|
|
642 |
Event event = new Event(); |
|
643 |
if(!swtComposite.isDisposed()) { |
|
644 |
event.display = swtComposite.getDisplay(); |
|
645 |
} |
|
646 |
event.widget = swtComposite; |
|
647 |
event.type = eventType; |
|
648 |
|
|
649 |
if(e instanceof MouseEvent) { |
|
650 |
MouseEvent me = (MouseEvent) e; |
|
651 |
event.button = me.getButton(); |
|
652 |
try { |
|
653 |
// Store the Swing tool tip source text in the SWT event to give it to the SWT composite listener in ChartComposite |
|
654 |
// NOTE: this method call sometimes throws a java.lang.IndexOutOfBoundsException |
|
655 |
event.text = swingComponent.getToolTipText(me); |
|
656 |
} |
|
657 |
catch(Exception e1) { |
|
658 |
//e1.printStackTrace(); |
|
659 |
} |
|
660 |
event.x = me.getX(); |
|
661 |
event.y = me.getY(); |
|
662 |
} |
|
663 |
return event; |
|
664 |
} |
|
665 |
|
|
666 |
|
|
667 |
/** |
|
668 |
* Internal method to help tracking the focus events of frame and components to fix SWT/AWT bridge focus bugs. |
|
669 |
*/ |
|
670 |
// FIXME: SJ: please keep this method ATM |
|
671 |
protected void debug_initSWTAWTBridgeFocusBugsTests() { |
|
672 |
|
|
673 |
|
|
674 |
this.frame.addFocusListener(new FocusListener() { |
|
675 |
|
|
676 |
@Override |
|
677 |
public void focusLost(FocusEvent e) { |
|
678 |
// TODO Auto-generated method stub |
|
679 |
Log.finest("SwingChartComposite.SwingChartComposite(...).new FocusListener() {...}.focusLost()"); |
|
680 |
} |
|
681 |
|
|
682 |
@Override |
|
683 |
public void focusGained(FocusEvent e) { |
|
684 |
// TODO Auto-generated method stub |
|
685 |
Log.finest("SwingChartComposite.SwingChartComposite(...).new FocusListener() {...}.focusGained()"); |
|
686 |
} |
|
687 |
}); |
|
688 |
|
|
689 |
|
|
690 |
|
|
691 |
// SJ: Workaround to fix a bug with some Java version and some OS where the focus of an embedded Swing component does not delegate to SWT, eg. the Part is not activated. |
|
692 |
// After some tests, doesn't seem to work on Linux and Mac |
|
693 |
// see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=377104 |
|
694 |
// see: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8203855 |
|
695 |
// this.frame.addWindowListener(new java.awt.event.WindowAdapter() { |
|
696 |
// @Override |
|
697 |
// public void windowActivated(java.awt.event.WindowEvent e) { |
|
698 |
// SwingChartComposite.this.getDisplay().asyncExec(new Runnable() { |
|
699 |
// @Override |
|
700 |
// public void run() { |
|
701 |
// if (Display.getCurrent().getFocusControl() == SwingChartComposite.this) { |
|
702 |
// Stack<Control> stack = new Stack<Control>(); |
|
703 |
// Control starter = SwingChartComposite.this; |
|
704 |
// Shell shell = SwingChartComposite.this.getShell(); |
|
705 |
// while (starter != null && !(starter instanceof Shell)) { |
|
706 |
// stack.push(starter.getParent()); |
|
707 |
// starter = starter.getParent(); |
|
708 |
// } |
|
709 |
// |
|
710 |
// Method m = null; |
|
711 |
// try { |
|
712 |
// // instead of calling the originally proposed |
|
713 |
// // workaround solution (below), |
|
714 |
// // |
|
715 |
// // Event event = new Event(); |
|
716 |
// // event.display = Display.getCurrent(); |
|
717 |
// // event.type = SWT.Activate; |
|
718 |
// // event.widget = stack.pop(); |
|
719 |
// // event.widget.notifyListeners(SWT.Activate, event); |
|
720 |
// // |
|
721 |
// // which should but does NOT set the active |
|
722 |
// // widget/control on the shell, we had |
|
723 |
// // to call the setActiveControl method directly. |
|
724 |
// // Updating the active control on the shell is |
|
725 |
// // important so that the last active |
|
726 |
// // control, when selected again, get the proper |
|
727 |
// // activation events fired. |
|
728 |
// |
|
729 |
// m = shell.getClass().getDeclaredMethod("setActiveControl", Control.class);// $NON-NLS-1$ |
|
730 |
// m.setAccessible(true); |
|
731 |
// while (!stack.isEmpty()) { |
|
732 |
// m.invoke(shell, stack.pop()); |
|
733 |
// } |
|
734 |
// |
|
735 |
// // force the Swing component focus |
|
736 |
// //setFocus(); |
|
737 |
// |
|
738 |
// } |
|
739 |
// catch (Exception e) { |
|
740 |
// Log.severe("** Embedded part was not able to set active control on Shell. This will result in other workbench parts not getting activated."); //$NON-NLS-1$ |
|
741 |
// Log.printStackTrace(e); |
|
742 |
// } |
|
743 |
// finally { |
|
744 |
// if (m != null) { |
|
745 |
// m.setAccessible(false); |
|
746 |
// } |
|
747 |
// } |
|
748 |
// } |
|
749 |
// } |
|
750 |
// }); |
|
751 |
// } |
|
752 |
// }); |
|
753 |
|
|
754 |
this.frame.addWindowListener(new WindowListener() { |
|
755 |
|
|
756 |
@Override |
|
757 |
public void windowOpened(WindowEvent e) { |
|
758 |
// TODO Auto-generated method stub |
|
759 |
|
|
760 |
} |
|
761 |
|
|
762 |
@Override |
|
763 |
public void windowIconified(WindowEvent e) { |
|
764 |
// TODO Auto-generated method stub |
|
765 |
|
|
766 |
} |
|
767 |
|
|
768 |
@Override |
|
769 |
public void windowDeiconified(WindowEvent e) { |
|
770 |
// TODO Auto-generated method stub |
|
771 |
|
|
772 |
} |
|
773 |
|
|
774 |
@Override |
|
775 |
public void windowDeactivated(WindowEvent e) { |
|
776 |
// TODO Auto-generated method stub |
|
777 |
Log.finest("SwingChartComposite.SwingChartComposite(...).new WindowListener() {...}.windowDeactivated()"); |
|
778 |
} |
|
779 |
|
|
780 |
@Override |
|
781 |
public void windowClosing(WindowEvent e) { |
|
782 |
// TODO Auto-generated method stub |
|
783 |
|
|
784 |
} |
|
785 |
|
|
786 |
@Override |
|
787 |
public void windowClosed(WindowEvent e) { |
|
788 |
// TODO Auto-generated method stub |
|
789 |
|
|
790 |
} |
|
791 |
|
|
792 |
@Override |
|
793 |
public void windowActivated(WindowEvent e) { |
|
794 |
// TODO Auto-generated method stub |
|
795 |
Log.finest("SwingChartComposite.SwingChartComposite(...).new WindowListener() {...}.windowActivated()"); |
|
796 |
} |
|
797 |
}); |
|
798 |
|
|
799 |
|
|
800 |
|
|
801 |
|
|
802 |
// this.frame.addWindowFocusListener(new WindowFocusListener() { |
|
803 |
// |
|
804 |
// @Override |
|
805 |
// public void windowLostFocus(WindowEvent e) { |
|
806 |
// // TODO Auto-generated method stub |
|
807 |
// Log.finest("SwingChartComposite.SwingChartComposite(...).new WindowFocusListener() {...}.windowLostFocus()"); |
|
808 |
// |
|
809 |
// // Force the keep the focus if the ChartEditor has the focus |
|
810 |
// if(!SwingChartComposite.this.isDisposed()) { |
|
811 |
// SwingChartComposite.this.getDisplay().asyncExec(new Runnable() { |
|
812 |
// @Override |
|
813 |
// public void run() { |
|
814 |
// if (Display.getCurrent().getFocusControl() == SwingChartComposite.this) { |
|
815 |
// Log.finest("SwingChartComposite.SwingChartComposite(...).new WindowFocusListener() {...}.windowLostFocus(): force focus in chart component."); |
|
816 |
// requestFocusInChartComponent(); |
|
817 |
// } |
|
818 |
// } |
|
819 |
// }); |
|
820 |
// } |
|
821 |
// |
|
822 |
// |
|
823 |
// |
|
824 |
// // FIXME: For Swing focus debug tests |
|
825 |
// if(RCPPreferences.getInstance().getBoolean(TBXPreferences.EXPERT_USER)) { |
|
826 |
// ((JComponent) rootPanel).setBorder(javax.swing.BorderFactory.createEmptyBorder()); |
|
827 |
// } |
|
828 |
// |
|
829 |
// |
|
830 |
// } |
|
831 |
// |
|
832 |
// @Override |
|
833 |
// public void windowGainedFocus(WindowEvent e) { |
|
834 |
// |
|
835 |
// // FIXME: For Swing focus debug tests |
|
836 |
// if(RCPPreferences.getInstance().getBoolean(TBXPreferences.EXPERT_USER)) { |
|
837 |
// ((JComponent) rootPanel).setBorder(new LineBorder(Color.red, 1)); |
|
838 |
// } |
|
839 |
// |
|
840 |
// |
|
841 |
// // TODO Auto-generated method stub |
|
842 |
// Log.finest("SwingChartComposite.SwingChartComposite(...).new WindowFocusListener() {...}.windowGainedFocus()"); |
|
843 |
// |
|
844 |
// |
|
845 |
// SwingChartComposite.this.getDisplay().asyncExec(new Runnable() { |
|
846 |
// @Override |
|
847 |
// public void run() { |
|
848 |
// if ( |
|
849 |
// Display.getCurrent().getFocusControl() == SwingChartComposite.this |
|
850 |
// //&& |
|
851 |
// //SwingChartComposite.this.chartEditor.getContextActivationToken() == null |
|
852 |
//// SwingChartComposite.this.chartEditor != PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor() |
|
853 |
// ) { |
|
854 |
// |
|
855 |
// Log.finest("SwingChartComposite.SwingChartComposite(...).new WindowFocusListener() {...}.windowGainedFocus(): activate the EditorPart."); |
|
856 |
// |
|
857 |
// Stack<Control> stack = new Stack<Control>(); |
|
858 |
// Control starter = SwingChartComposite.this; |
|
859 |
// Shell shell = SwingChartComposite.this.getShell(); |
|
860 |
// while (starter != null && !(starter instanceof Shell)) { |
|
861 |
// stack.push(starter.getParent()); |
|
862 |
// starter = starter.getParent(); |
|
863 |
// } |
|
864 |
// |
|
865 |
// Method m = null; |
|
866 |
// try { |
|
867 |
// // instead of calling the originally proposed |
|
868 |
// // workaround solution (below), |
|
869 |
// // |
|
870 |
//// Event event = new Event(); |
|
871 |
//// event.display = Display.getCurrent(); |
|
872 |
//// event.type = SWT.Activate; |
|
873 |
//// event.widget = stack.pop(); |
|
874 |
//// event.widget.notifyListeners(SWT.Activate, event); |
|
875 |
// // |
|
876 |
// // which should but does NOT set the active |
|
877 |
// // widget/control on the shell, we had |
|
878 |
// // to call the setActiveControl method directly. |
|
879 |
// // Updating the active control on the shell is |
|
880 |
// // important so that the last active |
|
881 |
// // control, when selected again, get the proper |
|
882 |
// // activation events fired. |
|
883 |
// |
|
884 |
// //PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().activate(SwingChartComposite.this.chartEditor); |
|
885 |
// |
|
886 |
// m = shell.getClass().getDeclaredMethod("setActiveControl", Control.class);// $NON-NLS-1$ |
|
887 |
// m.setAccessible(true); |
|
888 |
// while (!stack.isEmpty()) { |
|
889 |
// m.invoke(shell, stack.pop()); |
|
890 |
// } |
|
891 |
// |
|
892 |
// // force the Swing component focus |
|
893 |
// //setFocus(); |
|
894 |
// |
|
895 |
// } |
|
896 |
// catch (Exception e) { |
|
897 |
// Log.severe("** Embedded part was not able to set active control on Shell. This will result in other workbench parts not getting activated."); //$NON-NLS-1$ |
|
898 |
// Log.printStackTrace(e); |
|
899 |
// } |
|
900 |
// finally { |
|
901 |
// if (m != null) { |
|
902 |
// m.setAccessible(false); |
|
903 |
// } |
|
904 |
// } |
|
905 |
// } |
|
906 |
// } |
|
907 |
// }); |
|
908 |
// |
|
909 |
// } |
|
910 |
// }); |
|
911 |
|
|
912 |
|
|
913 |
|
|
790 | 914 |
// // Swing component focus delegation to the SWT chart composite |
791 | 915 |
// swingComponent.addFocusListener(new FocusListener() { |
792 | 916 |
// |
... | ... | |
839 | 963 |
// }); |
840 | 964 |
// |
841 | 965 |
|
842 |
|
|
843 | 966 |
|
844 | 967 |
|
845 |
|
|
846 | 968 |
// SWT |
847 | 969 |
|
848 | 970 |
// SWT Tooltips tests |
... | ... | |
970 | 1092 |
|
971 | 1093 |
|
972 | 1094 |
|
973 |
} |
|
974 |
|
|
975 |
|
|
976 |
// FIXME: SJ: some code here should be moved to the parent class ChartComposite |
|
977 |
@Override |
|
978 |
public void loadChart() { |
|
979 | 1095 |
|
980 |
// loads the chart from the result |
|
981 |
Object chart = this.chartEditor.getChart(); |
|
982 |
|
|
983 |
if(chart != null) { |
|
984 |
|
|
985 |
// creates components if they not exist |
|
986 |
if(this.chartComponent == null) { |
|
987 |
|
|
988 |
// recreates the chart if not of right type |
|
989 |
if(this.chartEditor.getResult().isChartDirty()) { |
|
990 |
try { |
|
991 |
this.chartEditor.getResult().clearLastRenderingParameters(); |
|
992 |
this.chartEditor.getResult().compute(); |
|
993 |
} |
|
994 |
catch (Exception e) { |
|
995 |
e.printStackTrace(); |
|
996 |
} |
|
997 |
} |
|
998 |
|
|
999 |
this.createChartComponent(); |
|
1000 |
|
|
1001 |
this.rootPanel.add((Component) this.chartComponent); |
|
1002 |
|
|
1003 |
this.frame.setVisible(true); |
|
1004 |
} |
|
1005 |
this.loadChart(this.chartEditor.getChart()); |
|
1006 |
} |
|
1007 | 1096 |
} |
1008 | 1097 |
|
1009 | 1098 |
|
1010 |
|
|
1011 |
|
|
1012 |
|
|
1013 |
@Override |
|
1014 |
public void copyChartViewToClipboard() { |
|
1015 |
|
|
1016 |
int w = ((Component) this.chartComponent).getWidth(); |
|
1017 |
int h = ((Component) this.chartComponent).getHeight(); |
|
1018 |
final BufferedImage bufferedImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); |
|
1019 |
Graphics2D g = bufferedImg.createGraphics(); |
|
1020 |
|
|
1021 |
|
|
1022 |
((Component) this.chartComponent).paint(g); |
|
1023 |
|
|
1024 |
Transferable img = new Transferable() { |
|
1025 |
|
|
1026 |
@Override |
|
1027 |
public boolean isDataFlavorSupported(DataFlavor flavor) { |
|
1028 |
return DataFlavor.imageFlavor.equals(flavor); |
|
1029 |
} |
|
1030 |
|
|
1031 |
@Override |
|
1032 |
public DataFlavor[] getTransferDataFlavors() { |
|
1033 |
return new DataFlavor[] {DataFlavor.imageFlavor}; |
|
1034 |
} |
|
1035 |
|
|
1036 |
@Override |
|
1037 |
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { |
|
1038 |
if(!DataFlavor.imageFlavor.equals(flavor)) { |
|
1039 |
throw new UnsupportedFlavorException(flavor); |
|
1040 |
} |
|
1041 |
return bufferedImg; |
|
1042 |
} |
|
1043 |
|
|
1044 |
}; |
|
1045 |
|
|
1046 |
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(img, null); |
|
1047 |
|
|
1048 |
} |
|
1049 |
|
|
1050 |
|
|
1051 |
|
|
1052 |
@Override |
|
1053 |
public EventCallBackHandler getMouseCallBackHandler() { |
|
1054 |
return super.getMouseCallBackHandler((Component) this.chartComponent); |
|
1055 |
} |
|
1056 |
|
|
1057 |
|
|
1058 |
@Override |
|
1059 |
public EventCallBackHandler getKeyCallBackHandler() { |
|
1060 |
return super.getKeyCallBackHandler((Component) this.chartComponent); |
|
1061 |
} |
|
1062 |
|
|
1063 |
|
|
1064 |
/** |
|
1065 |
* Converts an AWT event to SWT event. Also stores the Swing tool tip source text of the specified Swing component in the SWT event to give it to the SWT composite listener in <code>ChartComposite</code>. |
|
1066 |
* @param swtComposite |
|
1067 |
* @param swingComponent |
|
1068 |
* @param e |
|
1069 |
* @param eventType |
|
1070 |
* @return |
|
1071 |
*/ |
|
1072 |
// TODO : SJ: this method is incomplete |
|
1073 |
public static org.eclipse.swt.widgets.Event swingEventToSWT(Composite swtComposite, JComponent swingComponent, AWTEvent e, int eventType) { |
|
1074 |
|
|
1075 |
Event event = new Event(); |
|
1076 |
if(!swtComposite.isDisposed()) { |
|
1077 |
event.display = swtComposite.getDisplay(); |
|
1078 |
} |
|
1079 |
event.widget = swtComposite; |
|
1080 |
event.type = eventType; |
|
1081 |
|
|
1082 |
if(e instanceof MouseEvent) { |
|
1083 |
MouseEvent me = (MouseEvent) e; |
|
1084 |
event.button = me.getButton(); |
|
1085 |
try { |
|
1086 |
// Store the Swing tool tip source text in the SWT event to give it to the SWT composite listener in ChartComposite |
|
1087 |
// NOTE: this method call sometimes throws a java.lang.IndexOutOfBoundsException |
|
1088 |
event.text = swingComponent.getToolTipText(me); |
|
1089 |
} |
|
1090 |
catch(Exception e1) { |
|
1091 |
//e1.printStackTrace(); |
|
1092 |
} |
|
1093 |
event.x = me.getX(); |
|
1094 |
event.y = me.getY(); |
|
1095 |
} |
|
1096 |
return event; |
|
1097 |
} |
|
1098 |
|
|
1099 |
|
|
1100 |
|
|
1101 | 1099 |
} |
Formats disponibles : Unified diff