how to instantiate a java class from within JSNI - gwt

I'm trying to instantiate a java type inside a JSNI method body, using the JSO's package-private's ::new() method, but all instances are returned as null handles.
how come?
Is it possible to instantiate the class using a similar syntax to Java?
Here is the relevant code:
public class OnChangeHandlerJso extends JavaScriptObject {
protected OnChangeHandlerJso() {};
public static native JavaScriptObject create() /*-{
return function(cm, changeInfo) {
var eventBus = #com.gigaspaces.codemirror_gwt.client.events.EventUtils::CODE_MIRROR_EVENT_BUS;
var event = #com.gigaspaces.codemirror_gwt.client.events.EditorContentChangeEvent::new()();
// could something like this work?
// var event = new #com.gigaspaces.codemirror_gwt.client.events.EditorContentChangeEvent;
event.#com.gigaspaces.codemirror_gwt.client.events.EditorContentChangeEvent::setCm(Lcom/gigaspaces/codemirror_gwt/client/jsni/CodeMirrorJso;)(cm);
event.#com.gigaspaces.codemirror_gwt.client.events.EditorContentChangeEvent::setChangeInfo(Lcom/gigaspaces/codemirror_gwt/client/jsni/ChangeInfoJso;)(changeInfo);
eventBus.#com.google.gwt.event.shared.EventBus::fireEvent(Lcom/google/gwt/event/shared/GwtEvent;)(event);
};
}-*/;
}

Solved like this:
The overlay type
public class OnChangeHandlerJso extends JavaScriptObject {
protected OnChangeHandlerJso() {};
public static native OnChangeHandlerJso create() /*-{
return function(cm, changeInfo) {
#com.gigaspaces.codemirror_gwt.client.vo.OnChangeHandler::handle(Lcom/gigaspaces/codemirror_gwt/client/jsni/CodeMirrorJso;Lcom/gigaspaces/codemirror_gwt/client/jsni/ChangeInfoJso;)(cm, changeInfo);
};
}-*/;
}
The handler
public class OnChangeHandler implements JsoWrapper<OnChangeHandlerJso> {
public static void handle(CodeMirrorJso cmJso, ChangeInfoJso changeInfoJso) {
// ...
EventUtils.CODE_MIRROR_EVENT_BUS.fireEvent(new EditorContentChangeEvent(cm, changeInfo));
}
}

Related

What is the difference between a private static function vs. a public static function in typescript?

