In my App (Fusion Web) exist a ViewObject from Oracle DB.
I created the java classes and build a specific method (makeUniqueSearchByDate(String)) to process the data.
This method appears in "Data controls" that I can drag to the "view" and use as any other function. When I try to use it in a "bean" (instead of dragging directly):
public void setDate(ActionEvent actionEvent) {
ApplicationModule appMod =
Configuration.createRootApplicationModule("com.svr.model.AppModule", "AppModuleLocal");
ViewModelosByDataImpl fo = (ViewModelosByDataImpl) appMod.findViewObject("ViewModelosByData1");
String dateV = "07-01-2013";
fo.makeUniqueSearchByDate(dateV);
}
This code has no effect on the table. Can anyone see why?
Btw, the program does not throw any exception. Just does not work. The table remains the same. But if I use the button, automatically generated by "drag and drop" the function runs normally. I know I should study ADF, but unfortunately I have no time.
i think after you have exposed the method written at VO as Client interface, you need to create a method binding in pageDef file of you page. after creating the method binding, you need to access the method in bean through binding layer something like this :
OperationBinding op=((DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry()).getOperationBinding("Method Binding");
op.execute();
i think the method used by you to call VO method from bean is not right.
i think one more thing you need to do in your bean after calling the VO method is that you need to do refresh the table / perform PPR programatically :
AdfFacesContext adfFacesContext = AdfFacesContext.getCurrentInstance();
adfFacesContext.addPartialTarget(component binding for your table component);
you can try setting autosubmit to true for command button which invokes action event, and set partial trigger for table to component id of the command button.
can you post VO method code as well ?
does the method get called and data gets committed / updated when you execute it through bean ? is it only a table refresh issue ? do you see changes to data if you manually refresh the page ?
Related
I've searched several times here for answer but didn't get my solution.
In my case:
I want to take input from user and check validity. If everything is fine I will grab users ID from database and send that ID to another FXML and then run a select query there using that ID and display the results into a tableView.
In 2nd FXML (controller) I am using initialize() method to set data into tableView and a setId() method to receive user ID from previous FXML. But, initialize() method get called before setId() method and doesn't provide my required result as the ID is null.
Used Passing Parameters JavaFX FXML this method form passing data between FXML.
What will be the best solution for this?
FYI: Currently I'm using an extra class with static variable to store ID.
You could use a controller factory that initializes the id before it returns the controller instance:
FXMLLoader loader = new FXMLLoader(url);
loader.setControllerFactory(c -> {
MyController controller = new MyController();
controller.setId(userId);
return controller;
});
...
Node n = loader.load();
This way you could also use classes as controllers, that don't provide a default constructor. A more complex controller factory could be used to connect model and presenter (see MVP).
An alternative would be to modify the scene's contents in the setId method instead of the initialize method, which would be simpler than using a controller factory.
What the best solution is depends on your needs and personal preference. However, using a static member to pass data should be avoided, if possible.
I'm following the example from the GXT website here: http://www.sencha.com/examples/#ExamplePlace:paginggrid
Their code creates an RPCProxy, overrides load() to make an RPC call to get data and then I assume the listStore is populated in the callback that isn't provided in the example.
Question:
I want to populate the grid with search results so I want the fetching and loading of data to be done in response to sone button select event. I don't want to load the grid with data when it's created. I can't figure out how to refactor this example to do that.
I want to populate the grid with search results so I want the fetching and loading of data to be done in response
Just make sure you override the load method of RpcProxy class correctly, it will make an RPC call to your servlet and pass the search criteria, then receive the appropriate data.
I don't want to load the grid with data when it's created.
The RpcProxy object was passed to loader constructor, which mean the one controlling the RpcProxy object was the loader object. The grid by default was never loaded with data when it was created (unless we add the code to do that). The data was loaded everytime the method load of loader object was called, not when the object of loader or RpcProxy or even Grid object was created.
Finally, here is some example code to search data using RpcProxy :
RpcProxy<PagingLoadConfig, PagingLoadResult<Post>> proxy = new RpcProxy<PagingLoadConfig, PagingLoadResult<Post>>() {
#Override
public void load(PagingLoadConfig loadConfig, AsyncCallback<PagingLoadResult<Post>> callback) {
service.getPostsBySearchCriteria(loadConfig, searchCriteria, callback); // make sure your rpc service receive search criteria parameter
}
};
Hope this could help you :-)
I have been wrestling with this problem for a while. I would like to use the same Stripes ActionBean for show and update actions. However, I have not been able to figure out how to do this in a clean way that allows reliable binding, validation, and verification of object ownership by the current user.
For example, lets say our action bean takes a postingId. The posting belongs to a user, which is logged in. We might have something like this:
#UrlBinding("/posting/{postingId}")
#RolesAllowed({ "USER" })
public class PostingActionBean extends BaseActionBean
Now, for the show action, we could define:
private int postingId; // assume the parameter in #UrlBinding above was renamed
private Posting posting;
And now use #After(stages = LifecycleStage.BindingAndValidation) to fetch the Posting. Our #After function can verify that the currently logged in user owns the posting. We must use #After, not #Before, because the postingId won't have been bound to the parameter before hand.
However, for an update function, you want to bind the Posting object to the Posting variable using #Before, not #After, so that the returned form entries get applied on top of the existing Posting object, instead of onto an empty stub.
A custom TypeConverter<T> would work well here, but because the session isn't available from the TypeConverter interface, its difficult to validate ownership of the object during binding.
The only solution I can see is to use two separate action beans, one for show, and one for update. If you do this however, the <stripes:form> tag and its downstream tags won't correctly populate the values of the form, because the beanclass or action tags must map back to the same ActionBean.
As far as I can see, the Stripes model only holds together when manipulating simple (none POJO) parameters. In any other case, you seem to run into a catch-22 of binding your object from your data store and overwriting it with updates sent from the client.
I've got to be missing something. What is the best practice from experienced Stripes users?
In my opinion, authorisation is orthogonal to object hydration. By this, I mean that you should separate the concerns of object hydration (in this case, using a postingId and turning it into a Posting) away from determining whether a user has authorisation to perform operations on that object (like show, update, delete, etc.,).
For object hydration, I use a TypeConverter<T>, and I hydrate the object without regard to the session user. Then inside my ActionBean I have a guard around the setter, thus...
public void setPosting(Posting posting) {
if (accessible(posting)) this.posting = posting;
}
where accessible(posting) looks something like this...
private boolean accessible(Posting posting) {
return authorisationChecker.isAuthorised(whoAmI(), posting);
}
Then your show() event method would look like this...
public Resolution show() {
if (posting == null) return NOT_FOUND;
return new ForwardResolution("/WEB-INF/jsp/posting.jsp");
}
Separately, when I use Stripes I often have multiple events (like "show", or "update") within the same Stripes ActionBean. For me it makes sense to group operations (verbs) around a related noun.
Using clean URLs, your ActionBean annotations would look like this...
#UrlBinding("/posting/{$event}/{posting}")
#RolesAllowed({ "USER" })
public class PostingActionBean extends BaseActionBean
...where {$event} is the name of your event method (i.e. "show" or "update"). Note that I am using {posting}, and not {postingId}.
For completeness, here is what your update() event method might look like...
public Resolution update() {
if (posting == null) throw new UnauthorisedAccessException();
postingService.saveOrUpdate(posting);
message("posting.save.confirmation");
return new RedirectResolution(PostingsAction.class);
}
I have setup a Netbeans form with a text-field bound to a bean property. The binding is supposed to be two-way, but only works one-way. Updates to the field in the GUI update the bean, but if the bean is updated, the GUI does not update.
The Netbeans generated code looks like this for each property:
binding=org.jdesktop.beansbinding.Bindings.createAutoBinding(
org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, crmmast1,
org.jdesktop.beansbinding.ELProperty.create("${fname}"), lname,
org.jdesktop.beansbinding.BeanProperty.create("text"));
bindingGroup.addBinding(binding);
My bean has property change support added:
private PropertyChangeSupport changeSupport = new
PropertyChangeSupport(this);;
public void addPropertyChangeListener (PropertyChangeListener listener) {
changeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(
PropertyChangeListener listener) {
changeSupport.removePropertyChangeListener(listener);
}
public void firePropertyChange (String propertyName,
Object old, Object newObj) {
changeSupport.firePropertyChange(propertyName, old, newObj);
}
Within the sett for the properties I have:
public void setFname(String newName) {
firePropertyChange("fname", fname, newName);
this.fname = newName;
}
When I update the underlying bean, the bean updates but the textfield does not (even though I have verified that a property change event is being fired.
Ran into the same problem. Really annoying. It took me a long time to realize something about the AutoBinding: it appears to listen to actions within the Property context established between the Source and the Target that you specify in the createAutoBinding call. This is why entering text in the JTextField updates to your bean property with no problem. It's on the same binding 'rail' so to speak.
What this means is that when you attempt to update your JavaBean via its setX() call directly from another source, like I was doing with a JFileChooser, the members of the autobinding don't see it, even though the firePropertyChange method is called.
doing this does not work:
myBean1.setFileLocation(fileChooser.getSelectedFile().getAbsolutePath());
So, instead of doing that call, what I instead did was make sure the Binding had a 'name' attached to it, which gets placed as the last parameter in the createAutoBinding() call. I did this in the Netbeans Matisse Property editor Bind popup Tool under the Advanced tab. In the example below, it is named "fileLocation".
binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(
org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE,
myBean1,
org.jdesktop.beansbinding.ELProperty.create("${fileLocation}"),
jTextField12,
org.jdesktop.beansbinding.BeanProperty.create("text"),
"fileLocation");
bindingGroup.addBinding(binding);
The call that got me on the binding 'rail' so that the JTextField would update with my selected file looked like the following:
Binding fileBind = bindingGroup.getBinding("fileLocation");
Property fileProp = fileBind.getSourceProperty();
fileProp.setValue(myBean1, fileChooser.getSelectedFile().getAbsolutePath());
I had to pull this up with getBinding() and getSourceProperty() from the global binding group because Matisse locks out direct access to the original binding, and I am not supposed to edit it since the code is autogenerated. If you are hand editing your code, then you could always ensure that you have an available name to access the Property object directly.
In any case, the key to get an 'outside influencer' to work on the bean and the JTextField is to perform your changes on the Binding Property itself.
Recently I tried Swing GUI creation with netbeans and I was wondering about exactely the same issue (therefore found your post).
Your solution should work. There are only two things to keep in mind:
You will have to provide the correct prorperty name once you propagate bean changes (fname in your case should be ok)
The actual bean property has to be changed before changeSupport.firePropertyChange is being called. See: http://wiki.netbeans.org/BestPracticesWithJPAAndBeansBinding
Once these two things are obeyed, everthing should work. I also used JFileChooser to change a text field and there is no need to set the properties of the binding manually (as suggested by the other answer).
My current problem regards updating context information dynamically in FormInjector, my previous question Updating a zone inside a form in Tapestry 5 probably contains useful background information.
I added the following in my template.
<div t:type="FormInjector" t:id="injector" t:context="item.id"/>
And the following in my component class.
#OnEvent(component = "injector")
Block loadItemFields(String id) {
item = itemRepository.find(id);
return itemFieldsBlock;
}
Everything is working fine, new form fields appear, but the search is always done with the same id. I would like to change the id with JavaScript before triggering the event, but I don't know how to achieve this.
If there is additional information required I am happy to supply it.
Using the context parameter to pass a dynamic value wouldn't be my first option. (The FormInjector component generates a URL to trigger the event handler, which then includes the context - however, this is done when the component renders, and is not meant to be dynamic.)
I'd get rid of the context parameter and find a different way to submit the value. One possibility would be to submit the form via AJAX and trigger the injection in the callback:
this.myFormElement.observe('change', this.onChange.bindAsEventListener(this));
...
onChange: function(event) {
this.myFormElement.form.request({
onSuccess: this.afterFormSubmitted.bind(this)
});
},
afterFormSubmitted: function() {
this.formInjector.trigger();
}
That way, the value of the form element has been set on the server side when you trigger the form injection, and you can use it in your injection event handler.