I have page with grid. I am loading data through service to grid. Loading and computing all data takes about 20-40 seconds. When I press button to get data, page start loading (classical in vaadin top loading indicator start loading).
My question is, how can I stop loading/waiting for data?
I can't stop searching process on that server I am getting data from, it dont have this functionality, I can only request for data, and wait for them.
Should I stop some thread? should i use something like this.getUI... and somewhere here stop it?
I am using vaadin 7.7.4
Thank you :)
You should use threads for this.
You will need to separate your logic, that the main thread does add all components to the UI.
This thread then also needs to spawn a new thread which does fetch the data and then updates the UI accordingly.
To update the UI once the data has been fetched from the backend you will need to activate push in your UI.
Don't forget to synchronise thread access to the UI with something like:
ui.access(new Runnable() {
#Override
public void run() {
...grid_update_with_new_data... ;
}
});
The fetching of the data should occur outside the ui.access method, otherwise your UI will freeze during backend data loading.
See this post for more technical details
Using Thread with Vaadin? and https://vaadin.com/docs/v7/framework/advanced/advanced-push.html
#André Schild This is simplified code. When I hit search button, app start searching, no problem with that. Problem is how to STOP searching, before its done. Enough for me is to stop waiting for response, and stop loading bar at top of the page, but I dont know how to achive this.
#SpringComponent
#UIScope
#Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DistraintSearchComponent extends CustomComponent {
#Autowired
private Service service
private Button searchButton = new Button("Search");
public void init(){
searchButton.addClickListener(new ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
List<Results> results = service.findByFilter(filter);
refreshGrid(results);
}
});
}
}
Related
I want to append some log strings to a textArea in my vaadin app.
VaadinSqlApplication.logger.info("Export start");
logTextArea.setValue("Export Start");
...
logTextArea.setValue("Export done");
but the textArea only changed after the whole function ended.
Is there any function like in JavaFX :
Platform.runLater(new Runnable() {
#Override
public void run() {
//change text
});
or in swing :
EventQueue.invokeLater(changer);
You need to enable "push" on the Vaadin UI, as by default all updates to the UI will be grouped and sent as a single response (like you say: when the function returns).
Have a look at this page, it explains the whole setup very nicely:
https://vaadin.com/docs/v8/framework/advanced/advanced-push.html
BTW, once push is enabled, you will need a similar technique as the SwingUtilities.invokeLater that you mentioned:
Making changes to a UI object from another thread and pushing them to
the browser requires locking the user session when accessing the UI.
Otherwise, the UI update done from another thread could conflict with
a regular event-driven update and cause either data corruption or
deadlocks. Because of this, you may only access an UI using the
access() method, which locks the session to prevent conflicts. It
takes a Runnable which it executes as its parameter.
For example:
ui.access(new Runnable() {
#Override
public void run() {
...
}
});
I want to restart my service with new data, what allows me to release every objects in service without making complicated communication between Fragment<>Service.
I tried this, everything works:
if(isMyServiceRunning(PlayerService.class))
{
getActivity().stopService(intenx);
positionTemp--;
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
getActivity().startService(intenx);
positionTemp++;
}
}, 500);
}
else{
getActivity().startService(intenx);
}
}
});
But I don't know if I should to worry about closing time in different devices? Is there possibility than service will be closing longer than 500ms? My Motorola takes 300ms to close service and then I can re-run it without problem.
Any advice? Communication with service isn't really easy, it's music player with almost 15 different controls, etc. I think that the easiest way is just stop current service and restart with new entry variables.
That seems unnecessary, and it'll add a 500 ms lag to any user actions. A Service can accept multiple intents without stopping and starting again. Just handle each new intent in onStartCommand(). You don't need any complicated communication between the fragment and service; the fragment just needs to forward every request to the service and let the service do its thing. Although for a better UI you might need to bind to the service so it can update the UI based on the service's state.
my Activity shows to the user some data, which are download from a web server. Data could change over the time, so the web server communicates new updates to the connected clients.
So the work of my application is basically this:
while ( true ) {
wait for updates;
update the UI;
}
This code could run forever, and during its life it should update the UI many times.
What class should I use to implement this code?
Thread or Runnable seems the easiest solutions to my problem, but how could I comunicate to the UI thread?
onServerChangesListener... refresh UI
public void serverStateWrappr(){
Handler messageHandler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
_localstr = getStuff((String) msg.obj)
updateAdapter(_localstr)
}}
from the thread which has a handleRef ...
while (onChangesForClient) {
Message msg = Message.obtain();
msg.what=1;
msg.obj=newData;
//TODO this is the comment for UI
mhandleRef.sendMessage(msg);
}
}
You should probably go with an asyncTask, calling runOnUiThread when you need to update the UI. Have a look to this question to see how activity.runOnUiThread() should be used
IMHO AsyncTask is preferrable, because it gives you more fine-grained control over your background task via onPreExecute(), onPostExecute()
I'm a Fedora user currently making use of inotify-java to implement directory polling. I have the following code snippet:
InotifyEventListener inel = new InotifyEventListener() {
#Override
public void filesystemEventOccurred (InotifyEvent ine) {
// code to handle - done
}
#Override
public void queueFull (EventQueueFull eqf) {
// this is the part when I'm not sure what I should do
}
}
You should perform the recovery actions specific to your application.
The "queue full" event happens if you're not retrieving events fast enough. Excess events are dropped, but you're notified of this.
You should think what would be the consequences for your application if you miss an event or two, and plan the recovery actions (e.g. clean the queue fast and do the rescan of the directory).
To exchange data between apps I have created 2 applications, one is a UI application and the other is a background application, by setting an alternate entrypoint
I was able to find a similar question but was not able get the help I need there
I am able to create Global Events and a Global Listener,
but my problem is how to transfer Data from one application to another.
In UI APPLICATION we can post globalEvent
ApplicationManager.getApplicationManager().postGlobalEvent(0xba4b84944bb7);
In Background Application we can Listen and send the Acknowledgement
public void eventOccurred( long guid, int data0, int data1, Object object0, Object object1)
{
//Is this the GlobalEvent we are waiting for?
//Long = com.samples.globalEventFiring.GlobalEventListening
if (guid == 0x7d3a74a5ccfe6483L)
{
//Yes it is.
System.out.println("Acknowledgement received.");
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Event was fired and acknowledged.");
}
});
}
}
But how to transfer data from background application to ui application.How UI application can access data or objects of background application.
you can use Runtime storage as a central location to share your data between background and UI thread.
You can use the int and Object arguments in the event system to pass data between the application instances. When posting the event, use the postGlobalEvent overload that takes ints and Objects. And in the event handler, downcast object0 or object1 as necessary.