Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: Not updating a form field on setFormObject()?

  1. #1
    Join Date
    Feb 2005
    Posts
    23

    Default Not updating a form field on setFormObject()?

    In our application, we send our form object off for asynchronous calculation and, when it returns, we update the form with the new form object. This works very well. The problem is that when a user is in the process of editing a form field when the calculation returns, we're currently blowing away their work. Obviously not good.

    One thought I have on this is, when the calculation returns, to register a VetoablePropertyChangeListener for the field with focus (assuming it's in my form and a bound control) and veto the update request, the drop the listener. Seems kind of hokey, but I was thinking that it would keep the field from getting updated nicely. However, with the SwingFormModel I can't add a veto listener.

    Anyone have any thoughts on this? I'm going to keep trying other things, but I thought I'd enlist the help of the experts.

    Thanks,
    Scott

  2. #2
    Join Date
    Aug 2004
    Posts
    229

    Default

    It looks like you are using an older version of Spring-rich, as SwingFormModel has now been removed and replaced. After rummaging through (the latest) Spring-rich source, I can't find anywhere that VetoableChangeListener is used, except in AbstractPropertyChangePublisher, which is just a support class providing vetoable "fire" methods that are never called in the source. This tells me that there probably isn't support for Vetoable changes in spring-rich at the moment. I imagine, based on my current understanding of Oliver's (relatively new) form code that a good home for such Vetoable support would be ValueModel. I imagine something like this:
    Code:
      ValueModel formProperty = formModel.getValueModel("someFormProperty");
      formProperty.addVetoableChangeListener(someVetoableChangeListener);
    The ValueModel will then fire a PropertyChangeEvent at the VetoableChangeListener whenever the value changes and revert the value if the change is vetoed. Special care will have to be taken so that when the form object changes this PropertyChangeEvent is fired and that the "old" value to revert to if the change is vetoed is the value that the ValueHolder contained before the form object was changed. Hhhm.. not the greatest sentence in the world, but hopefully you get the idea.

    - Andy

  3. #3
    Join Date
    Feb 2005
    Posts
    23

    Default

    Yep, that's exactly what I want, but it sounds like it's neither in the version of RCP that we're using now, nor would it be in the new one if we upgraded (which unfortunately isn't an option now since we're on a minor patch of a product that uses it).

    Out of curiosity, can any of you come up with a good way to do this in the current world order?

  4. #4
    Join Date
    Aug 2004
    Posts
    229

    Default

    One thing to try is to create your own ValueModel for that property. I'm basing this on the latest sources, so I'm not sure how compatible this is to your version, but most FormModels will implement the ConfigurableFormModel interface, which provides the "add(String formPropertyPath, ValueModel valueModel)" method. You could use this method to supply your own custom ValueModel for the property. Another approach would be to supply your own MutablePropertyAccessStrategy (which is provides the source ValueModels to your FormModel). You would have to be careful to preserve default behavior when doing either of these (BeanPropertyAccessStrategy does all sorts of things with its ValueModel, for example)... maybe using the decorator pattern or extending BeanPropertyAccessStrategy? Anyway, once you have your custom ValueModel in place, you could design it to protect the property when the form object is changed - maybe even using Vetoable property change events.

    - Andy

  5. #5
    Join Date
    Aug 2004
    Location
    Melbourne, Australia
    Posts
    335

    Default

    I can think of 2 solutions:

    1) Copy the property being edited from the current form object over to the new result object and then set that result object back into the form (make sure you do all this on the event dispatch thread). You could quite easily extend this to all properties modified since the last calculation started rather than just the currently focused property.

    2) If your calculation is only modifying some of the form's properties you could make your form object a PropertyChangePublisher and them just copy the appropriate properties from the result object to the form object. This would mean that only the properties modified by the calculation would be updated. Though this would still overwrite the field being updated by the user if that field was also updated by the calculation.

    Though as you're using an old version of the code I'd recommend you go with 1 - from memory the PropertyChangePublisher support was quite flaky.

    HTH

    Ollie

  6. #6
    Join Date
    Feb 2005
    Posts
    23

    Default

    Thanks, guys. Yeah, that's what I was implementing when this message came in. I have it working pretty well now. It helps that I really only have to worry about this for text components, because they're the only types of components that can be in a working state when the calculation returns. Other components like combo boxes, date pickers, etc., change values immediately and queue up their own calculation requests immediately. With a text component you can be in the middle of making a change when the calculation comes back.

    I think I'm there. Thanks again!

  7. #7
    Join Date
    Jul 2005
    Location
    Austria
    Posts
    105

    Default

    Hi,

    now I came up with the same problem. Have you a little code-snippet that demonstrates how it works. This does not work:
    Code:
    ..
    MyObject myObject = (MyObject)getFormObject();
    myObject.setText("This is a test");
    setFormObject(myObject);
    --> no new value in the textfield
    thank you for your help

  8. #8
    Join Date
    Aug 2004
    Location
    Melbourne, Australia
    Posts
    335

    Default

    Your call to setFormObject will do nothing as it will notice that you are setting the same object that is already contained in the form.

    This will work:
    Code:
    ..
    MyObject myObjectClone = (MyObject)getFormObject().clone();
    myObjectClone .setText("This is a test");
    setFormObject(myObjectClone);
    Or you need to make your MyObject class a property change publisher and fire a property change event when you change the "text" property.

    Ollie

  9. #9
    Join Date
    Jul 2005
    Location
    Austria
    Posts
    105

    Default

    thank you. But which way is better or do you prefer? A clone or a property change publisher?
    Is there any example where a property change publisher is implemented?

    markus

  10. #10
    Join Date
    Aug 2005
    Location
    Austin, TX
    Posts
    425

    Default

    I think the suggestion of cloning the object was meant to help exemplify the point that calling setFormObject with the same object won't do what you wanted.

    Using property changes would certainly be a better solution. Take a look at AbstractFormModel and its superclass AbstractPropertyChangePublisher for examples on how this works.

    HTH,
    Larry.

Similar Threads

  1. Replies: 3
    Last Post: Jun 8th, 2010, 03:27 AM
  2. Replies: 4
    Last Post: Jun 13th, 2006, 05:21 PM
  3. Replies: 9
    Last Post: May 4th, 2006, 09:53 AM
  4. Replies: 7
    Last Post: Feb 21st, 2005, 11:33 PM
  5. How to mark a form field as required???
    By Christian in forum Web
    Replies: 4
    Last Post: Sep 21st, 2004, 02:26 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •