]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
9a8f43887c069d90fb0c399c59b6d94652af8a55
[simantics/sysdyn.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.sysdyn.ui.properties.widgets;\r
13 \r
14 import java.awt.Font;\r
15 import java.awt.GraphicsEnvironment;\r
16 import java.util.ArrayList;\r
17 import java.util.List;\r
18 import java.util.Locale;\r
19 import java.util.TreeMap;\r
20 \r
21 import org.eclipse.core.runtime.ListenerList;\r
22 import org.eclipse.jface.layout.GridDataFactory;\r
23 import org.eclipse.jface.layout.GridLayoutFactory;\r
24 import org.eclipse.jface.resource.FontDescriptor;\r
25 import org.eclipse.jface.resource.JFaceResources;\r
26 import org.eclipse.jface.resource.LocalResourceManager;\r
27 import org.eclipse.swt.SWT;\r
28 import org.eclipse.swt.events.KeyEvent;\r
29 import org.eclipse.swt.events.KeyListener;\r
30 import org.eclipse.swt.events.ModifyEvent;\r
31 import org.eclipse.swt.events.ModifyListener;\r
32 import org.eclipse.swt.events.SelectionEvent;\r
33 import org.eclipse.swt.events.SelectionListener;\r
34 import org.eclipse.swt.graphics.FontData;\r
35 import org.eclipse.swt.graphics.Point;\r
36 import org.eclipse.swt.graphics.Rectangle;\r
37 import org.eclipse.swt.widgets.Composite;\r
38 import org.eclipse.swt.widgets.Event;\r
39 import org.eclipse.swt.widgets.Listener;\r
40 import org.eclipse.swt.widgets.ScrollBar;\r
41 import org.eclipse.swt.widgets.Table;\r
42 import org.eclipse.swt.widgets.TableColumn;\r
43 import org.eclipse.swt.widgets.TableItem;\r
44 import org.eclipse.swt.widgets.Text;\r
45 \r
46 /**\r
47  * Composite for displaying font selection tools. By default, the composite contains\r
48  * font family, font style and font size.\r
49  * \r
50  * @author Teemu Lempinen\r
51  *\r
52  */\r
53 public class FontSelectionComposite extends Composite {\r
54 \r
55 \r
56     protected Text fontName, fontStyle, fontSize;\r
57     protected ArrayList<String> familyIndex = new ArrayList<String>();\r
58     protected TreeMap<String, ArrayList<Font>> fonts = getFonts(familyIndex);\r
59     protected Table fontFamilyTable, fontStyleTable, fontSizeTable;\r
60     protected String[] sizes = new String[] {"8", "9", "10", "11", "12", "14", "16", "18", "20", "24", "26", "28", "36", "48", "72"};\r
61 \r
62     private ListenerList modifyListeners;\r
63     \r
64     private final LocalResourceManager resourceManager;\r
65 \r
66     /**\r
67      * Gets all available fonts\r
68      * @param familyIndex Optional list for indexing font families\r
69      * @return Tree where key is font family name and object a list of fonts belonging to that family\r
70      */\r
71     private static TreeMap<String, ArrayList<Font>> getFonts(ArrayList<String> familyIndex) {\r
72         TreeMap<String, ArrayList<Font>> fonts = new TreeMap<String, ArrayList<Font>>();\r
73 \r
74         GraphicsEnvironment gEnv = GraphicsEnvironment\r
75                 .getLocalGraphicsEnvironment();\r
76         Font allFonts[] = gEnv.getAllFonts();\r
77 \r
78         for(Font font : allFonts) {\r
79             String family = font.getFamily(Locale.ROOT);\r
80             if(!fonts.containsKey(family)) {\r
81                 if(familyIndex != null)\r
82                     familyIndex.add(family);\r
83                 fonts.put(family, new ArrayList<Font>());\r
84             }\r
85 \r
86             boolean add = true;\r
87             for(Font f : fonts.get(family)) {\r
88                 if(f.getFontName().equals(font.getFontName())) {\r
89                     add = false;\r
90                     break;\r
91                 }\r
92             }\r
93 \r
94             if(add)\r
95                 fonts.get(family).add(font);\r
96         }\r
97         return fonts;\r
98     }\r
99 \r
100     /**\r
101      * Composite containing components for selecting a font\r
102      * \r
103      * @param parent Parent composite\r
104      * @param style SWT style\r
105      */\r
106     public FontSelectionComposite(Composite parent, int style) {\r
107         super(parent, style);\r
108         \r
109         // Create a ResourceManager to dispose images when the widget is disposed.\r
110         this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), this);\r
111 \r
112         modifyListeners = new ListenerList();\r
113 \r
114         GridLayoutFactory.fillDefaults().numColumns(3).applyTo(this);\r
115         GridDataFactory.fillDefaults().applyTo(this);\r
116 \r
117         /*\r
118          * Two-row layout. First row consists of editable text boxes,\r
119          * second row consists of tables containing possible options\r
120          */\r
121 \r
122         // First row\r
123         fontName = new Text(this, SWT.BORDER);\r
124         GridDataFactory.fillDefaults().applyTo(fontName);\r
125 \r
126         fontStyle = new Text(this, SWT.BORDER);\r
127         GridDataFactory.fillDefaults().applyTo(fontStyle);\r
128 \r
129         fontSize = new Text(this, SWT.BORDER);\r
130         GridDataFactory.fillDefaults().applyTo(fontSize);\r
131 \r
132         // Second row\r
133         fontFamilyTable = new Table (this, SWT.VIRTUAL | SWT.BORDER | SWT.FULL_SELECTION);\r
134         fontFamilyTable.setLinesVisible (false);\r
135         fontFamilyTable.setHeaderVisible (false);\r
136         GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 100).applyTo(fontFamilyTable);\r
137         fontFamilyTable.setItemCount(familyIndex.size());\r
138         TableColumn column = new TableColumn (fontFamilyTable, SWT.NONE);\r
139         column.setWidth(200);\r
140 \r
141 \r
142         fontStyleTable = new Table (this, SWT.BORDER | SWT.FULL_SELECTION);\r
143         fontStyleTable.setLinesVisible (false);\r
144         fontStyleTable.setHeaderVisible (false);\r
145         GridDataFactory.fillDefaults().hint(100, 100).applyTo(fontStyleTable);\r
146         column = new TableColumn (fontStyleTable, SWT.NONE);\r
147         setFontStyleTableWidth();\r
148 \r
149 \r
150 \r
151         fontSizeTable = new Table (this, SWT.VIRTUAL | SWT.BORDER | SWT.FULL_SELECTION);\r
152         fontSizeTable.setLinesVisible (false);\r
153         fontSizeTable.setHeaderVisible (false);\r
154         GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 100).applyTo(fontSizeTable);\r
155         column = new TableColumn (fontSizeTable, SWT.NONE);\r
156         column.setWidth(70);\r
157         for(String size : sizes) {\r
158             TableItem item = new TableItem(fontSizeTable, SWT.NONE);\r
159             item.setText(0, size);\r
160         }\r
161 \r
162         // Listeners for components\r
163         addFontFamilyListeners();\r
164         addFontStyleListeners();\r
165         addFontSizeListeners();\r
166     }\r
167 \r
168 \r
169     /**\r
170      * Set controls to display given font\r
171      */\r
172     public void setFont(Font font, boolean notify) {\r
173         if(font == null)\r
174             return;\r
175         \r
176         Object[] listeners = new Object[0];\r
177         if(!notify) {\r
178             listeners = modifyListeners.getListeners();\r
179             for(Object listener : listeners)\r
180                 modifyListeners.remove(listener);\r
181         }\r
182 \r
183         String fontFamily = font.getFamily(Locale.ROOT);\r
184         String fontName = font.getFontName(Locale.ROOT);\r
185         this.fontName.setText(fontFamily);\r
186         this.fontFamilyTable.setTopIndex(this.fontFamilyTable.getSelectionIndex());\r
187 \r
188         String style = "Regular";\r
189         if(fontName.length() > fontFamily.length())\r
190             style = fontName.substring(fontFamily.length() + 1);\r
191         this.fontStyle.setText(style);\r
192 \r
193         int size = font.getSize();\r
194         fontSize.setText("" + size);\r
195 \r
196         for(int i = 0; i < sizes.length; i++) {\r
197             if(sizes[i].equals("" + size)) {\r
198                 fontSizeTable.select(i);\r
199                 fontSizeTable.setTopIndex(i);\r
200                 fontChanged();\r
201                 break;\r
202             }\r
203         }  \r
204         \r
205         if(!notify) {\r
206             for(Object listener : listeners)\r
207                 modifyListeners.add(listener);\r
208         }\r
209     }\r
210 \r
211     /**\r
212      * Get the AWT font defined in this composite\r
213      * @return AWT font\r
214      */\r
215     public Font getAWTFont() {\r
216         String family = fontName.getText();\r
217         String style = fontStyle.getText();\r
218         if(style.equals("Regular"))\r
219             style = null;\r
220         \r
221         int stylebits = 0;\r
222         if(style != null) {\r
223             if(style.toLowerCase().contains("bold"))\r
224                 stylebits |= SWT.BOLD;\r
225             if(style.toLowerCase().contains("italic"))\r
226                 stylebits |= SWT.ITALIC;\r
227         }\r
228 \r
229         String name = family + (style != null ? " " + style : "");\r
230 \r
231         int size = 10;\r
232         try {\r
233             size = Integer.parseInt(fontSize.getText());\r
234         } catch (NumberFormatException e) {\r
235         }\r
236 \r
237         if(name != null && name.length() > 0)\r
238             return new Font(name, stylebits, size);\r
239         else\r
240             return null;\r
241     }\r
242     \r
243     /**\r
244      * Adds listeners for font family name text and table\r
245      */\r
246     protected void addFontFamilyListeners() {\r
247 \r
248         // Font name modify listener\r
249         fontName.addModifyListener(new ModifyListener() {\r
250 \r
251             @Override\r
252             public void modifyText(ModifyEvent e) {\r
253                 Text text = (Text) e.widget;\r
254                 String name = text.getText();\r
255                 fontFamilyTextModified(name, false);\r
256             }\r
257         });\r
258 \r
259         // Font name key listener for auto-completion\r
260         fontName.addKeyListener(new KeyListener() {\r
261 \r
262             @Override\r
263             public void keyReleased(KeyEvent e) {\r
264             }\r
265 \r
266             @Override\r
267             public void keyPressed(KeyEvent e) {\r
268                 if ((e.character == ' ') && ((e.stateMask & SWT.CTRL) != 0) ) {\r
269                     fontFamilyTextModified(fontName.getText(), true);\r
270                     e.doit = false;\r
271                 } else if(e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) {\r
272                     fontChanged();\r
273                 }\r
274             }\r
275         });\r
276         \r
277         // Call listener when editing has ended\r
278         fontName.addListener(SWT.FocusOut, new Listener() {\r
279             public void handleEvent(Event e) {\r
280                 fontChanged();\r
281             }\r
282         });\r
283 \r
284         // Font family data listener for lazy initialization of the table\r
285         fontFamilyTable.addListener (SWT.SetData, new Listener () {\r
286             public void handleEvent (Event event) {\r
287                 TableItem item = (TableItem) event.item;\r
288                 int index = fontFamilyTable.indexOf (item);\r
289 \r
290                 String family = familyIndex.get(index);\r
291                 item.setText (family);\r
292 \r
293                 Font font = fonts.get(family).get(0);\r
294                 if(font.canDisplay('a')) {\r
295                     FontData fontData =  toSwtFontData(font, 10);\r
296                     org.eclipse.swt.graphics.Font swtFont = resourceManager.createFont(FontDescriptor.createFrom(fontData));\r
297                     item.setFont(swtFont);\r
298                 }\r
299             }\r
300         });\r
301 \r
302 \r
303         // Updates selected font to font name text\r
304         fontFamilyTable.addSelectionListener(new SelectionListener() {\r
305 \r
306             @Override\r
307             public void widgetSelected(SelectionEvent e) {\r
308                 TableItem[] selection = fontFamilyTable.getSelection();\r
309 \r
310                 if(selection.length > 0) {\r
311                     String family = selection[0].getText();\r
312                     fontName.setText(family);\r
313                     fontChanged();\r
314                 }\r
315             }\r
316 \r
317             @Override\r
318             public void widgetDefaultSelected(SelectionEvent e) {\r
319             }\r
320         });\r
321 \r
322         /*\r
323          *  Forces focus to font name texts and starts editing it, \r
324          *  if user presses a letter when focus is in font family table\r
325          */\r
326         fontFamilyTable.addKeyListener(new KeyListener() {\r
327             @Override\r
328             public void keyReleased(KeyEvent e) {\r
329             }\r
330 \r
331             @Override\r
332             public void keyPressed(KeyEvent e) {\r
333                 if(Character.isLetter(e.character)) {\r
334                     fontName.forceFocus();\r
335                     fontName.setTextChars(new char[] {e.character});\r
336                     fontName.setSelection(1, 1);\r
337                 }\r
338             }\r
339         });\r
340     }\r
341 \r
342     /**\r
343      * Implements interactions between font name text and font family table, when \r
344      * the text in font name text has been changed.\r
345      * @param name New name\r
346      * @param autoComplete Has autocomplete been called\r
347      */\r
348     protected void fontFamilyTextModified(String name, boolean autoComplete) {\r
349         if(name.isEmpty())\r
350             return;\r
351         for(int i = 0; i < familyIndex.size(); i++) {\r
352             String family = familyIndex.get(i);\r
353             if(family.equals(name)) {\r
354                 //complete match\r
355                 fontFamilyTable.select(i);\r
356                 selectFontFamily(name);\r
357                 break;\r
358             } else if(family.toLowerCase().equals(name.toLowerCase())) {\r
359                 // Wrong case but correct name\r
360                 fontName.setText(family);\r
361                 fontName.setSelection(family.length(), family.length());\r
362                 fontFamilyTable.setTopIndex(i);\r
363                 fontChanged();\r
364                 break;\r
365             } else if(family.toLowerCase().startsWith(name.toLowerCase())) {\r
366                 if(autoComplete) {\r
367                     // Fill in the rest of the name\r
368                     fontName.setText(family);\r
369                     fontName.setSelection(family.length());\r
370                     fontChanged();\r
371                     // The beginning is correct, help user by displaying the nearest name\r
372                 } else { \r
373                     fontFamilyTable.setTopIndex(i);\r
374                 }\r
375                 break;\r
376             }\r
377         }\r
378     }\r
379 \r
380 \r
381     /**\r
382      * Adds listeners for font style text and table\r
383      */\r
384     protected void addFontStyleListeners() {\r
385 \r
386         // Font style modify listener\r
387         fontStyle.addModifyListener(new ModifyListener() {\r
388 \r
389             @Override\r
390             public void modifyText(ModifyEvent e) {\r
391                 Text text = (Text) e.widget;\r
392                 String name = text.getText();\r
393                 fontStyleTextModified(name, false);\r
394             }\r
395         });\r
396 \r
397         // Font style key listener for auto-complete\r
398         fontStyle.addKeyListener(new KeyListener() {\r
399 \r
400             @Override\r
401             public void keyReleased(KeyEvent e) {\r
402             }\r
403 \r
404             @Override\r
405             public void keyPressed(KeyEvent e) {\r
406                 if ((e.character == ' ') && ((e.stateMask & SWT.CTRL) != 0) ) {\r
407                     fontStyleTextModified(fontStyle.getText(), true);\r
408                     e.doit = false;\r
409                 } else if(e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) {\r
410                     fontChanged();\r
411                 }\r
412             }\r
413         });\r
414 \r
415         // Update selected style to font style text\r
416         fontStyleTable.addSelectionListener(new SelectionListener() {\r
417 \r
418             @Override\r
419             public void widgetSelected(SelectionEvent e) {\r
420                 TableItem[] selection = fontStyleTable.getSelection();\r
421 \r
422                 if(selection.length > 0) {\r
423                     String family = selection[0].getText();\r
424                     fontStyle.setText(family);\r
425                     fontChanged();\r
426                 }\r
427             }\r
428 \r
429             @Override\r
430             public void widgetDefaultSelected(SelectionEvent e) {\r
431             }\r
432         });\r
433 \r
434         /*\r
435          *  Forces focus to font style text and starts editing it, \r
436          *  if user presses a letter when focus is in font style table\r
437          */\r
438         fontStyleTable.addKeyListener(new KeyListener() {\r
439             @Override\r
440             public void keyReleased(KeyEvent e) {\r
441             }\r
442 \r
443             @Override\r
444             public void keyPressed(KeyEvent e) {\r
445                 if(Character.isLetter(e.character)) {\r
446                     fontStyle.forceFocus();\r
447                     fontStyle.setTextChars(new char[] {e.character});\r
448                     fontStyle.setSelection(1, 1);\r
449                     e.doit = false;\r
450                 } else if(e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) {\r
451                     fontChanged();\r
452                 }\r
453             }\r
454         });\r
455     }\r
456 \r
457     /**\r
458      * Handles interactions between font style text and font style table, when\r
459      * font style text has been changed\r
460      * \r
461      * @param name New text for font style \r
462      * @param autoComplete is auto-completion used\r
463      */\r
464     protected void fontStyleTextModified(String name, boolean autoComplete) {\r
465         if(name.isEmpty())\r
466             return;\r
467 \r
468         for(int i = 0; i < fontStyleTable.getItemCount(); i++) {\r
469             TableItem item = fontStyleTable.getItem(i);\r
470             String style = item.getText();\r
471 \r
472             if(style.equals(name)) {\r
473                 //complete match\r
474                 fontStyleTable.select(i);\r
475                 break;\r
476             } else if(style.toLowerCase().equals(name.toLowerCase())) {\r
477                 // Wrong case, correct style. -> fix the case\r
478                 fontStyle.setText(style);\r
479                 fontStyle.setSelection(style.length());\r
480                 fontStyleTable.setTopIndex(i);\r
481                 fontChanged();\r
482                 break;\r
483             } else if(style.toLowerCase().startsWith(name.toLowerCase())) {\r
484                 // The beginning of the word is correct\r
485                 fontStyleTable.setTopIndex(i);\r
486                 if(autoComplete) {\r
487                     // Fill in the rest of the name\r
488                     fontStyle.setText(style);\r
489                     fontStyle.setSelection(style.length());\r
490                     fontChanged();\r
491                     // The beginning is correct, help user by displaying the nearest name\r
492                 } else { \r
493                     fontStyleTable.setTopIndex(i);\r
494                 }\r
495                 break;\r
496             }\r
497         }\r
498     }\r
499 \r
500 \r
501     /**\r
502      * Listeners for font size text and font size table\r
503      */\r
504     protected void addFontSizeListeners() {\r
505 \r
506         // Select an item from size table, if there is a matching item \r
507         fontSize.addKeyListener(new KeyListener() {\r
508 \r
509             @Override\r
510             public void keyReleased(KeyEvent e) {\r
511                 Text text = (Text) e.widget;\r
512                 String size = text.getText();\r
513 \r
514                 for(int i = 0; i < sizes.length; i++) {\r
515                     if(sizes[i].equals(size)) {\r
516                         fontSizeTable.select(i);\r
517                         fontSizeTable.setTopIndex(i);\r
518                         fontChanged();\r
519                         break;\r
520                     }\r
521                 }  \r
522             }\r
523 \r
524             @Override\r
525             public void keyPressed(KeyEvent e) {\r
526             }\r
527         });\r
528 \r
529         // Change the text in size text according to the selection in size table\r
530         fontSizeTable.addSelectionListener(new SelectionListener() {\r
531 \r
532             @Override\r
533             public void widgetSelected(SelectionEvent e) {\r
534                 fontSize.setText(fontSizeTable.getSelection()[0].getText());\r
535                 fontChanged();\r
536             }\r
537 \r
538             @Override\r
539             public void widgetDefaultSelected(SelectionEvent e) {\r
540             }\r
541         });\r
542 \r
543         // Change focus from table to text, if user starts to write a number \r
544         fontSizeTable.addKeyListener(new KeyListener() {\r
545 \r
546             @Override\r
547             public void keyReleased(KeyEvent e) { }\r
548 \r
549             @Override\r
550             public void keyPressed(KeyEvent e) {\r
551                 if(Character.isDigit(e.character)) {\r
552                     fontSize.setTextChars(new char[]{e.character});\r
553                     fontSize.setSelection(1);\r
554                     fontSize.forceFocus();\r
555                     e.doit = false;\r
556                 }\r
557             }\r
558         });\r
559 \r
560     }\r
561 \r
562     /**\r
563      * Creates the contents of fontStyleTable according to the selected font family \r
564      * @param family Selected font family\r
565      */\r
566     protected void selectFontFamily(String family) {\r
567         String old = fontStyle.getText();\r
568         String selection = null, optionalSelection = null;\r
569 \r
570         // Clear the table\r
571         fontStyleTable.removeAll();\r
572 \r
573         if(familyIndex.indexOf(family) > -1) {\r
574             for(int i = 0; i < fonts.get(family).size(); i++) {\r
575                 Font font = fonts.get(family).get(i);\r
576 \r
577                 String name = font.getFontName(Locale.ROOT);\r
578 \r
579                 // Style is "Regular", unless otherwise defined\r
580                 String style = "Regular";\r
581                 if(name.length() > family.length())\r
582                     style = name.substring(family.length() + 1);\r
583 \r
584                 // If previous font was bold, try to conserve the style\r
585                 if(old.equals(style))\r
586                     selection  = style;\r
587                 else if((!old.isEmpty() && style.contains(old)) || optionalSelection == null)\r
588                     optionalSelection = style;\r
589 \r
590                 TableItem item = new TableItem (fontStyleTable, SWT.NONE);\r
591                 item.setText (0, style);\r
592                 item.setData(font);\r
593 \r
594                 // If the font is not symbolic, use the font in the created item\r
595                 if(font.canDisplay('a')) {\r
596                     FontData fontData = toSwtFontData(font, 10);\r
597                     org.eclipse.swt.graphics.Font swtFont = resourceManager.createFont(FontDescriptor.createFrom(fontData));\r
598                     item.setFont(swtFont);\r
599                 }\r
600             }\r
601             fontStyleTable.setItemCount(fonts.get(family).size());\r
602 \r
603             if(selection == null)\r
604                 selection = optionalSelection;\r
605 \r
606             fontStyle.setText(selection);\r
607             fontStyle.setSelection(selection.length(), selection.length());\r
608 \r
609             setFontStyleTableWidth();\r
610         }\r
611     }\r
612 \r
613     /**\r
614      * Set width for style table column. Width can change, if scroll bar appears \r
615      */\r
616     protected void setFontStyleTableWidth() {\r
617         Rectangle area = fontStyleTable.getClientArea();\r
618         Point size = fontStyleTable.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
619         ScrollBar vBar = fontStyleTable.getVerticalBar();\r
620         int width = 100;\r
621         if (area.height == 0 || size.y <= area.height) {\r
622             Point vBarSize = vBar.getSize();\r
623             width += vBarSize.x;\r
624         }\r
625         fontStyleTable.getColumn(0).setWidth(width);\r
626     }\r
627 \r
628 \r
629     /**\r
630      * Builds SWT FontData from AWT font. Simple conversion.\r
631      * \r
632      * @param font AWT font\r
633      * @param height Height for the created data (or -1 if inherited directly from awt font, size matching not guaranteed)\r
634      * @return\r
635      */\r
636     protected static FontData toSwtFontData(Font font, int height) {\r
637         FontData fontData = new FontData();\r
638         fontData.setName(font.getFontName());\r
639         fontData.setStyle(font.getStyle());\r
640         fontData.setHeight(height > 0 ? height : font.getSize());\r
641         return fontData;\r
642     }\r
643 \r
644 \r
645     public void addFontModifiedListener(FontModifyListener listener) {\r
646         modifyListeners.add(listener);\r
647     }\r
648 \r
649     public void removeFontModifiedListener(FontModifyListener listener) {\r
650         modifyListeners.remove(listener);\r
651     }\r
652 \r
653     public List<FontModifyListener> getFontModifiedListener() {\r
654         ArrayList<FontModifyListener> listeners = new ArrayList<FontModifyListener>(modifyListeners.size());\r
655         for(Object l : modifyListeners.getListeners())\r
656             listeners.add((FontModifyListener)l);\r
657         return listeners;\r
658     }\r
659 \r
660     /**\r
661      * Called when some property of the font definiton has changed.\r
662      * Calls font change listeners.\r
663      */\r
664     protected void fontChanged() {\r
665         Font font = getAWTFont();\r
666         if(font != null) {\r
667             \r
668             int style = 0;\r
669             style |= (font.getFontName(Locale.ROOT).contains("Bold") ? SWT.BOLD : 0);\r
670             style |= (font.getFontName(Locale.ROOT).contains("Italic") ? SWT.ITALIC : 0);\r
671             FontData fontData = new FontData(font.getFamily(Locale.ROOT), font.getSize(), style);\r
672             \r
673             Object[] listenersArray = modifyListeners.getListeners();\r
674             for (int i = 0; i < listenersArray.length; i++) {\r
675                 ((FontModifyListener)listenersArray[i]).awtFontChanged(font);\r
676                 ((FontModifyListener)listenersArray[i]).swtFontDataChanged(fontData);\r
677             }\r
678         }\r
679     }\r
680 \r
681 }\r