Primefaces Schedule - Extracting data from event - java

After a day of pain I finally got data into the schedule event.
I'm now trying to set event when it's clicked, it loads a new page using the data variable.
Here's the xhtml
<p:schedule id="schedule"
value="#{LeadListScheduleController.eventModel}" widgetVar="schedule">
<p:ajax event="eventSelect"
listener="#{LeadListController.redirectToLeadEdit(Data)}" />
</p:schedule>
And the Java
public void redirectToLeadEdit(String data) throws IOException {
redirect("/lead/" + data + "/edit");
}
How can I get the data object that's now in the event so the url works?

As the showcase explains, there's no need of manually passing the current selected event as an argument to the listener method. Just declare a method where you catch the incoming event and get the data from it. After that, you can call your redirect method with everything you need.
<p:ajax event="eventSelect"
listener="#{LeadListController.onEventSelect}" />
public void onEventSelect(SelectEvent selectEvent) {
ScheduleEvent event = (ScheduleEvent) selectEvent.getObject();
redirect(event.getData());
}
Appart from that and totally unrelated to the problem, I encourage you to name your managed beans as the bean class name with the first letter lowercased. It's a java specification that has been already discussed here.

Related

How to deal with 'cached' instance in #ViewScoped page?

App running with JSF, Primefaces, eclipselink, not a small app, about 100 pages/bean all working perfectly
I got some troubles understanding how my #ViewScoped page works, I got a select UI component, filled with a simple List<People> and a back-end selectedPeople in my bean
// all getters, setters, JPA annotations, all good
public class People {
private String name;
private List<Car> cars;
}
#ManagedBean
#ViewScoped
public class PeopleBean {
#EJB
private Service sPeople;
private People selectedPeople;
private List<People> listPpl;
#PostConstruct
public void init(){
listPpl = sPeople.readAll(); // always good, same as DB values
}
public People getSelectedPeople(){
return selectedPeople;
}
public People setSelectedPeople(People p){ // p is an old element
selectedPeople = p; // BREAKPOINT
}
// getter for the list too
public void method(){
Logger.getAnoymousLogger().severe(selectedPeople.getCars()); // the one the old people, not the ne contained in the actual list
}
}
<p:selectOneMenu id="selectP" value="#{peopleBean.selectedPeople}" converted="#{genericSecuerdConverter}" >
<p:ajax event="change" partialSubmit="true" listener="#{peopleBean.method()}" />
<f:selectItems value="#{peopleBean.listPpl}" var="people" itemLabel="#{people.name}" itemValue="#{people}" />
</p:selectOneMenu>
Sequence of use and problem is (information taken from debugging) :
go to peoplePage.xhtml where the select element is, IDs of the list's element are #410, #411, #412 (3 peoples)
go to modif.xhtml, change the 3rd people (remove a car, saved in DB (check in DB))
come back to peoplePage.xhtml, list is OK, IDs in debug are #650, #651, #652
change the value (from null) of the selectUI to choose a people, and at the breakpoint, p appears to be the #412 element, so the changes on its car's list are not visible, it does not come from the listPpl (because contains only valid elements and corresponds to DB), it's kind of caching
I tried to disable ecpliselink cache as states EclipleLink cache
change eclipselink property
change JPA propery
use #Cacheable(false)
No one had an effect, nor go to private navigation neither clear the browser cache and come back to the page, the p element is still the old one from first loading
I thought #ViewScoped allows to open a page each time as if it was the first time, but seems not, can't figure where the element can be stored/cached
Edit I used a workaround for the moment but this is obviously o the best solution
public People setSelectedPeople(People p){
if(p!=null)
selectedPeople = sPeople.read(p.getId());
}
What you are looking for is #RequestScoped. It will create everything each and every time you do a suitable HTTP request. Otherwise it is not guaranteed to destroy the #ViewScoped beans. An example in the Omnifaces documentation: ViewScoped.
This feature could be used to help the recreation of the page when the user is using the back and forward buttons of the browser for example.
#RequestScoped
Bean lives as long as the HTTP request-response lives. It gets created upon a HTTP request and gets destroyed when the HTTP response associated with the HTTP request is finished.
#ViewScoped
Bean lives as long as the user is interacting with the same JSF view in the browser window/tab. It gets created upon a HTTP request and gets destroyed once the user postbacks to a different view.
Source of descriptions: https://www.tutorialspoint.com/jsf/jsf_managed_beans.htm

