--- /dev/null
+/*******************************************************************************\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