Custom TabLayoutPanel in GWT - gwt

I'm trying to create my custom TabLayoutPanel extension, my code is following:
public class ExpandableTabLayoutPanel extends TabLayoutPanel {
#UiConstructor
public ExpandableTabLayoutPanel(double barHeight, Unit barUnit) {
super(barHeight, barUnit);
addExpandableBehaviour();
}
private addExpandableBehaviour(){
//...
}
}
And here I invoke it from UIBinder:
<a:ExpandableTabLayoutPanel barHeight="20" barUnit="PX">
<a:tab>
<a:header>header</a:header>
<a:AdvancedRichTextArea styleName="{style.area}" ui:field="area"/>
</a:tab>
</a:ExpandableTabLayoutPanel>
(I was forced by error messages to use a:tab/a:header instead of g:tab/g:header even if I don't have tab and header defined in my a: package/workspace, but that's probably not the issue)
If #UiConstructor annotation is present over ExpandableTabLayoutPanel like in the listing, I'm getting strange error:
[ERROR] [gwtreproduce] - <a:ExpandableTabLayoutPanel barHeight='20' barUnit='PX'> missing required attribute(s): arg1 barHeight Element <a:ExpandableTabLayoutPanel barHeight='20' barUnit='PX'> (:13)
When I disable #UiConstructor, I'm getting even stranger error:
[ERROR] [gwtreproduce] - Errors in 'generated://E6338B946DFB2D28988DA492134093C7/reproduce/client/TestView_TestViewUiBinderImpl.java' : [ERROR] [gwtreproduce] - Line 33: Type mismatch: cannot convert from TabLayoutPanel to ExpandableTabLayoutPanel
What am I doing wrong with extending TabLayoutPanel?
And side question: how it is possible that TabLayoutPanel constructor isn't annotated with #UiConstructor and can be used in UiBinder (how UiBinder knows which constructor to invoke)?

for you side question : you have to add (provided=true) to the UiField annotation of your widget. Then in the code, set the instance yourself, before createAndBindUi() call like this :
class Whaoo extends Composite{
/* with 'provided', UiBinder don't call any constructor */
#UiField(provided = true)
final Great foo;
interface WhaooUiBinder extends
UiBinder<Widget, Whaoo> {}
private static WhaooUiBinder uiBinder =
GWT.create(WhaooUiBinder.class);
public Whaoo() {
// initialize "provided" before createAndBindUi call
foo = new Great(String bar, int pouet);
initWidget(uiBinder.createAndBindUi(this));
}
}

Related

Abstract components via org.osgi.service.component annotations

