Cette section explique pas à pas comment implémenter sa propre grammaire XML et son propre renderer UI. Cette exemple s'appuiera sur une grammaire XML MyXMLMarkup qui sera indentifiée par le namespace http://tk-ui.sourceforge.net/MyXMLMarkup .Le renderer implémenté sera SWT.
Le principe est de charger dans un DOM Document implémentant l'interface org.akrogen.tkui.core.dom.IDOMDocument un contenu MyXMLMarkup . Ce DOM document doit être initialisé avec deux types de factory :<MyPage xmlns="http://tk-ui.sourceforge.net/MyXMLMarkup" > <MyTextbox text="bla bla bla" /> </MyPage>
Vous pourrez trouver l'exemple de cette section dans le projet Eclipse org.akrogen.tkui.samples.myxmlmarkup-1 stocké sur SVN.
La classe org.akrogen.tkui.impl.core.dom.bindings.DOMDocumentBindableImpl est l'implémentation du org.akrogen.tkui.core.dom.IDOMDocument de TK-UI qui permet de charger une grammaire XML et de la rendre en Swing, SWT.... Elle permet de gérer le binding à l'aide de JFace Databinding.
package org.akrogen.tkui.samples.myxmlmarkup.impl.dom; import org.akrogen.tkui.impl.core.dom.css.DOMElementNSStylableImpl; import org.apache.xerces.dom.CoreDocumentImpl; import org.w3c.dom.DOMException; public class MyTextboxElementImpl extends DOMElementNSStylableImpl { public MyTextboxElementImpl(CoreDocumentImpl ownerDocument, String namespaceURI, String qualifiedName, String localName) throws DOMException { super(ownerDocument, namespaceURI, qualifiedName, localName); } public String getUIElementId() { return "myText"; } protected void applyBindings() { // TODO : manage bindings between UI and DOM } }
package org.akrogen.tkui.samples.myxmlmarkup.dom; import org.akrogen.tkui.core.dom.IDOMElementFactory; import org.akrogen.tkui.samples.myxmlmarkup.impl.dom.MyTextboxElementImpl; import org.apache.xerces.dom.CoreDocumentImpl; import org.w3c.dom.Document; import org.w3c.dom.Element; public class MyDOMElementFactoryImpl implements IDOMElementFactory { private static final IDOMElementFactory instance = new MyDOMElementFactoryImpl(); public static IDOMElementFactory getInstance() { return instance; } public String getNamespaceURI() { return "http://tk-ui.sourceforge.net/MyXMLMarkup"; } public Element createElementNS(Document ownerDocument, String namespaceURI, String qualifiedName, String localName) { if ("MyTextbox".equals(localName)) { return new MyTextboxElementImpl((CoreDocumentImpl) ownerDocument, namespaceURI, qualifiedName, localName); } return null; } }
<MyPage xmlns="http://tk-ui.sourceforge.net/MyXMLMarkup" > <MyTextbox text="bla bla bla" /> </MyPage>
package org.akrogen.tkui.samples.myxmlmarkup.impl.ui; import org.akrogen.tkui.core.ui.elements.IUIElementInfo; import org.akrogen.tkui.core.ui.elements.IUINativeElement; import org.akrogen.tkui.impl.core.ui.bindings.AbstractUIElementBindable; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Text; public class MySWTTextImpl extends AbstractUIElementBindable { protected Object buildNativeWidget(IUINativeElement parentUIElement, IUIElementInfo uiElementInfo, IUINativeElement uiNativeElement) { Composite parent = (Composite)parentUIElement.getNativeWidget(); Text text = new Text(parent, SWT.BORDER); return text; } public void dispose() { ((Text)getNativeWidget()) .dispose(); } public boolean isDisposed() { return ((Text)getNativeWidget()).isDisposed(); } public IUINativeElement getUIWindowElement() { return null; } }
package org.akrogen.tkui.samples.myxmlmarkup.ui; import org.akrogen.tkui.core.ui.UIConstants; import org.akrogen.tkui.core.ui.elements.IUIElementFactory; import org.akrogen.tkui.core.ui.elements.IUINativeElement; import org.akrogen.tkui.impl.core.ui.AbstractUIElementFactory; import org.akrogen.tkui.samples.myxmlmarkup.impl.ui.MySWTTextImpl; public class MySWTElementFactoryImpl extends AbstractUIElementFactory { private static final IUIElementFactory instance = new MySWTElementFactoryImpl(); public static IUIElementFactory getInstance() { return instance; } public String getId() { return "MySWT"; } public String getType() { return UIConstants.SWT_UI_ELEMENT_FACTORY_TYPE; } protected void registerDefaultUIElements() { registerUIElement("myText", MySWTTextImpl.class); } public IUINativeElement getUINativeElement(final Object nativeWidget) { return new IUINativeElement() { public Object getNativeWidget() { return nativeWidget; } public IUINativeElement getUIWindowElement() { return null; } }; } }
.... public String getUIElementId() { return "myText"; }
package org.akrogen.tkui.samples.myxmlmarkup; import java.io.InputStream; import org.akrogen.tkui.core.IConfiguration; import org.akrogen.tkui.core.dom.bindings.IDOMDocumentBindable; import org.akrogen.tkui.core.ui.elements.IUIElementFactory; import org.akrogen.tkui.impl.core.ConfigurationImpl; import org.akrogen.tkui.samples.myxmlmarkup.dom.MyDOMElementFactoryImpl; import org.akrogen.tkui.samples.myxmlmarkup.impl.dom.MyDocumentImpl; import org.akrogen.tkui.samples.myxmlmarkup.ui.MySWTElementFactoryImpl; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xml.sax.InputSource; public class TestMyPage { public static void main(String[] args) { try { Display display = new Display(); Shell shell = new Shell(display, SWT.SHELL_TRIM); shell.setLayout(new FillLayout()); // 2. Load MyPage into Xerces DOM parser InputStream source = TestMyPage.class .getResourceAsStream("page.myxmlmarkup"); org.apache.xerces.parsers.DOMParser parser = new org.apache.xerces.parsers.DOMParser(); parser.setFeature("http://xml.org/sax/features/namespaces", true); parser.parse(new InputSource(source)); source.close(); // 3. Initialise TK-UI configuration IConfiguration configuration = new ConfigurationImpl(); // Register My DOM element factory configuration .registerDOMElementFactory(MyDOMElementFactoryImpl.getInstance()); // Register My SWT UI element factory IUIElementFactory mySWTUIElementFactory = MySWTElementFactoryImpl.getInstance(); configuration.registerUIElementFactory(mySWTUIElementFactory); // 4. Initialize TK-UI DOM document final IDOMDocumentBindable document = new MyDocumentImpl(); // Regsiter configuration document.setConfiguration(configuration); // Regsiter UI Element SWT factory to use to create SWT widgets. document.setUIElementFactoryId(mySWTUIElementFactory.getId()); // Set Shell as root. SWT widgets created. document.setNativeWidgetRoot(shell); // 6. Import nodes of the DOM HTML into TK-UI DOM document // and add nodes imported into TK-UI DOM document Document sourceDocument = parser.getDocument(); Node newNode = document.importNode(sourceDocument .getDocumentElement(), true); document.appendChild(newNode); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } shell.dispose(); } catch (Exception e) { e.printStackTrace(); } } }
Le code de Test ci dessous peut paraitre lourd et il est possible de le simplifier en utilisant des IToolkit et une instance de IPlatform. TK-UI se configure a l'aide d'uen instance IConfiguration qui stocke les IDOMElementFactory et IUIElementFactory. Un ITookit est une instance qui permet de configurer un IConfiguration. Dans cette section nous allons creer un Toolkit qui permet d'enregistrer le IDOMElementFactory (MyDOMElementFactoryImpl) et le IUIElementFactory (MySWTElementFactoryImpl).
Creer la classe MyDOMToolkit. Cette classe enregistre la factory MyDOMElementFactoryImpl au sein d'une instance configuration :
package org.akrogen.tkui.samples.myxmlmarkup.dom.toolkit; import org.akrogen.tkui.core.IConfiguration; import org.akrogen.tkui.core.dom.toolkit.IDOMToolkit; import org.akrogen.tkui.samples.myxmlmarkup.dom.MyDOMElementFactoryImpl; public class MyDOMToolkit implements IDOMToolkit { private static final IDOMToolkit toolkit = new MyDOMToolkit(); public static IDOMToolkit getDefaultToolkit() { return toolkit; } public void initialize(IConfiguration configuration) { configuration.registerDOMElementFactory(MyDOMElementFactoryImpl .getInstance()); } }
Creer la classe MySWTToolkit. Cette classe enregistre la factory MySWTElementFactoryImpl au sein d'une instance configuration :
package org.akrogen.tkui.samples.myxmlmarkup.ui.toolkit; import org.akrogen.tkui.core.IConfiguration; import org.akrogen.tkui.core.ui.toolkit.IUIToolkit; import org.akrogen.tkui.impl.core.ui.toolkit.AbstractUIToolkitImpl; import org.akrogen.tkui.samples.myxmlmarkup.ui.MySWTElementFactoryImpl; import org.eclipse.core.databinding.DataBindingContext; public class MySWTToolkit extends AbstractUIToolkitImpl { private static final IUIToolkit toolkit = new MySWTToolkit(); public static IUIToolkit getDefaultToolkit() { return toolkit; } protected void registerUIElementFactories(IConfiguration configuration) { configuration.registerUIElementFactory(MySWTElementFactoryImpl .getInstance()); } public String getDefaultUIElementFactoryId() { return MySWTElementFactoryImpl.getInstance().getId(); } public DataBindingContext getDataBindingContext(Object nativeWidgetRoot) { return null; } }
package org.akrogen.tkui.samples.myxmlmarkup.platform; import org.akrogen.tkui.core.IConfiguration; import org.akrogen.tkui.core.exceptions.TkuiRuntimeException; import org.akrogen.tkui.core.platform.IPlatform; import org.akrogen.tkui.impl.core.platform.AbstractPlatformImpl; import org.akrogen.tkui.samples.myxmlmarkup.dom.toolkit.MyDOMToolkit; import org.akrogen.tkui.samples.myxmlmarkup.ui.toolkit.MySWTToolkit; import org.eclipse.swt.widgets.Widget; public class MySWTPlatform extends AbstractPlatformImpl { private static IPlatform instance = new MySWTPlatform(); public static IPlatform getDefaultPlatform() { return instance; } public MySWTPlatform() { super(MySWTToolkit.getDefaultToolkit()); } protected void initializeDOMToolkit() { IConfiguration configuration = super.getConfiguration(); MyDOMToolkit.getDefaultToolkit().initialize(configuration); } protected void checkNativeWidgetRoot(Object nativeWidgetRoot) { if (!(nativeWidgetRoot instanceof Widget)) { throw new TkuiRuntimeException( "widget parameter of createDocument method must be instance of " + Widget.class); } } }
package org.akrogen.tkui.samples.myxmlmarkup; import org.akrogen.tkui.core.dom.bindings.IDOMDocumentBindable; import org.akrogen.tkui.core.platform.IPlatform; import org.akrogen.tkui.samples.myxmlmarkup.platform.MySWTPlatform; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class TestMyPageWithPlatform { public static void main(String[] args) { try { Display display = new Display(); Shell shell = new Shell(display, SWT.SHELL_TRIM); shell.setLayout(new FillLayout()); // Get MySWTPlatform IPlatform platform = MySWTPlatform.getDefaultPlatform(); IDOMDocumentBindable document = platform.createDocument(shell, null, null); // Load MyPage into TK-UI DOM Document platform.loadDocument(TestMyPageWithPlatform.class .getResourceAsStream("page.myxmlmarkup"), document); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } shell.dispose(); } catch (Exception e) { e.printStackTrace(); } } }