updating UI with a volley request from a different class

I am having trouble with volley (again). I want to run a volley request in a class, so more than one activity can feed off its results and update their UI's accordingly. I have got it return data and call the request from the UI but now im struggling to update the UI with the new data. I have looked at answers but I'm trying to understand the structure and I am at a loss, can some please advise/ talk me through it
assuming I understand what you mean as being:
A Volley request returns, updates some data set through some activity
In this case, assuming the calling activity contains everything, and reminding that this is a very general example, what you should usually do (usually, since there are exceptions to the case), is just insert the data into the data set contained in your UI holder (e.g. your recycler adapter) and update it, an example would be your adapter holding a method similar to this:
public void updateDataSet(List<Item> items)
{
//mItemList is the adapters member list
if (null != mItemList)
{
mItemList.clear();
mItemList.addAll(items);
}
else
mItemList = items;
notifyDataSetChanged();
}
you call this inside the request callback you fired earlier, just make sure to initialize everything BEFORE you fire the request, e.g.
#Override
public void onResponse(JSONObject response)
{
Log.d(TAG + ": ", "somePostRequest Response : " + response.toString());
// here you need to parse to JSON to a list and then call...
List<Item> items = parseResponse(response);
myAdapter.updateDataSet(items);
}
Now, if what you meant was
A Volley request returns in some Activity, I want it to update stuff in another place
there are a couple of options:
As someone said in the comments - you could go for EventBus.
You could hold a DataManager class, which would be a global singleton, in which case you can either hold the data and update it there, and then every activity (in it's onResume or other relevant lifecycle method) knows to pull that data.
You could do the same as option 2, with the exception of that DataManager holding a reference to other UI parts (e.g. Fragments), and triggering member methods in them that pass the data and trigger the updates.
Personally I find option 3 cumbersome and somewhat bad practice, but if all else fails, (and it shouldn't, but if it does) then you can try.
There are more options out there, it depends and varies according to the data, your app architecture, coding style and other stuff you apply.
Hope this helps!
You can use EventBus. To use EventBus you need to register class where you will receive update and when you publish event for those event all classes will receive it.
Here is an example using greenrobot's EventBus :
Event Model :
public class MessageEvent {
/* Additional fields if needed */
}
Subscribe :
EventBus.getDefault().register(this); // In Activity onCreate method
#subscribe
public void onMessageEvent(MessageEvent event){
// this is the method to receive event
}
Publish event :
EventBus.getDefault().post(new MessageEvent());
Now every class subscribed for this event model will be updated.
Note : subscribed classes have to alive, If anyone destroyed they won't receive update.

Java EE application and "global" variables

we have a Java EE application with primefaces and we are wondering if there's a way to have a "global" application variable.
I mean: imagine user1 is editing document1, when user2 try to access document1 we'd like to show a message: "User1 is already editing this document".
So, we have to use something "global" for keep track of user action or document locking and so on, what's the best way to achieve this?
I've search the internet but opinion differs and generally no working examples are provided, so link and pointer are welcome!
EDIT: the above is just an example, please not focus on "documents", you can call it "resources", or whatever you like. I've used the document lock problem as an example, but it can be a total counter or something else that need to be stores at application level.
What I'm asking (and sorry if it was not clear) is not how to manage document locking, but what's the best way to have a "global" variable at application level in Java EE, if it's possible.
Thank you
Just curious: why if I add "hola," or "hi," as first line it disappear when I save the edit?
If you want to save something globally, in Java EE 6+ it should use the Application Scope
http://docs.oracle.com/javaee/6/api/javax/enterprise/context/ApplicationScoped.html
For example:
#ApplicationScoped
class Global {
void setDocInUse(boolean) { ... }
boolean isDocInUse() { ... }
}
#RequestScoped
class MyDocEditor {
#Inject Global global;
public void edit() {
if (global.isDocInUse()) { ... }
else { ... }
}
}
For most simple cases you can use a static field inside your managed beans for that purpose because it will be shared by all the instances of your managed bean. For example, let us imagine that to edit documents you users interact with the following bean:
#ManagedBean
#ViewScoped
public class DocumentManager {
private static Map<Long, String> editedDocs = new HashMap<>();
private Document selectedDoc;
}
Then let us imagine that after users have selected the document (for example from the dataTable so that it gets into the selectedDoc field) they get the document editing page by clicking on a button which action attribute points to the method editDocument like this:
then in your editDocument method we add the document's id and username of the user that clicked on the button to the mapping that tracks presently edited documents.
public String editDocument() {
if (!editedDocs.contains(selectedDoc.getId())) {
String username = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal().getName();
editedDocs.put(selectedDoc.getId(), username);
String msg = "User " + username + " is already editing the document";
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg));
}
return theAddressOfEditDocumentPage;
}
Please do not forget to delete the document id and the username from the editedDocs when the user leaves the edit page (by clicking Save or Cancel buttons).
Another possibility is to store such mapping externally (e.g. in the database)

