GWT: Create Canvas widget from CanvasElement - gwt

I want to wrap a CanvasElement (<canvas> in HTML) in a Canvas widget.
Many widgets (e.g. Label) have a static method SomeWidget.wrap(Element) for wrapping an existing DOM element.
I imagine Canvas does not feature such a method because not all browser support and therefore the user should be forced to go through createIfSupported().
Unfortunately the constructor in Canvas is private (protected would work), which means that Canvas can not be subclassed. (There isn't any constructor available in the derived class.)
Code snippets of createIfSupported and the constructor in the Canvas class:
public static Canvas createIfSupported() {
// check if canvas is supported; if it is not supported: return null
return new Canvas(element);
}
private Canvas(CanvasElement element) {
setElement(element);
}
I ended up copying the Canvas class and making the constructor public.
Is there a better way to do this?
If not, what is the reasoning behind it (besides that <canvas> might not be supported)?
I am using GWT version 2.4.0.rc1.
Thanks,
Julian

This question is old, but there is a solution in newer versions of GWT:
Canvas.wrap(canvasElement);
See javadocs.
I don't know in which version of GWT it was added, but It works on 2.7.0.

Related

How to use a FreeMarker template in a Magnolia App?

I'm using Magnolia 5.4 and have developed an app following the documentation:
https://documentation.magnolia-cms.com/display/DOCS54/Apps
The app is being rendered correctly in the magnolia shell.
Opening the app shows a «Hello World» message as described in the documentation:
https://documentation.magnolia-cms.com/display/DOCS54/Programming+an+app#Programminganapp-MainSubApp
I've removed the unnecessary code and ended up with this:
public class HelloWorldMainSubAppViewImpl implements HelloWorldMainSubAppView {
private VerticalLayout layout = new VerticalLayout();
private Listener listener;
public HelloWorldMainSubAppViewImpl() {
layout.setMargin(true);
layout.setSpacing(true);
layout.addComponent(new Label("Hello World!"));
}
#Override
public Component asVaadinComponent() {
return layout;
}
}
Instead of using the Label component I would like to use a FreeMarker template where I define a custom view.
Having read through the documentation I haven't figured out yet how to do this.
Here is the solution to my problem, based on the previous work.
This is the «EmbeddedPageSubApp» approach as described under «Custom App»
Create a regular page somewhere in your navigation.
Open the Configuration app, go to /modules/<APP_NAME>/apps/<APP_NAME>/subApps/main and add a url property to the mainSubApp with an absolute path to the previously created page.
Change value of the class property /modules/<APP_NAME>/apps/<APP_NAME>/subApps/main to info.magnolia.ui.framework.app.embedded.EmbeddedPageSubAppDescriptor
Change the value of the subAppClass property to info.magnolia.ui.framework.app.embedded.EmbeddedPageSubApp
If you don't want that page to be visible restrict its access within 'superuser' group / role so that only administrators can use it.
This binds that with an iframe. You should choose a blank template since the navigation elements of the embedded page are visible within the app.
I might be wrong here but to my knowledge Freemarker is only used to create templates and unfortunately limited to it. https://documentation.magnolia-cms.com/display/DOCS60/Template+scripts
On the other hand, What you want to do is to develop your custom app and here is an example of how to do that.
https://documentation.magnolia-cms.com/display/DOCS54/My+first+content+app
Also, if you are motivated to move to latest Magnolia version, you can define your custom app pretty easily using Content Types.
Hope that helps,
Cheers,

How to switch between UI implementations in run-time?

I'm developing an application using GWT 2.6.
Now I have a task to implement a functionality to switch between simple/expert modes (of view) at run-time. It means to show a simplified version of view which may contain another widgets.
But the problem is that all the views in most cases are "static" and defined as singletons (using GIN).
Is it possible to implement this using only GWT and what should I use to make it?.
There are many ways that this can be done. A couple of ideas that spring to mind:
Option 1.
Instead of using GIN to inject the view, inject a view provider (com.google.inject.Provider). This can be used by the code that builds the view (the activity?) to get the view. The implementation of the view provider can then return an implementation of the view for the relevant mode, simple or expert. For example,
#Inject
public ComposeMessageActivity(Provider<ComposeMessageView> viewProvider, ...) { ... }
#Override
public final void start(final AcceptsOneWidget panel, final EventBus eventBus) {
view = viewProvider.get();
Option 2.
Use deferred binding. This is not so dynamic but has the advantage a simple implementation will be a smaller download than an expert implementation. There is a project, gwt-seminar, on github that shows this in practice that has mobile and desktop versions.

Canvas J2mE list form

How can I create create a form/list using canvas and add TextField to it?
public void paint(Graphics g){
g.setColor(44,255,44);
g.fillRect(0,0, getWidth (), getHeight ());
form = new Form("");
form.append("acfascca");
}
See this article Drawing TextField on Canvas j2me. But i feel If you are starting new project means you can go with LWUIT Framework. Also see this discussion.
Canvas is a low level API, hence I don't think it supports adding of Form to it.

GWT integration with SmartGWT - Cant select text SectionStack->Section->Canvas->HTML

we've used a combination of GWT and smart gwt to add some features to an app we've built.
The problem I have is that we decided to make use of the accordion functionality (SectionStack's) that SmartGWT offers and we are nesting our stock gwt widget inside a canvas and then nesting that inside the section stack. E.G
SectionStack(SmartGWT)->Section(SmartGWT)->Canvas (SmartGWT)->VerticalPanel(GWT) -> Other GWT Widgets (HTML, labels etc)
Before we mixed GWT and SmartGWT it was possible to select text in the standard GWT widgets and then copy and paste etc. Nesting the GWT widgets in the SmartGWT canvas means this is now not possible. Can anyone offer an explanation why this is the case and/or a solution on how to fix it.
I've tried canvas.setCanSelectText(true); but this doesn't seem to do anything either.
We're using GWT 2.1 with SmartGWT 2.2. The demo app using SmartGWT2.2 seems to exhibit the same problem over at http://www.smartclient.com/smartgwt/showcase/#featured_gwt_integration . I've also tried GWT 2.0.x with SmartGWT 2.2
Any help appreciated.
For those interested I've managed to find a bug registered for this at : code.google.com/p/smartgwt/issues/…
Actually it is not an issue. You have to call the setCanSelectText method on the WidgetCanvas wich is wrapping your GWT widget. The WidgetCanvas is created in the addItem(Widget) method. One way to go is to override the addItem method like this:
#Override
public void addItem(Widget widget) {
if (widget instanceof Canvas) {
addItem((Canvas) widget);
} else {
WidgetCanvas wg = new WidgetCanvas(widget);
wg.setCanSelectText(true);
addItem(wg);
}
}

Problem with GWT TabPanel and Google Maps

Working with Google Web Toolkit (with Google Maps Extension) I got a little problem:
I want to insert a Google Map into a TabLayoutPanel. Without that TabLayoutPanel everything worked fine. But as soon as the Map is inside of a tab it behaves really strange (its not centered right, and "jumps" when you try to scroll.).
The same Problem is when using TabPanel instead of TabLayoutPanel.
extract from my code:
in the onModuleLoad - method of my EntryPoint class:
DockLayoutPanel mainPanel;
MainUITabs tabWidget = new MainUITabs();
mainPanel.add(tabWidget);
RootLayoutPanel.get().add(mainPanel);
the MainUITabsWiget looks about like that:
public class MainUITabs extends Composite {
public MainUITabs(){
TabLayoutPanel tabPanel = new TabLayoutPanel(10, Unit.PCT);
MapWidget googleMapsTab = buildMapWidget();
tabPanel.add(googleMapsTab, "Google Maps");
initWidget(tabPanel);
}
private MapWidget buildMapWidget() {
LatLng coord = LatLng.newInstance(51.509, 11.434);
final MapWidget map = new MapWidget(coord, 2);
map.setSize("600px", "300px");
map.setCenter(coord);
map.addControl(new LargeMapControl());
map.addOverlay(new Marker(coord));
return map;
}
}
Seems like the Map doesn't like to be inside a tab..does anyone have an idea where the problem could be?
Thanks.
Andy
The TabPanel docs say that "This widget will only work in quirks mode. If your application is in Standards Mode, use TabLayoutPanel instead."
So, if your page has a DOCTYPE and thus is in Standards Mode, that suggests you'll have problems.
I found that when using a TabPanel in Standards Mode, widgets on tabs after the first one (which aren't visible at first) don't always render correctly. A workaround was to render these elements when the tab is shown, by using SelectionHandler.onSelection, as noted in the docs for the deprecated method TabPanel#onTabSelected. But reading the bit I quoted above, that's probably asking for trouble and in Standards Mode you ought to use TabLayoutPanel instead.
At first glance this looks like a problem I had with integrating TinyMCE (a WYSIWYG editor) with GWT - generally, components like these don't like when the DOM changes - in this case, it happens when you switch tabs (in my case it was drag & drop).
IIRC, the solution was to remove the TinyMCE widget from the text field it wrapped around when it wasn't shown on the screen. In your case, you'd want to remove the MapWidget from tabPanel, while it's not shown. I'm not familiar enough with the Google Maps API to know if there's a designated method to do that, but you can try a simple tabPanel.remove(googleMapsTab);.