]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
First implementation of font changing controls (refs #2959)
authorlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Fri, 2 Mar 2012 14:35:05 +0000 (14:35 +0000)
committerlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Fri, 2 Mar 2012 14:35:05 +0000 (14:35 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@24332 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FontSelectionComposite.java [new file with mode: 0644]

diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FontSelectionComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FontSelectionComposite.java
new file mode 100644 (file)
index 0000000..fd3b4a3
--- /dev/null
@@ -0,0 +1,668 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.awt.Font;\r
+import java.awt.GraphicsEnvironment;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Locale;\r
+import java.util.TreeMap;\r
+\r
+import org.eclipse.core.runtime.ListenerList;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.FontData;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.ScrollBar;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableColumn;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.management.ISessionContext;\r
+\r
+/**\r
+ * Composite for displaying font selection tools. By default, the composite contains\r
+ * font family, font style and font size.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class FontSelectionComposite extends Composite {\r
+\r
+\r
+    protected Text fontName, fontStyle, fontSize;\r
+    protected ArrayList<String> familyIndex = new ArrayList<String>();\r
+    protected TreeMap<String, ArrayList<Font>> fonts = getFonts(familyIndex);\r
+    protected Table fontFamilyTable, fontStyleTable, fontSizeTable;\r
+    protected String[] sizes = new String[] {"8", "9", "10", "11", "12", "14", "16", "18", "20", "24", "26", "28", "36", "48", "72"};\r
+\r
+    private ListenerList modifyListeners;\r
+\r
+\r
+    /**\r
+     * Gets all available fonts\r
+     * @param familyIndex Optional list for indexing font families\r
+     * @return Tree where key is font family name and object a list of fonts belonging to that family\r
+     */\r
+    private static TreeMap<String, ArrayList<Font>> getFonts(ArrayList<String> familyIndex) {\r
+        TreeMap<String, ArrayList<Font>> fonts = new TreeMap<String, ArrayList<Font>>();\r
+\r
+        GraphicsEnvironment gEnv = GraphicsEnvironment\r
+                .getLocalGraphicsEnvironment();\r
+        Font allFonts[] = gEnv.getAllFonts();\r
+\r
+        for(Font font : allFonts) {\r
+            String family = font.getFamily(Locale.ROOT);\r
+            if(!fonts.containsKey(family)) {\r
+                if(familyIndex != null)\r
+                    familyIndex.add(family);\r
+                fonts.put(family, new ArrayList<Font>());\r
+            }\r
+\r
+            boolean add = true;\r
+            for(Font f : fonts.get(family)) {\r
+                if(f.getFontName().equals(font.getFontName())) {\r
+                    add = false;\r
+                    break;\r
+                }\r
+            }\r
+\r
+            if(add)\r
+                fonts.get(family).add(font);\r
+        }\r
+        return fonts;\r
+    }\r
+\r
+    /**\r
+     * Composite containing components for selecting a font\r
+     * \r
+     * @param parent Parent composite\r
+     * @param context {@link ISessionContext}\r
+     * @param support {@link WidgetSupport}\r
+     * @param style SWT style\r
+     */\r
+    public FontSelectionComposite(Composite parent, ISessionContext context, WidgetSupport support, int style) {\r
+        super(parent, style);\r
+\r
+        modifyListeners = new ListenerList();\r
+\r
+        GridLayoutFactory.fillDefaults().numColumns(3).applyTo(this);\r
+\r
+        /*\r
+         * Two-row layout. First row consists of editable text boxes,\r
+         * second row consists of tables containing possible options\r
+         */\r
+\r
+        // First row\r
+        fontName = new Text(this, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().applyTo(fontName);\r
+\r
+        fontStyle = new Text(this, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().applyTo(fontStyle);\r
+\r
+        fontSize = new Text(this, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().applyTo(fontSize);\r
+\r
+        // Second row\r
+        fontFamilyTable = new Table (this, SWT.VIRTUAL | SWT.BORDER | SWT.FULL_SELECTION);\r
+        fontFamilyTable.setLinesVisible (false);\r
+        fontFamilyTable.setHeaderVisible (false);\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 100).applyTo(fontFamilyTable);\r
+        fontFamilyTable.setItemCount(familyIndex.size());\r
+        TableColumn column = new TableColumn (fontFamilyTable, SWT.NONE);\r
+        column.setWidth(200);\r
+\r
+\r
+        fontStyleTable = new Table (this, SWT.BORDER | SWT.FULL_SELECTION);\r
+        fontStyleTable.setLinesVisible (false);\r
+        fontStyleTable.setHeaderVisible (false);\r
+        GridDataFactory.fillDefaults().hint(100, 100).applyTo(fontStyleTable);\r
+        column = new TableColumn (fontStyleTable, SWT.NONE);\r
+        setFontStyleTableWidth();\r
+\r
+\r
+\r
+        fontSizeTable = new Table (this, SWT.VIRTUAL | SWT.BORDER | SWT.FULL_SELECTION);\r
+        fontSizeTable.setLinesVisible (false);\r
+        fontSizeTable.setHeaderVisible (false);\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 100).applyTo(fontSizeTable);\r
+        column = new TableColumn (fontSizeTable, SWT.NONE);\r
+        column.setWidth(70);\r
+        for(String size : sizes) {\r
+            TableItem item = new TableItem(fontSizeTable, SWT.NONE);\r
+            item.setText(0, size);\r
+        }\r
+\r
+        // Listeners for components\r
+        addFontFamilyListeners();\r
+        addFontStyleListeners();\r
+        addFontSizeListeners();\r
+    }\r
+\r
+\r
+    /**\r
+     * Set controls to display given font\r
+     */\r
+    public void setFont(Font font, boolean notify) {\r
+        Object[] listeners = new Object[0];\r
+        if(!notify) {\r
+            listeners = modifyListeners.getListeners();\r
+            for(Object listener : listeners)\r
+                modifyListeners.remove(listener);\r
+        }\r
+\r
+        String fontFamily = font.getFamily(Locale.ROOT);\r
+        String fontName = font.getFontName(Locale.ROOT);\r
+        this.fontName.setText(fontFamily);\r
+        this.fontFamilyTable.setTopIndex(this.fontFamilyTable.getSelectionIndex());\r
+\r
+        String style = "Regular";\r
+        if(fontName.length() > fontFamily.length())\r
+            style = fontName.substring(fontFamily.length() + 1);\r
+        this.fontStyle.setText(style);\r
+\r
+        int size = font.getSize();\r
+        fontSize.setText("" + size);\r
+        \r
+        if(!notify) {\r
+            for(Object listener : listeners)\r
+                modifyListeners.add(listener);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Get the AWT font defined in this composite\r
+     * @return AWT font\r
+     */\r
+    public Font getAWTFont() {\r
+        String family = fontName.getText();\r
+        String style = fontStyle.getText();\r
+        if(style.equals("Regular"))\r
+            style = null;\r
+\r
+        String name = family + (style != null ? " " + style : "");\r
+\r
+        int size = 10;\r
+        try {\r
+            size = Integer.parseInt(fontSize.getText());\r
+        } catch (NumberFormatException e) {\r
+        }\r
+\r
+        if(name != null && name.length() > 0)\r
+            return new Font(name, 0, size);\r
+        else\r
+            return null;\r
+    }\r
+\r
+\r
+    /**\r
+     * Adds listeners for font family name text and table\r
+     */\r
+    protected void addFontFamilyListeners() {\r
+\r
+        // Font name modify listener\r
+        fontName.addModifyListener(new ModifyListener() {\r
+\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                Text text = (Text) e.widget;\r
+                String name = text.getText();\r
+                fontFamilyTextModified(name, false);\r
+            }\r
+        });\r
+\r
+        // Font name key listener for auto-completion\r
+        fontName.addKeyListener(new KeyListener() {\r
+\r
+            @Override\r
+            public void keyReleased(KeyEvent e) {\r
+            }\r
+\r
+            @Override\r
+            public void keyPressed(KeyEvent e) {\r
+                if ((e.character == ' ') && ((e.stateMask & SWT.CTRL) != 0) ) {\r
+                    fontFamilyTextModified(fontName.getText(), true);\r
+                    e.doit = false;\r
+                } else if(e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) {\r
+                    fontChanged();\r
+                }\r
+            }\r
+        });\r
+        \r
+        // Call listener when editing has ended\r
+        fontName.addListener(SWT.FocusOut, new Listener() {\r
+            public void handleEvent(Event e) {\r
+                fontChanged();\r
+            }\r
+        });\r
+\r
+        // Font family data listener for lazy initialization of the table\r
+        fontFamilyTable.addListener (SWT.SetData, new Listener () {\r
+            public void handleEvent (Event event) {\r
+                TableItem item = (TableItem) event.item;\r
+                int index = fontFamilyTable.indexOf (item);\r
+\r
+                String family = familyIndex.get(index);\r
+                item.setText (family);\r
+\r
+                Font font = fonts.get(family).get(0);\r
+                if(font.canDisplay('a')) {\r
+                    FontData fontData =  toSwtFontData(font, 10);\r
+                    org.eclipse.swt.graphics.Font swtFont = new org.eclipse.swt.graphics.Font(item.getDisplay(), fontData);\r
+                    item.setFont(swtFont);\r
+                }\r
+            }\r
+        });\r
+\r
+\r
+        // Updates selected font to font name text\r
+        fontFamilyTable.addSelectionListener(new SelectionListener() {\r
+\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                TableItem[] selection = fontFamilyTable.getSelection();\r
+\r
+                if(selection.length > 0) {\r
+                    String family = selection[0].getText();\r
+                    fontName.setText(family);\r
+                    fontChanged();\r
+                }\r
+            }\r
+\r
+            @Override\r
+            public void widgetDefaultSelected(SelectionEvent e) {\r
+            }\r
+        });\r
+\r
+        /*\r
+         *  Forces focus to font name texts and starts editing it, \r
+         *  if user presses a letter when focus is in font family table\r
+         */\r
+        fontFamilyTable.addKeyListener(new KeyListener() {\r
+            @Override\r
+            public void keyReleased(KeyEvent e) {\r
+            }\r
+\r
+            @Override\r
+            public void keyPressed(KeyEvent e) {\r
+                if(Character.isLetter(e.character)) {\r
+                    fontName.forceFocus();\r
+                    fontName.setTextChars(new char[] {e.character});\r
+                    fontName.setSelection(1, 1);\r
+                }\r
+            }\r
+        });\r
+    }\r
+\r
+    /**\r
+     * Implements interactions between font name text and font family table, when \r
+     * the text in font name text has been changed.\r
+     * @param name New name\r
+     * @param autoComplete Has autocomplete been called\r
+     */\r
+    protected void fontFamilyTextModified(String name, boolean autoComplete) {\r
+        if(name.isEmpty())\r
+            return;\r
+        for(int i = 0; i < familyIndex.size(); i++) {\r
+            String family = familyIndex.get(i);\r
+            if(family.equals(name)) {\r
+                //complete match\r
+                fontFamilyTable.select(i);\r
+                selectFontFamily(name);\r
+                break;\r
+            } else if(family.toLowerCase().equals(name.toLowerCase())) {\r
+                // Wrong case but correct name\r
+                fontName.setText(family);\r
+                fontName.setSelection(family.length(), family.length());\r
+                fontFamilyTable.setTopIndex(i);\r
+                fontChanged();\r
+                break;\r
+            } else if(family.toLowerCase().startsWith(name.toLowerCase())) {\r
+                if(autoComplete) {\r
+                    // Fill in the rest of the name\r
+                    fontName.setText(family);\r
+                    fontName.setSelection(family.length());\r
+                    fontChanged();\r
+                    // The beginning is correct, help user by displaying the nearest name\r
+                } else { \r
+                    fontFamilyTable.setTopIndex(i);\r
+                }\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Adds listeners for font style text and table\r
+     */\r
+    protected void addFontStyleListeners() {\r
+\r
+        // Font style modify listener\r
+        fontStyle.addModifyListener(new ModifyListener() {\r
+\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                Text text = (Text) e.widget;\r
+                String name = text.getText();\r
+                fontStyleTextModified(name, false);\r
+            }\r
+        });\r
+\r
+        // Font style key listener for auto-complete\r
+        fontStyle.addKeyListener(new KeyListener() {\r
+\r
+            @Override\r
+            public void keyReleased(KeyEvent e) {\r
+            }\r
+\r
+            @Override\r
+            public void keyPressed(KeyEvent e) {\r
+                if ((e.character == ' ') && ((e.stateMask & SWT.CTRL) != 0) ) {\r
+                    fontStyleTextModified(fontStyle.getText(), true);\r
+                    e.doit = false;\r
+                } else if(e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) {\r
+                    fontChanged();\r
+                }\r
+            }\r
+        });\r
+\r
+        // Update selected style to font style text\r
+        fontStyleTable.addSelectionListener(new SelectionListener() {\r
+\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                TableItem[] selection = fontStyleTable.getSelection();\r
+\r
+                if(selection.length > 0) {\r
+                    String family = selection[0].getText();\r
+                    fontStyle.setText(family);\r
+                    fontChanged();\r
+                }\r
+            }\r
+\r
+            @Override\r
+            public void widgetDefaultSelected(SelectionEvent e) {\r
+            }\r
+        });\r
+\r
+        /*\r
+         *  Forces focus to font style text and starts editing it, \r
+         *  if user presses a letter when focus is in font style table\r
+         */\r
+        fontStyleTable.addKeyListener(new KeyListener() {\r
+            @Override\r
+            public void keyReleased(KeyEvent e) {\r
+            }\r
+\r
+            @Override\r
+            public void keyPressed(KeyEvent e) {\r
+                if(Character.isLetter(e.character)) {\r
+                    fontStyle.forceFocus();\r
+                    fontStyle.setTextChars(new char[] {e.character});\r
+                    fontStyle.setSelection(1, 1);\r
+                    e.doit = false;\r
+                } else if(e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) {\r
+                    fontChanged();\r
+                }\r
+            }\r
+        });\r
+    }\r
+\r
+    /**\r
+     * Handles interactions between font style text and font style table, when\r
+     * font style text has been changed\r
+     * \r
+     * @param name New text for font style \r
+     * @param autoComplete is auto-completion used\r
+     */\r
+    protected void fontStyleTextModified(String name, boolean autoComplete) {\r
+        if(name.isEmpty())\r
+            return;\r
+\r
+        for(int i = 0; i < fontStyleTable.getItemCount(); i++) {\r
+            TableItem item = fontStyleTable.getItem(i);\r
+            String style = item.getText();\r
+\r
+            if(style.equals(name)) {\r
+                //complete match\r
+                fontStyleTable.select(i);\r
+                break;\r
+            } else if(style.toLowerCase().equals(name.toLowerCase())) {\r
+                // Wrong case, correct style. -> fix the case\r
+                fontStyle.setText(style);\r
+                fontStyle.setSelection(style.length());\r
+                fontStyleTable.setTopIndex(i);\r
+                fontChanged();\r
+                break;\r
+            } else if(style.toLowerCase().startsWith(name.toLowerCase())) {\r
+                // The beginning of the word is correct\r
+                fontStyleTable.setTopIndex(i);\r
+                if(autoComplete) {\r
+                    // Fill in the rest of the name\r
+                    fontStyle.setText(style);\r
+                    fontStyle.setSelection(style.length());\r
+                    fontChanged();\r
+                    // The beginning is correct, help user by displaying the nearest name\r
+                } else { \r
+                    fontStyleTable.setTopIndex(i);\r
+                }\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Listeners for font size text and font size table\r
+     */\r
+    protected void addFontSizeListeners() {\r
+\r
+        // Select an item from size table, if there is a matching item \r
+        fontSize.addKeyListener(new KeyListener() {\r
+\r
+            @Override\r
+            public void keyReleased(KeyEvent e) {\r
+                Text text = (Text) e.widget;\r
+                String size = text.getText();\r
+\r
+                for(int i = 0; i < sizes.length; i++) {\r
+                    if(sizes[i].equals(size)) {\r
+                        fontSizeTable.select(i);\r
+                        fontSizeTable.setTopIndex(i);\r
+                        fontChanged();\r
+                        break;\r
+                    }\r
+                }  \r
+            }\r
+\r
+            @Override\r
+            public void keyPressed(KeyEvent e) {\r
+            }\r
+        });\r
+\r
+        // Change the text in size text according to the selection in size table\r
+        fontSizeTable.addSelectionListener(new SelectionListener() {\r
+\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                fontSize.setText(fontSizeTable.getSelection()[0].getText());\r
+                fontChanged();\r
+            }\r
+\r
+            @Override\r
+            public void widgetDefaultSelected(SelectionEvent e) {\r
+            }\r
+        });\r
+\r
+        // Change focus from table to text, if user starts to write a number \r
+        fontSizeTable.addKeyListener(new KeyListener() {\r
+\r
+            @Override\r
+            public void keyReleased(KeyEvent e) { }\r
+\r
+            @Override\r
+            public void keyPressed(KeyEvent e) {\r
+                if(Character.isDigit(e.character)) {\r
+                    fontSize.setTextChars(new char[]{e.character});\r
+                    fontSize.setSelection(1);\r
+                    fontSize.forceFocus();\r
+                    e.doit = false;\r
+                }\r
+            }\r
+        });\r
+\r
+    }\r
+\r
+    /**\r
+     * Creates the contents of fontStyleTable according to the selected font family \r
+     * @param family Selected font family\r
+     */\r
+    protected void selectFontFamily(String family) {\r
+        String old = fontStyle.getText();\r
+        String selection = null, optionalSelection = null;\r
+\r
+        // Clear the table\r
+        fontStyleTable.removeAll();\r
+\r
+        if(familyIndex.indexOf(family) > -1) {\r
+            for(int i = 0; i < fonts.get(family).size(); i++) {\r
+                Font font = fonts.get(family).get(i);\r
+\r
+                String name = font.getFontName(Locale.ROOT);\r
+\r
+                // Style is "Regular", unless otherwise defined\r
+                String style = "Regular";\r
+                if(name.length() > family.length())\r
+                    style = name.substring(family.length() + 1);\r
+\r
+                // If previous font was bold, try to conserve the style\r
+                if(old.equals(style))\r
+                    selection  = style;\r
+                else if((!old.isEmpty() && style.contains(old)) || optionalSelection == null)\r
+                    optionalSelection = style;\r
+\r
+                TableItem item = new TableItem (fontStyleTable, SWT.NONE);\r
+                item.setText (0, style);\r
+                item.setData(font);\r
+\r
+                // If the font is not symbolic, use the font in the created item\r
+                if(font.canDisplay('a')) {\r
+                    FontData fontData = toSwtFontData(font, 10);\r
+                    org.eclipse.swt.graphics.Font swtFont = new org.eclipse.swt.graphics.Font(item.getDisplay(), fontData);\r
+                    item.setFont(swtFont);\r
+                }\r
+            }\r
+            fontStyleTable.setItemCount(fonts.get(family).size());\r
+\r
+            if(selection == null)\r
+                selection = optionalSelection;\r
+\r
+            fontStyle.setText(selection);\r
+            fontStyle.setSelection(selection.length(), selection.length());\r
+\r
+            setFontStyleTableWidth();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Set width for style table column. Width can change, if scroll bar appears \r
+     */\r
+    protected void setFontStyleTableWidth() {\r
+        Rectangle area = fontStyleTable.getClientArea();\r
+        Point size = fontStyleTable.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+        ScrollBar vBar = fontStyleTable.getVerticalBar();\r
+        int width = 100;\r
+        if (area.height == 0 || size.y <= area.height) {\r
+            Point vBarSize = vBar.getSize();\r
+            width += vBarSize.x;\r
+        }\r
+        fontStyleTable.getColumn(0).setWidth(width);\r
+    }\r
+\r
+\r
+    /**\r
+     * Builds SWT FontData from AWT font. Simple conversion.\r
+     * \r
+     * @param font AWT font\r
+     * @param height Height for the created data (or -1 if inherited directly from awt font, size matching not guaranteed)\r
+     * @return\r
+     */\r
+    protected static FontData toSwtFontData(Font font, int height) {\r
+        FontData fontData = new FontData();\r
+        fontData.setName(font.getFontName());\r
+        fontData.setStyle(font.getStyle());\r
+        fontData.setHeight(height > 0 ? height : font.getSize());\r
+        return fontData;\r
+    }\r
+\r
+\r
+    public void addFontModifiedListener(FontChangeListener listener) {\r
+        modifyListeners.add(listener);\r
+    }\r
+\r
+    public void removeFontModifiedListener(FontChangeListener listener) {\r
+        modifyListeners.remove(listener);\r
+    }\r
+\r
+    public List<FontChangeListener> getFontModifiedListener() {\r
+        ArrayList<FontChangeListener> listeners = new ArrayList<FontChangeListener>(modifyListeners.size());\r
+        for(Object l : modifyListeners.getListeners())\r
+            listeners.add((FontChangeListener)l);\r
+        return listeners;\r
+    }\r
+\r
+    /**\r
+     * Called when some property of the font definiton has changed.\r
+     * Calls font change listeners.\r
+     */\r
+    protected void fontChanged() {\r
+        Font font = getAWTFont();\r
+        if(font != null) {\r
+            \r
+            int style = 0;\r
+            style |= (font.getFontName(Locale.ROOT).contains("Bold") ? SWT.BOLD : 0);\r
+            style |= (font.getFontName(Locale.ROOT).contains("Italic") ? SWT.ITALIC : 0);\r
+            FontData data = new FontData(font.getFamily(Locale.ROOT), font.getSize(), style);\r
+            org.eclipse.swt.graphics.Font swt = new org.eclipse.swt.graphics.Font(this.getDisplay(), data);\r
+            \r
+            Object[] listenersArray = modifyListeners.getListeners();\r
+            for (int i = 0; i < listenersArray.length; i++) {\r
+                ((FontChangeListener)listenersArray[i]).awtFontChanged(font);\r
+                ((FontChangeListener)listenersArray[i]).swtFontChanged(swt);\r
+            }\r
+        }\r
+    }\r
+\r
+    \r
+\r
+    /**\r
+     * Font change listening interface\r
+     */\r
+    public interface FontChangeListener {\r
+        public void awtFontChanged(Font font);\r
+        public void swtFontChanged(org.eclipse.swt.graphics.Font font);\r
+    }\r
+}\r