How to refresh other users Vaadin Table without causing Concurrent Modification Exception? - multithreading

Use Case: User logged in and a Vaadin Table component opened showing statuses of appointments. Every row has a drop down (ComboBox) to change status (Scheduled, Arrived, Reviewed). Now multiple users has opened this table in their own browsers and making continuous changes to appointment status. These changes should be reflected on all opened tables i.e if user A changes status of appointment appt-1 it reflects and refresh on all Tables currently opened.
Previously we applied event based refreshing with ICE-PUSH Add-on i.e if Change made on PC-1 (i.e Application instance a1), i get the other instances of Vaadin application from static CopyOnWriteArrayList from MainApplication class and by that instance I call loadTable function. after that I call the ICEPUSH to push new changes to all users.
public class MainApplication extends Application {
public static CopyOnWriteArrayList<MainMedMaxApplication> appList=new CopyOnWriteArrayList<MainMedMaxApplication>();
#Override
public void init() {
setMainWindow(new Window("APPointment Dashboard"));
getMainWindow().setContent(mainLayout);
setMainComponent(getCustomTable());
//Custome Table make table . it also register listeners over table.
//loadTable will load the table.
loadTable()
appList.add(this);
}
}
public void loadTabl(String date) {
//this will reload the table component By Querying database
}
private void registerlistener() {
table.addListeners()
{
//do any change to table in this instance and save it to db then call ICE push so it can referesh all app instances by getting from applist.
synchronizePortlets();
}
}
public void synchronizePortlets() {
// TODO Auto-generated method stub
Iterator<MainApplication>itM = appList.iterator();
while(itM.hasNext()) {
MainApplication app = itM.next();
app.loadTabl();
app.getPusher().push();
}
}
}
This works fine but in some conditions when to many frequent changes made then Concurrent Modification Exception rises. so if any one can help to improve this?
The solution I am thinking after this is to refresh table component not forcefully rather continuously in every 1 mint by its own app instances. This will query database and reload the table container with updated statuses. For this purpose I use Refresher add-on But it raises an exception i.e ConcurrentModificationException, because sometimes user also changing the table component by changing combo statuses in table meanwhile refresher refresh the Table and here raises concurrent Modification exception. So I am thinking of freezing Table component from user point of view so user can't do anything and in background can easily refresh table.
If for this use case you guys have better solution please do tell me. I am grateful of you.
Using Vaadin 6.8.12, java 1.7, apache Tomcat 7.42

Vaadin 6
You need to apply synchronization since you're making changes to the GUI from another thread (and I think it doesn't matter whether Refresher or IcePush is used, I think in both cases you'll use another thread). Synchronize on the Application instance.
See this post on the Vaadin forum.
Vaadin 7
EDIT: I encourage you to upgrade to Vaadin 7.1 and use this new method on UI: UI#access as is recommended here.

Related

Windows 10 IoT Core, Sharing SPI data

