LoadingGWTApplicationsInXWiki
Contents
Loading Google Web Toolkit (GWT) Applications in XWiki
In the document, we will see how to load a GWT application to Xwiki Page. I will take the Mail sample bundled with Google Web Toolkit (GWT) SDK for example.
First, we take a look how the WYSIWYG editor is injected into a textarea in the Xwiki page. Here is the code:
{{velocity}}
$xwiki.jsfx.use("js/xwiki/wysiwyg/xwe/XWikiWysiwyg.js", true)
{{/velocity}}
{{html}
<textarea id="demo"></textarea>
<script type="text/javascript">
Wysiwyg.onModuleLoad(function() {
new WysiwygEditor({hookId:'demo'});
});
</script>
{{/html}}
We will inject our Mail sample into a div based on the same rationale.
Step 1 Modify the Mail.java and Prepare the DOM
Open Mail.java file and add the follow string to the entry point onModuleLoad()String hookId = "mail_example";
Element hook = DOM.getElementById(hookId);
if (hook == null) {
return;
}
Element container = DOM.createDiv();
String containerId = hookId + "_container";
container.setId(containerId);
hook.getParentElement().replaceChild(container, hook);
In this case, we hard coded the name as "mail_example" of the div which will be injected in.
Step 2 Initialize the UI of Mail Sample
Here is the code:
DockPanel outer = initialUI();
private DockPanel initialUI()
{
singleton = this;
topPanel.setWidth("100%");
// MailList uses Mail.get() in its constructor, so initialize it after
// 'singleton'.
mailList = new MailList();
mailList.setWidth("100%");
// Create the right panel, containing the email list & details.
rightPanel.add(mailList);
rightPanel.add(mailDetail);
mailList.setWidth("100%");
mailDetail.setWidth("100%");
// Create a dock panel that will contain the menu bar at the top,
// the shortcuts to the left, and the mail list & details taking the rest.
DockPanel outer = new DockPanel();
outer.add(topPanel, DockPanel.NORTH);
outer.add(shortcuts, DockPanel.WEST);
outer.add(rightPanel, DockPanel.CENTER);
outer.setWidth("60%");
outer.setSpacing(4);
outer.setCellWidth(rightPanel, "100%");
// Hook the window resize event, so that we can adjust the UI.
Window.addResizeHandler(this);
return outer;
}
Be careful of this line in the Mail.java:Window.enableScrolling(false);
If you do not get rid of this line or pass the true parameter, there will not be any scrollbar in your Xwiki page.
Step 3 Inject the Mail Sample to Div
Use this line of code to inject mail into the div:
RootPanel.get(containerId).add(outer);So the overall code looks like:/*
* Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package gwt.sample.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
/**
* This application demonstrates how to construct a relatively complex user
* interface, similar to many common email readers. It has no back-end,
* populating its components with hard-coded data.
*/
public class Mail implements EntryPoint, ResizeHandler {
private static Mail singleton;
/**
* Instantiate an application-level image bundle. This object will provide
* programmatic access to all the images needed by widgets.
*/
private static final Images images = GWT.create(Images.class);
/**
* An aggragate image bundle that pulls together all the images for this
* application into a single bundle.
*/
public interface Images extends Shortcuts.Images, TopPanel.Images {
}
/**
* Gets the singleton Mail instance.
*/
public static Mail get() {
return singleton;
}
private TopPanel topPanel = new TopPanel(images);
private VerticalPanel rightPanel = new VerticalPanel();
private MailList mailList;
private MailDetail mailDetail = new MailDetail();
private Shortcuts shortcuts = new Shortcuts(images);
/**
* Displays the specified item.
*
* @param item
*/
public void displayItem(MailItem item) {
mailDetail.setItem(item);
}
/**
* This method constructs the application user interface by instantiating
* controls and hooking up event handler.
*/
public void onModuleLoad() {
loadingUI();
}
private void loadingUI(){
String hookId = "mail_example";
Element hook = DOM.getElementById(hookId);
if (hook == null) {
return;
}
// Prepare the DOM
Element container = DOM.createDiv();
String containerId = hookId + "_container";
container.setId(containerId);
hook.getParentElement().replaceChild(container, hook);
DockPanel outer = initialUI();
RootPanel.get(containerId).add(outer);
// Call the window resized handler to get the initial sizes setup. Doing
// this in a deferred command causes it to occur after all widgets' sizes
// have been computed by the browser.
DeferredCommand.addCommand(new Command() {
public void execute() {
onWindowResized(Window.getClientWidth(), Window.getClientHeight());
}
});
onWindowResized(Window.getClientWidth(), Window.getClientHeight());
}// end of loadingUI
private DockPanel initialUI()
{
singleton = this;
topPanel.setWidth("100%");
// MailList uses Mail.get() in its constructor, so initialize it after
// 'singleton'.
mailList = new MailList();
mailList.setWidth("100%");
// Create the right panel, containing the email list & details.
rightPanel.add(mailList);
rightPanel.add(mailDetail);
mailList.setWidth("100%");
mailDetail.setWidth("100%");
// Create a dock panel that will contain the menu bar at the top,
// the shortcuts to the left, and the mail list & details taking the rest.
DockPanel outer = new DockPanel();
outer.add(topPanel, DockPanel.NORTH);
outer.add(shortcuts, DockPanel.WEST);
outer.add(rightPanel, DockPanel.CENTER);
outer.setWidth("60%");
outer.setSpacing(4);
outer.setCellWidth(rightPanel, "100%");
// Hook the window resize event, so that we can adjust the UI.
Window.addResizeHandler(this);
return outer;
}
public void onResize(ResizeEvent event) {
onWindowResized(event.getWidth(), event.getHeight());
}
public void onWindowResized(int width, int height) {
// Adjust the shortcut panel and detail area to take up the available room
// in the window.
int shortcutHeight = height - shortcuts.getAbsoluteTop() - 8;
if (shortcutHeight < 1) {
shortcutHeight = 1;
}
shortcuts.setHeight(shortcutHeight + "px");
// Give the mail detail widget a chance to resize itself as well.
mailDetail.adjustSize(width, height);
}
}
Step 4 Copy the compiled code to the right directory
After the compile of your Java GWT code, under war folder you can find the compiled JavaScript and html files in the mail folder. Copy the mail directory to webapps/xwiki/resources/js/xwiki/. Then in edit the Xwiki page that you wants to include the Mail sample at wiki edit mode. Include the the following code:
{{velocity}}
$xwiki.jsfx.use("js/xwiki/mail/mail.nocache.js", true)
{{html}}
<div id="mail_example">Mail</div>
{{/html}}
{{/velocity}}
Click "Save & View", the mail sample should appear on top of your page. The appearance of mail application might be appeared broken a little due to the size of your Xwiki page. You can adjust the layout by modifying the Mail.java file.
Reference
"All GWT sample applications append their UIs to the HTML body using RootPanel.get() but that's not good. One way to pass this information to onModuleLoad method is to use a JavaScript configuration object and GWT's Dictionary class. See getConfig(int) method in http://tinyurl.com/ybzdw32 and the Wysiwyg0 JavaScript object in http://tinyurl.com/y9nhaos. The hookId configuration parameter tells me where to put the WYSIWYG editor." - Marius