How to get notified about file content changes in NetBeans with DataObject API

I'm trying to implement a NavigatorPanel for my NetBeans module.
Now I would like to always get notified whenever the associated DataObject was modified so that I can invoke the parser and update the navigator.
I tried adding a PropertyChangeListener to the DataObject, but that only notifies me about the first change made to the document and that's it. However, I've noticed that the first time PropertyChangeListener.propertyChange() method is invoked, the propertyName is set to "COOKIE" and the second time to "MODIFIED".
Any ideas on how to always get notified when the content of the document in the editor (not the underlying FileObject!) has changed?
EDIT:
I already looked at http://wiki.netbeans.org/DevFaqListenForSaveEvents. They state that the PropertyChangeListener is used for getting informed about documents being saved (e.g. by Ctrl+S) and if one wants to be notified about modifications to the content, FileChangeListener should be used instead. But that didn't work for me. In either case I don't get notified when I'm modifying the document in the editor, except for when using PropertyChangeListener, then I do get notified, but only the first time I edit something (exactly the opposite as what they write in the FAQ).
EDIT2:
I haven't figured out how to get properly notified yet. But in my case I should have actually approached my goal from a different perspective, i.e. since I want to update the NavigatorPanel based on parsing results, I should probably be registering a ParserResultTask. By that I can define when I should get notified, and when I do get notified I also get the already parsed results I would need for updating the panel.
Well, this is not a direct answer to the actual question but a more suitable solution for this particular problem.
Here is something that works for me. Mind you that an event is fired only when you save your changes. Note that the code below might not compile well as I have deleted my code to make it concise. But it is as simple as implementing FileChangeListener on your DataObject. Geertjan did a blog post on this a while ago. Let me know how it goes.
https://blogs.oracle.com/geertjan/entry/org_openide_filesystems_filechangelistener
public class YourDataObject extends MultiDataObject implements FileChangeListener {
public YourDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {
super(pf, loader);
pf.addFileChangeListener(this);
registerEditor("text/x-puml", true);
}
#Override
protected int associateLookup() {
return 1;
}
#Override
public void fileFolderCreated(FileEvent fe) {}
#Override
public void fileDataCreated(FileEvent fe) {}
#Override
public void fileChanged(FileEvent fe) {
System.out.println("Here =========== :" + fe);
}
#Override
public void fileDeleted(FileEvent fe) {}
#Override
public void fileRenamed(FileRenameEvent fre) {}
#Override
public void fileAttributeChanged(FileAttributeEvent fae) {}
}
EDIT
Nevermind, I forgot you didn't want to deal with FileObject. Here is a netbeans forum post.
http://forums.netbeans.org/ptopic7909.html

wicket onrendered values [duplicate]

1) i have added an element in request object given below, i need to get/read this in my webpage, how can i do it?
<input type="hidden"> wicket:id="submitted" value="false" />
eg: in servlet, use request.getParameter("submitted") from hidden session.
2) in my controller class i want to set the value in session or hidden field, so that i can identify the user if he already processed the request or enetered my block of code.
1) use HiddenField
2) use a custom WebSession object:
public class MySession extends WebSession{
public Mysession(Request request){super(request);}
private boolean completedRegistration;
public boolean hasCompletedRegistration() {
return completedRegistration;
}
public void setCompletedRegistration(boolean completedRegistration) {
this.completedRegistration = completedRegistration;
}
}
I am not sure I have fully understood your questions.
But to make it short, if you want to get the value stored in your request object, you'll need to make the model of your input map to this value (by using HiddenField wicket internal class).
If you want to track your user, the best thing to do is looking around for a cookie set on the client side that'll allow you to manage its visits.
Please refine your question if you want a more precise answer...

Categories