public void onSuccess(String result), from where/how the result is being set? - gwt

I've tried to follow the GWT RPC sample codes, and i don't understand how the AsyncCallback's Onsuccess method result is being set. Anyone help me to understand the flow.
Thanks.

AsyncCallback<YourReturnType> callback = new AsyncCallback<YourReturnType>() {
#Override
public void onSuccess(YourReturnType result) {
//to do something with the result
}
#Override
public void onFailure(Exception ex) {
//to do something with exceptions
}
}

#Rajesh, I'm providing a link here. I hope this may help you.

Related

RecyclerView.Adapter notifyDataSetChanged not working with AsyncTask Callback

I am sure it's just a simple fault, but I'm not able to solve it.
My RecyclerView.Adapter loads its data with help of an AsyncTask (LoadAllPersonsFromDb) out of a SQLite DB. The response is handled by a callback interface (ILoadPersonFromDb.onFindAll).
Here is the code of the Adapter:
public class ListViewAdapter extends RecyclerView.Adapter<ListViewViewholder> implements LoadAllPersonsFromDb.ILoadPersonFromDb {
private int layout;
private List<Person> persons;
private Context context;
private AdapterDataSetListener adapterDataSetListener;
public ListViewAdapter(int layout, Context context,
AdapterDataSetListener adapterDataSetListener) {
this.layout = layout;
persons = new ArrayList<>();
this.context = context;
this.adapterDataSetListener = adapterDataSetListener;
new LoadAllPersonsFromDb(context, this).execute();
}
#Override
public ListViewViewholder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
return new ListViewViewholder(view, context);
}
#Override
public void onBindViewHolder(ListViewViewholder holder, int position) {
holder.assignData(persons.get(position));
}
#Override
public int getItemCount() {
return persons.size();
}
#Override
public void onFindAll(List<Person> persons) {
Log.d("LISTVIEW", "Counted: " + persons.size() + " elements in db");
if (this.persons != null) {
this.persons.clear();
this.persons.addAll(persons);
} else {
this.persons = persons;
}
adapterDataSetListener.onChangeDataSet();
//notifyDataSetChanged();
}
public interface AdapterDataSetListener {
void onChangeDataSet();
}
}
As you can see, I tried more than one way to get it running. The simple notifyDataSetChanged did not do anything, so I made another interface which is used to delegate the ui information to the relating fragment. Following code documents this interface which is implemented in the relating fragment:
#Override
public void onChangeDataSet() {
Log.d("Callback", "called");
listViewAdapter.notifyDataSetChanged();
/*
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
listViewAdapter.notifyDataSetChanged();
}
});
*/
}
Here I also tried to put it on the MainUiThread but nothing works. I'm just not able to see where my problem is. Hopefully any of you guys can give me a hint.
The logging works, which is the prove for the working callbacks.
Thank you in advance.
PS: If you need any more code, just tell me and I will provide it.
instead of using the interface-llistener pattern, try this
#Override
public void onFindAll(List<Person> persons) {
Log.d("LISTVIEW", "Counted: " + persons.size() + " elements in db");
if (this.persons != null) {
this.persons.clear();
this.persons.addAll(persons);
} else {
this.persons = persons;
}
refereshAdapter(persons);
}
public void refereshAdapter(List<Person> persons){
listViewAdapter.clear();
listViewAdapter.addAll(persons);
listViewAdapter.notifyDataSetChanged();
}
To tell the background, I used RecyclerView in Version 23.1.1 because the latest 23.2.0 had some weird behaviour in holding a huge space for each card.
//Update: the problem with the space between cards, was because of a failure of myself in the layout file (match_parent instead of wrap_content). -_-
The upshot was using the latest version again and everything worked just fine. I have no idea why, but at the moment I am just happy, that I can go on. This little problem wasted enough time.
Maybe somebody has a similar situation and can use this insight.
Thx anyway #yUdoDis.

SwipeRefreshLayout error

I am trying to implement swiperefreshlayout and I am getting error at "this"
public class viewBets_activity extends ActionBarActivity {
SwipeRefreshLayout swipeLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewbets);
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
}
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
swipeLayout.setRefreshing(false);
}
}, 5000);
}
}
I am getting error at swipeLayout.setOnRefreshListener(this); screenshot below
Well, now that you added the screenshot, the error is clear.
You're passing the wrong argument into setOnRefreshListener()! And of course, this makes sense, if you think about it. Your class is a ActionBarActivity. You're trying to set the OnRefreshListener as an ActionBarActivity...doesn't make any sense! You need to change your code to this:
swipeLayout.setOnRefreshListener(new OnRefreshListener()
{
#Override
public void onRefresh()
{
// what you want to happen onRefresh goes here
}
});
Here, you're creating a new OnRefreshListener object which you're adding as the listener.
For the future, in general, any time you have a setOn______Listener() method, the argument you'll be passing will be a On_____Listener object that you've customized. You can either created separately, or create it right in the set method the way I did in my answer.
Your class is missing
implement SwipeRefreshLayout.OnRefreshListener
This allows the listener to refer to the overridden method onRefresh when passing through this as the argument for setOnRefreshListener

GWT RPC ClassNotFoundException while initialize AsyncCallback

this isn't my first RPC try. All others worked well, but I can't figure out, why this doesn't.
public void confirmRequest(String requestId, boolean confirmWithDefault, List<String> values, final String laneId){
AsyncCallback<Void> callback = new AsyncCallback<Void>(){
#Override
public void onFailure(Throwable caught)
{
// TODO Auto-generated method stub
}
#Override
public void onSuccess(Void result)
{
Window.alert("jo");
ServiceCalls.this.mainmenu.getSlidePanel().getLaneMenu().getProperLanes().get(laneId)
.getDefaultButton().setText("");
statusFor();
}
};
getLaneProxy().confirmRequest(requestId, confirmWithDefault, values, laneId, callback);
}
When I run the programm, it does not even throw an exception. It just doesn't do what it should do. Then I debugged it and saw that a ClassNotFoundException was thrown at this point.
AsyncCallback< Void> callback = new AsyncCallback<Void>()
Assuming you're using GWT 2.5.0, this is a known issue; upgrade to 2.5.1-rc1 where this is fixed.
I had the same Problem, and found the solution with gridDragon's help.
My problem was that the servlet configuration in web.xml was wrong and so my Impl class couldn't be found.

Decouple GWT Asynchronous callbacks

I have the following problem:
I am trying to model a process using GWT, where i have a couple of views with a couple of submit buttons. And pressing button1 will create a server interaction and if everything was ok, the next view will be loaded. My problem is now that I get really nasty spaghetti code (just very highlevel to show you what i mean):
onClick {
AsyncCallback {
onSuccess {
load new view with another clickhandler and an asynccallback
}
}
}
Is there some way to create some kind of abstraction or something? Maybe a state pattern? How? Thanks a lot!
This is actually a very good question - and probably one without a definitive answer. It's a problem that applies to many frameworks, not just GWT, so I like your idea to look at this with some simplified code. I'll make this a little bit longer, to show what even just 4 very simple callbacks look like:
Nested callbacks
alice.call("a", new Callback() {
#Override
public void onSuccess() {
bob.call("b", new Callback() {
#Override
public void onSuccess() {
charlie.call("c", new Callback() {
#Override
public void onSuccess() {
daisy.call("d", new Callback() {
#Override
public void onSuccess() {
// finished
}
});
}
});
}
});
}
});
Named callbacks
You can use your IDE to refactor this easily into named callbacks (hint: Please read the callbacks from bottom to top!):
final Callback daisyCallback = new Callback() {
#Override
public void onSuccess() {
// finished
}
};
final Callback charlieCallback = new Callback() {
#Override
public void onSuccess() {
daisy.call("d", daisyCallback);
}
};
final Callback bobCallback = new Callback() {
#Override
public void onSuccess() {
charlie.call("c", charlieCallback);
}
};
final Callback aliceCallback = new Callback() {
#Override
public void onSuccess() {
bob.call("b", bobCallback);
}
};
alice.call("a", aliceCallback);
Problem: The control flow is not so immediately obvious anymore.
Still, an IDE can help by using "Search References" (Ctrl-G in Eclipse) or something similar.
Event Bus (or Observer/Publish-Subscribe pattern)
This is how the same calls look like with an event bus:
alice.call("a", new Callback() {
#Override
public void onSuccess() {
bus.fireEvent(BusEvent.ALICE_SUCCESSFUL_EVENT);
}
});
bus.addEventListener(BusEvent.ALICE_SUCCESSFUL_EVENT, new BusEventListener() {
#Override
public void onEvent(final BusEvent busEvent) {
bob.call("b", new Callback() {
#Override
public void onSuccess() {
bus.fireEvent(BusEvent.BOB_SUCCESSFUL_EVENT);
}
});
}
});
bus.addEventListener(BusEvent.BOB_SUCCESSFUL_EVENT, new BusEventListener() {
#Override
public void onEvent(final BusEvent busEvent) {
charlie.call("c", new Callback() {
#Override
public void onSuccess() {
bus.fireEvent(BusEvent.CHARLIE_SUCCESSFUL_EVENT);
}
});
}
});
bus.addEventListener(BusEvent.CHARLIE_SUCCESSFUL_EVENT, new BusEventListener() {
#Override
public void onEvent(final BusEvent busEvent) {
daisy.call("d", new Callback() {
#Override
public void onSuccess() {
bus.fireEvent(BusEvent.DAISY_SUCCESSFUL_EVENT);
}
});
}
});
bus.addEventListener(BusEvent.DAISY_SUCCESSFUL_EVENT, new BusEventListener() {
#Override
public void onEvent(final BusEvent busEvent) {
// finished
}
});
Under the right circumstances (when it's very clear what each event means, and
if you don't have too many), this pattern can make things very nice and clear.
But in other cases, it can make the control flow more confusing (and you easily get twice the lines of code).
It's harder to use your IDE to find out about the control flow.
The GWT History mechanism is a very positive example for where to use this technique reasonably.
Divide and Conquer
In my experience, it's often a good idea to "divide and conquer" by mixing nesting and named callbacks:
final Callback charlieCallback = new Callback() {
#Override
public void onSuccess() {
daisy.call("d", new Callback() {
#Override
public void onSuccess() {
// finished
}
});
}
};
alice.call("a", new Callback() {
#Override
public void onSuccess() {
bob.call("b", new Callback() {
#Override
public void onSuccess() {
charlie.call("c", charlieCallback);
}
});
}
});
Depending on the situation, two nested callbacks are often still readable, and they reduce jumping around between methods when reading the code by 50%.
(I created a pastebin of my examples here, if you like to play around with them: http://pastebin.com/yNc9Cqtb)
Spaghetti code is a tricky problem in GWT as it is in Javascript, where much of your code is structured around asynchronous callbacks.
Some of the techniques to deal with it that are described in the answers to this question could apply.
The suggested approach to avoid coupling between widgets is to use EventBus. Read more details here https://developers.google.com/web-toolkit/articles/mvp-architecture#events
Hope it helps.
changeview(boolean first){
if(first)
{
firstView.setVisible(true);
secondView.setVisible(false);
}else{
firstView.setVisible(false);
secondView.setVisible(true);
}
}
onClick {
AsyncCallback {
onSuccess {
changeView(false);
}
}
}
Switch between views by above.
Use MVP from very beginning. Use Activities and Places. Your code will be clean.

not able to set focus on TextBox in a GWT app

This should not be causing me so much pain but it is. It is a very weird problem. In a GWT application, I have two .java files, login.java and application.java.
In login.java, I'm creating a user login page where if the username and password is verified the user is logged into the application and application.java takes from here.
Now in application. java's onModuleLoad() this is how i'm starting with a login page.
public void onModuleLoad() {
Login login = new Login();
login.textBoxUsername.setFocus(true);
RootLayoutPanel.get().add(login);}
This works great, except for the tiny problem of not being able to set focus on the username TextBox when the page loads. I have tried evrything I can think of. But the focus just doesn't get set on the TextBox. If anyone can suggest a solution, please do. Your help is greatly appreciated.
Solution: (In case it helps anyone facing the same issue)
final Login login = new Login();
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
public void execute () {
login.textBoxUsername.setFocus(true);
}
});
RootLayoutPanel.get().add(login);
Try using Scheduler.scheduleDeferred():
public void onModuleLoad() {
Login login = new Login();
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand () {
public void execute () {
login.textBoxUsername.setFocus(true);
}
});
RootLayoutPanel.get().add(login);
}
Update: answer updated to use Scheduler.get().scheduleDeferred() instead of DeferredCommand, which is deprecated.
Why using DefferedCommand, I think it's better to use someWidget.getElement().focus() which is a native Javascript. I'm using it everywhere, I've not seen any problem.
If your Widget extends Composite, you can:
#Override
protected void onAttach() {
super.onAttach();
textBoxUsername.setFocus(true);
}
It would be so easy for GWT to store a 'wantsFocus' in the internal state, and call focus after the widget is attached. We are still waiting after many years for that feature however...
Still, even after the attach handler is called, setFocus does not always work.
So in the meantime, our GwtUtil library has used the following code. It is a combination of several other solutions, and has been wrapped in a utility function:
static public void setFocus(final FocusWidget focusWidget) {
if (focusWidget.isAttached()) {
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
#Override
public void execute() {
focusWidget.setFocus(true);
}
});
} else {
focusWidget.addAttachHandler(new AttachEvent.Handler() {
#Override
public void onAttachOrDetach(AttachEvent event) {
if (event.isAttached()) {
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
#Override
public void execute() {
focusWidget.setFocus(true);
}
});
}
}
});
}
}
And call it like this:
setFocus(myTextBox);
It makes sense to use a utility function; If and when GWT finally makes setFocus work, you won't have to change your source code in multiple places.