My windows 10 IOT core application uses SPI to collect change notifications of
many entities. There are excellent examples for launching a timer to get SPI data, update data and binding UI elements to this data. The result is anytime SPI gets some data about a changed entity, the data that drives the UI is updated and any UI element bound to this data is updated. I can even change what subset of data is displayed on this page by using two way bindings to track the selected items on a list.
Just like the many examples, my code is structured as follows:
public async void Init_SPI()
{
....
periodicTimer = new Timer(this.TimerCallback, null, 0, 10);
} // public async void Init_SPI()
private void TimerCallback(object state)
{
/* UI updates must be invoked on the UI thread */
var task =
this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{ ... update states of data that many be bound to UI element
My issue / question:
I don't see how to update data for multiple pages based on the above, since this.variable refers to the UI thread of the page that launched the timer.
It would be too inefficient to update a static class and have the multiple pages continuously poll this static data to make the UI track these large number of element.
My only thought at present is to code all the XAML pages in one page and tab between these "virtual" pages. I would rather have multiple pages to keep the functionality of these pages separated.
Any suggestions for how I could update multiple pages from data read on a SPI port would be appreciated.
Regards,
John
Sorry for a very late answer, but my solution would be to still create "real" pages -- but "relayed" the data only to the currently visible page. So whenever a page becomes visible I would have made the internals of the code piece above { ... update states of data [...] to point out that page.
This could be achieved with a simple switch statement, or by a simple interface with a HandleSpiData(TheSpiData) method -- or even a simple Action<YourSpiData>.

Warn the user that he is about to loose his change in Edit view when leaving to view to another in GWT

I want to prevent the user that he will loose his changes in an EditView when changing the view to another.
I use MVP4G in my project and the project is divided as mvp's structure (one package for the template another one for views ..) is there any solution to detect the EditView in the eventBus. or detect the current View shown to user
Thanks in advance
Thanks to the Navigation Event feature in mvp4g, the presenter will get control before the view changes. At this point the presenter can decide if the navigation will be done or not. This is the correct place in a mvp4g application to save your data.
First zu have to mark all events in the eventbus that will change your view with:
#Event(..., navigationEvent = true)
void goToPage1();
Next your presenters have to implement the NavigationConfirmationInterface and the requires confirm-method:
public class Presenter extends ... implements NavigationConfirmationInterface {
public void confirm(NavigationEventCommand event) {
//pseudo method to verify if the view has changed
if (isViewModified(){
//Window shouldn't be used inside a presenter
//this is just to give a simple example
if (Window.confirm("Are you sure you want to leave?")){
event.fireEvent();
}
} else {
event.fireEvent();
}
}
}
And the last thing to do, is to set the presenter of the current view to the confirmation presenter by calling:
event.fireEvent(false);
This is usually done when the presenter gets control.
You will find the documentation here:
https://github.com/FrankHossfeld/mvp4g/wiki/03.-Defining-EventBus#navigation-event
Thanks to MVP4G's team including El Hoss who gives me a hint to check the MVP4G's blog.. I've solved my problem by following this example
http://mvp4g.blogspot.com/2011/06/navigation-control.html

xpages: is it possible to trap when user logs in?

I am writing an app in which the end user can mark documents as his favourites. I already have the necessary forms and views to save and read back the favorites, but I have one little problem: all is done in the back end (the favorites are displayed from a view, not a scoped variable) and there seems to be a sync issue between the click on the "add to favorites" link and the partial refresh that reloads the favorites: the newly added document only shows after a second refresh. No problem then, I then decided to move the favorites in a managed bean I already have for the session where I keep the language and other user's prefs.
The problem I now face is this: how can I trap the login event so I can build the favorites list in the bean? I looked at how the "xInvolve" control's favorite piece was built and I found that there is some code added to the custom control's beforePageLoad event. But I'm wandering if there's a better way of doing this. If I go that way, this means that each time a page loads, it will go in my session bean to look if it needs to build the favorites list. I feel it's a bit of an overload: I'd rather build the list once, when the user logs in.
Is that possible or I should keep the beforePageLoad code just as it is now? Any ideas/thoughts are appreciated.
Note this does NOT actually trap the login.. I'm not sure how to do that exactly but I'm not sure it's nexessary..
Just thinking out loud here.. but I would try this..
Assume you have a "UserObject" to hold the favorites for the user.. then the object gets loaded it reads them in etc...
What about an "App Bean".. a managed bean in app scope... basically a factory for your application... inside the AppBean you have a Map... so that's an easy way to get a hold of the userobject anytime and it lives throughout the app scope...
Now on each page.. you try to grab the UserObject... if it doesn't exist.. you load it once into the App Bean so it's there for later... if it exists.. it's already loaded... you then update the UserObject when the user adds/removes a favorite... make sure to go through the object in the app bean to keep it updated...
An advantage of this is if the user opens another browser or tab.. it all pulls from the AppBean...
Give that some thought and let me know if you need any help...
Also note: This is a java solution... it might be workable in SSJS though..
A standard login page is HTTP only, not XPages. HTTP identifies that a login is required, validates credentials, checks the URL that you're redirecting to exists and only then does the XPages runtime take over.
If you want to trap login, you need to have an XPage making an AJAX request to do the login.
You might want to have a look at XPages Help Application on OpenNTF. I built a favouriting function into that. Favourites are stored in the person's profile, but for the duration of the session held in memory in a Map. The person's profile is created with the hashed value of the username. There is a potential issue with renames, but that's not a significant issue.
You could use a SessionListener. In the sessionCreated method you can calculate the List and initialize your session scoped bean:
public class MySessionListener implements SessionListener {
public void sessionCreated(ApplicationEx arg0, HttpSessionEvent event) {
FavBean bean = new FavBean();
// create the favorites List
// and push it to your bean
// add the bean to session scope
event.getSession().setAttribute("favBean", bean);
}
public void sessionDestroyed(ApplicationEx arg0, HttpSessionEvent event) {}
}

Binding changes in model reflect in TableView only after column resizing

First example work fine, if you run the next code you will see table.
Selected row is reflected in text field.
After saving changes their immediately reflecting in tableview due model properties to table cell binding.
In the second sample
after double clicking table view is hiding and edit form opened.
But after saving changes their reflect in table view only after column resizing.
How to fix this issue?
The issue appears to be that the TableView is not updated because it is not part of the Scene graph when the property is changed. (This would be a bug.) It does work fine in JavaFX8 (though you need to modify your code to ensure that the FX Nodes are initialized on the FX Application Thread; i.e. in the initComponents() method).
For a (fairly ugly) workaround to make this work in JavaFX 2.2, try the following:
private void openTable() {
Platform.runLater(new Runnable() {
#Override
public void run() {
table.setItems(FXCollections.<Person>observableArrayList());
vbox.getChildren().setAll(label, table);
table.setItems(data);
}
});
}
(I streamlined your existing code a little; also, the code you posted doesn't need a Platform.runLater(...) here as openTable() is only invoked from the FX Application Thread. However, this may be different in your real application.)

GXT custom event handler code executes multiple times

I have implemented MVP pattern in my GXT project. The system registers customers as part of it function. Also the system user can search for the registered user providing the id.
i have added an OnClick event to the "search customer" button.
/* On click search button */
view.getBtnSearch().addListener(Events.OnClick, new Listener<BaseEvent>() {
#Override
public void handleEvent(BaseEvent be) {
eventBus.fireEvent(new CustomerRegistrationTabSelectionEvent(0, false));
eventBus.fireEvent(new CustomerFetchEvent(view.getValueCustSearchParameter(), view.getValueCustSearchValue(), true));
}
});
The CustomerRegistrationTabSelectionEvent does select the relevant tab and enables other tabs. Thats all it does.
Here is the handler for the custom event CustomerFetchEvent.
eventBus.addHandler(CustomerFetchEvent.TYPE, new CustomerFetchEventHandler() {
#Override
public void fetchCustomer(CustomerFetchEvent event) {
searchCustomer(event.getParameter(), event.getParameterValue(), event.isOpenFirstTab());
}
});
The issue is the search customer method is executed multiple times and if there is a invalid search the error message dialog shows multiple popups. Within the searchCustomer method i call for service which fetch me the customer data or show the popup error message if the search is invalid.
im using GXT 2.2.5 and JRE 1.6.
Could anyone help me in finding out why the code is executed multiple times?
Added Later:
When i run the application first time the code is only executed only once, therefore only 1 popup. Then i logout of the system and log in again (navigating to the same page where the "search customer" button exists.) and the code is executed twice. Likewise equal to the number of times i create/navigate to the particular page, the code executes. Is it actually adding the event handler code without removing the last one every time i recreate the page?
Yes, it seems that 'addHandler' adds handler multiple times, but stores previous context. Your code should add handlers only once, on initialization phase. You can check the number of handlers with 'getHandlerCount' method.
Ya. I fixed it!Here is the solution Unbinding presenters necessary in GWT
U can read more here. http://draconianoverlord.com/2010/11/23/gwt-handlers.html
what happened actually was, the presenter objects where i have registered with HandlerManager to receive events were not garbage collected. Because though i remove the reference to the presenters still the HandlerManager holds a reference to those objects. So every time i kept on creating new presenters on top of the old presenters of the same class. so a event is listened by multiple objects of the same class. so u need to ensure that the unused presenters are garbage collected by removing the registered handlers
in HandlerManager.

Resources