I am migrating from org.apache.felix.scr annotations to org.osgi.service.component annotations. I have a set of Components that inherit from a common abstract class. In the felix case, I can use a #Component annotation with the option componentAbstract=true on the super class, and then use #Reference annotation in the super class. I cannot find how to migrate this to osgi annotations.
Is it possible to use Component annotations in a super class of a Component? And if so, what is then the appropriate way to handle the properties and metatype generation?
So, what I am looking for, is something like this
/* No component definition should be generated for the parent, as it is
abstract and cannot be instantiated */
#Component(property="parent.property=parentValue")
public abstract class Parent {
#Reference
protected Service aService;
protected activate(Map<String,Object> props) {
System.out.println("I have my parent property: "+props.get("parent.property"));
#Override
public abstract void doSomething();
}
/* For this class, the proper Component definition should be generated, also
including the information coming from the annotations in the parent */
#Component(property="child.property=childValue")
public class Child extends Parent {
#Activate
public activate(Map<String,Object> props) {
super.activate(props);
System.out.println("I have my child property: "+props.get("child.property"));
}
public void doSomething() {
aService.doSomething();
}
}
By default BND will not process DS annotations in parent classes. You can change that with -dsannotations-options: inherit but please see http://enroute.osgi.org/faq/ds-inheritance.html why you shouldn't!
2021-02-23 UPDATE: It seems like the page mentioned above is no longer available. I don't know if it was moved elsewhere or simply removed but its content (in Markdown format) is still available on GitHub: https://github.com/osgi/osgi.enroute.site/blob/pre-R7/_faq/ds-inheritance.md

Usage of JsniBundle: calling methods on initialized js library

When I initialize d3.js and dc.js using JsniBundle there is no global variable "dc" or "d3" that is created. But I initialze crossfilter in the same way and there is window.crossfilter present.
My question is: what is the best way to call methods from the dc library using JsniBundle? Is using JsUtils.prop(window, "dc") the correct way to get a reference to the library object?
In the method drawBarChartWidget() below, the variable "dc" is null.
public interface D3Bundle extends JsniBundle {
#LibrarySource("d3.js")
public void initD3();
}
public interface CrossfilterBundle extends JsniBundle {
#LibrarySource("crossfilter.js")
public abstract void initCrossfilter();
}
public abstract static class DCBundle implements JsniBundle {
#LibrarySource("dc.js")
public abstract void initDC();
public void drawBarChart(Widget container, JSONValue data, Properties chartConfig) {
JavaScriptObject dc = JsUtils.prop(window, "dc");
}
}
LayoutPanel layoutPanel = new LayoutPanel();
SimplePanel chartPanel = new SimplePanel();
public ChartDemo() {
D3Bundle d3 = GWT.create(D3Bundle.class);
CrossfilterBundle crossfilter = GWT.create(CrossfilterBundle.class);
final DCBundle dc = GWT.create(DCBundle.class);
d3.initD3();
crossfilter.initCrossfilter();
dc.initDC();
Maybe not a direct answer to your question, but if you want to use d3.js with GWT, there is a wrapper that cover most of the main APIs from d3.js :
https://github.com/gwtd3/gwt-d3
Here's what made it work:
change final assignment statement in d3.js library from
this.d3 = d3;
to
window.d3 = d3;
and change final assignment statement in dc.js library from
this.dc = _dc(d3);
to
window.dc = _dc(window.d3);
I assume this is because of some weirdness around the iframe context that GWT code is executed in, but I'm not totally clear on why it works. I haven't done it yet but I believe that instead of editing the original library you can use the "replace" attribute of the LibrarySource annotation to automate that substitution.

Confused with UiBinder code

I get this code from tutorialspoint.com/gwt as I was learning UiBinder.
Actually I am confused about what does the second line actually does? Why are we using interface name as a ".class" argument in create() function.And what the parameters "widget" and "login" resembles in UiBinder.
The code is:
public class Login extends Composite
{
private static LoginUiBinder uiBinder = GWT.create(LoginUiBinder.class);
#UiTemplate("Login.ui.xml")
interface LoginUiBinder extends UiBinder<Widget, Login>
{
}
}
Every widget that is declared in a template is created by a call to GWT.create().
The UiBinder interface declares two parameter types:
U is the type of root element declared in the ui.xml file, returned by the createAndBindUi call
O is the owner type whose #UiFields are to be filled in.
(In your example U is Widget and O is Login.)
Refer this link

Binding a bean property to a TextField in GXT 3.0

I am working on a ExtGWT 3.0 (beta) application.
I have a simple Java bean containing one property:
public class MyBean {
private String content;
// getter and setter here...
}
I want to bind the property to a TextField.
I have created an interface:
interface MyBeanProperties extends PropertyAccess<MyBean> {
ValueProvider<MyBean, String> content();
}
But what's next? How do I tell the TextField to bind to that particular property of a particular MyBean object?
PropertyAccess is used to generically refer to an objects properties, often for data widgets that use a Store like the grid or charts. For binding a form to a bean, check out GWT's editor framework at http://code.google.com/webtoolkit/doc/latest/DevGuideUiEditors.html. There are some examples for this with GXT at http://www.sencha.com/examples/#ExamplePlace:basicbinding%28uibinder%29
Roughly, you'll build a form widget that wraps all the properties you need, and make an editor driver for that editor and its bean:
public class MyBeanEditor implements Editor<MyBean> {
// do any kind of widget setup you like, just make sure to have methods/fields
// package protected or higher that extends Editor (Field extends Editor)
TextField content;
}
//... declare the driver
interface Driver extends SimpleBeanEditorDriver<MyBean, MyBeanEditor> {}
//... use the driver to bind a form to a bean
Driver driver = GWT.create(Driver.class);
driver.initialize(myBeanEditorInstance);
driver.edit(myBean);
//... when save is clicked (or a timer, or whatever), get the value and do
// something with it
MyBean model = driver.flush();

Simple GWT Editor Example

I'm finding anything other than copying and pasting existing GWT Editor examples to be frustrating. Here's an attempt to create a minimal Editor, without success.
public class ContactEditor extends Composite implements Editor<Contact> {
interface Binder extends UiBinder<Widget, ContactEditor> {}
interface ContactEditorDriver extends
SimpleBeanEditorDriver<Contact, ContactEditor> {}
private final ContactEditorDriver editorDriver;
#UiField TextBox salutation;
public ContactEditor(Contact contact) {
editorDriver = GWT.create(ContactEditorDriver.class);
editorDriver.initialize(this);
editorDriver.edit(contact);
initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this));
}
}
When this is instantiated with
ContactEditor contactEditor = new ContactEditor(new Contact());
I get an UmbrellaException that contains
Caused by: java.lang.NullPointerException: null
at ...ContactEditor_SimpleBeanEditorDelegate.attachSubEditors(ContactEditor_SimpleBeanEditorDelegate.java:12)
at com.google.gwt.editor.client.impl.AbstractEditorDelegate.initialize(AbstractEditorDelegate.java:264)
at com.google.gwt.editor.client.impl.SimpleBeanEditorDelegate.initialize(SimpleBeanEditorDelegate.java:32)
at com.google.gwt.editor.client.impl.AbstractSimpleBeanEditorDriver.edit(AbstractSimpleBeanEditorDriver.java:45)
at ...ContactEditor.<init>(ContactEditor.java
What's going on here---SubEditors? The failure seems to be in generated code and is hard for me to debug.
Much thanks.
By the time you initialize the editor driver, the "salutation" subeditor isn't initialized yet (still null).
Move your createAndBindUi call before the editor init call.