In the context of an angular2 service; what is the difference between a private static function vs. a public static function in typescript?
public static getUserStockList(): Stock[] {
/* TODO: implement http call */
return WATCHLIST;
}
vs.
private static getUserStockList(): Stock[] {
/* TODO: implement http call */
return WATCHLIST;
}
EDIT:
When would it be appropriate to use a private static function over a private function?
Private static methods can be invoked from instances of the class.
An example of this:
interface Data {
// ...
}
interface StrictData {
// ...
abstract class MyClass {
protected constructor(data: StrictData) {
// ...
}
}
class AnotherClass extends MyClass {
private static normalizeData(data?: Data | StrictData): StrictData {
// ...
}
constructor(data?: Data | StrictData) {
super(AnotherClass.normalizeData(data));
}
}
AnotherClass.normalizeData is accessible from the instance and the compiler is just fine with this.
However, this:
console.log(AnotherClass.normalizeData({}));
Will result in:
Property 'normalizeData' is private and only accessible within class
'AnotherClass'

Why does my sub-dependency not get set in Dagger?

I am having a hard time figuring out how to inject CachedRithms into my RithmioManager and CachedKamms into my KamilManager?
I have the following files:
AppScopeModule:
#Module
(
library = true,
complete = false,
injects = {
KamilApplication.class,
KamilManager.class
}
)
public class AppScopeModule {
/* package */ static Context sApplicationContext = null;
private final Context mApplicationContext;
AppScopeModule(Context applicationContext) {
KamilManager.initInstance(applicationContext);
mApplicationContext = applicationContext;
}
#Provides
#Singleton
KamilManager provideKamilManager() {
return KamilManager.getInstance();
}
}
KamilApplication:
public class KamilApplication extends Application implements Injector {
private ObjectGraph mObjectGraph;
#Inject
KamilManager KamilManager;
#Override
public void onCreate() {
super.onCreate();
AppScopeModule sharedAppModule = new AppScopeModule(this);
// bootstrap. So that it allows no-arg constructor in AppScopeModule
sharedAppModule.sApplicationContext = this.getApplicationContext();
List<Object> modules = new ArrayList<Object>();
modules.add(sharedAppModule);
modules.add(new AuthModule());
modules.addAll(getAppModules());
mObjectGraph = ObjectGraph.create(modules.toArray());
mObjectGraph.inject(this);
}
}
KamilManager
public class KamilManager {
#Inject
CachedKamms mCachedKamms;
private static KamilManager instance;
private boolean mWearIsConnectedToMobile;
private KamilManager() {
Log.d(TAG, "KamilManager private constructor");
}
public static void initInstance(Context appContext) {
if (instance == null) {
instance = new KamilManager();
.....doing more things here...
}
}
public static KamilManager getInstance() {
return instance;
}
}
But mCAchedKamms is always blank when I initialize the app. Any idea what I'm doing wrong?
You need to call ObjectGraph.inject(this) somewhere in KamilManager.
I suggest you to add this code to your KamilApplication class:
public ObjectGraph getObjectGraph() {
return mObjectGraph;
}
After that you need to somehow get instance of KamilApplication(pass it via constructor maybe?) in KamilManager and call:
kamilApplication.getObjectGraph.inject(this);
after this call every field in class KamilManager annotated with #Inject should be injected.
OR
Just annotate constructor of CachedKamms with #Inject
Extra:
Avoid of using library = true and complete = false unless you know what are you doing. With this settings you disable some validations at compile time.

Custom Renderer in GWT

I'm trying to create a widget that will render its associated value in a format that is not the same as the native value. For example, if the value (in the database) is "abcde" I want to show "ab.cd.e" on the screen, and if the user types "abcde" I would also want to show "ab.cd.e". If the user types "ab.cd.e" then I would want to store just "abcde" in the database. I am doing this within the GWT editor framework. I have attempted to use the advice from this answer: Converting String to BigDecimal in GWT, but I can't get it to work. Here's what I have in the UiBinder file:
<g:TextBox ui:field='myTextBox' width='300px'/>
And in the associated Java unit:
#UiField
TextBox myTextBox;
...
initWidget(binder.createAndBindUi(this));
new MyValueBox(myTextBox);
And here's the definition of the MyValueBox widget:
public class MyValueBox extends ValueBox<String> {
//=========================================================================
public static class MyRenderer extends AbstractRenderer<String> {
private static MyRenderer _instance;
private static MyRenderer instance() {
if (_instance == null) {
_instance = new MyRenderer();
}
return _instance;
}
#Override
public String render(final String text) {
// validation is required before doing this!
return text.substring(0, 2) + "." + text.substring(2, 4) + "."
+ text.substring(4);
}
}
//=========================================================================
public static class MyParser implements Parser<String> {
private static MyParser _instance;
private static MyParser instance() {
if (_instance == null) {
_instance = new MyParser();
}
return _instance;
}
#Override
public String parse(final CharSequence text) throws ParseException {
return "parsed string";
}
}
//=========================================================================
public MyValueBox(final TextBox valueBox) {
super(valueBox.getElement(), MyRenderer.instance(), MyParser.instance());
}
}
As you can see, I'm trying to wrap the TextBox that was created using UiBinder, but I don't see any effect from this. I know that I'm missing something very simple, and that there is a much easier way to accomplish this, but I'm stumped. Thank you for any suggestions!
--Edit--
I eventually decided to use a CellWidget, which had the added advantage that I can use this code in a cell widget (e.g., a DataGrid), in addition to using it on a panel. I have documented my solution here: GWT: A Custom Cell Example
You are missing to declare your custom Widget in the UIBinder. You need to tie the package to the xml declaration, adding yours to the standard one (called 'g'):
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui' xmlns:myurn='urn:import:mypackage'>
Then you should use your declared urn, and the name of your class when declaring your TextBox in the UIBinder:
<myurn:MyValueBox ui:field='myTextBox' width='300px'/>
======EDIT=====
You should extend ValueBoxBase instead of wrapping TextBox, that way you will get control over the Renderer and the Parser as you intend, now you will be able to use your custom box as a widget from within the UIBinder:
public class CustomText extends ValueBoxBase<String>
{
public CustomText() {
super(Document.get().createTextInputElement(),CustomRenderer.instance(),
CustomParser.instance());
}
private static class CustomRenderer extends AbstractRenderer<String>
{
private static CustomRenderer INSTANCE;
public static CustomRenderer instance() {
if (INSTANCE == null) {
INSTANCE = new CustomRenderer();
}
return INSTANCE;
}
#Override
public String render(String text)
{
return "rendered string";
}
}
private static class CustomParser implements Parser<String>
{
private static CustomParser INSTANCE;
public static CustomParser instance() {
if (INSTANCE == null) {
INSTANCE = new CustomParser();
}
return INSTANCE;
}
#Override
public String parse(CharSequence text) throws ParseException
{
return "parsed string";
}
}
}

GWT Extending the Constants Interface

I'm using the GWT's Constants Interface. i have an instance class class that create a Java instance of MyConstants using the GWT.create(Class) facility, and then hold it, for the use of other.
public class LocaleMsgReader {
private static LocaleMsgReader INSTANCE = new LocaleMsgReader();
private static ErrorMessages errorMessages;
private LocaleMsgReader () {
}
public void init (){
errorMessages = (ErrorMessages) GWT.create(ErrorMessages.class);
}
public ErrorMessages getErrorMessages() {
return errorMessages;
}
public static LocaleMsgReader getInstance() {
return INSTANCE;
}
}
on the init method the it create the java instance, but when i calling the method getErrorMessages(), i get null.
why?
You're making a singleton instance for LocalMsgReader so make errorMessages a instance variable instead of a class variable by removing static, and instantiate it in the constructor.
public class LocaleMsgReader {
private static LocaleMsgReader INSTANCE = new LocaleMsgReader();
private ErrorMessages errorMessages;
private LocaleMsgReader () {
this.errorMessages = (ErrorMessages) GWT.create(ErrorMessages.class);
}
public ErrorMessages getErrorMessages() {
return errorMessages;
}
public static LocaleMsgReader getInstance() {
return INSTANCE;
}
}

Gwt - How can I "cast" a overlay (JavaScriptObject) into a real Java object?

In my GWT project, I really need to implement the same interface between several overlays (JavaScriptObject).
According to the documentation :
Starting with GWT 2.0, it is permissible for JavaScriptObject subtypes to implement interfaces. Every method defined in an interface may map to at most one method declared in a JavaScriptObject subtype. Practically speaking, this means that only one JavaScriptObject type may implement any given interface, but any number of non-JavaScriptObject types may also implement that interface.
So, I would like to "cast" my JavaScriptObject to a real Java object. It allows me to reduce considerably a lot of duplication code.
Is it possible ?
Thanks.
How about creating classes that wrap a JSO instead of inherting it?
public class PersonJso extends JavaScriptObject{
protected PersonJso() {}
public static native PersonJso create(String name) /*-{
return {name : name};
}-*/;
public final native String getName() /*-{
return this.name;
}-*/;
}
public class AnimalJso extends JavaScriptObject{
protected AnimalJso() {}
public static native PersonJso create(String name) /*-{
return {name : name};
}-*/;
public final native String getName() /*-{
return this.name;
}-*/;
}
public class AnimalWrapper implements hasName{
AnimalJso jso;
public AnimalWrapper(){}
public AnimalWrapper(AnimalJso jso){
this.jso = jso;
}
#Override
public String getName() {
return jso.getName();
}
}
public class PersonWrapper implements hasName{
PersonJso jso;
public PersonWrapper(){}
public PersonWrapper(PersonJso jso){
this.jso = jso;
}
#Override
public String getName() {
return jso.getName();
}
}