Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » scout » SmartField.execValidateValue cannot be used
SmartField.execValidateValue cannot be used [message #1065592] Wed, 26 June 2013 15:30 Go to next message
Urs Beeli is currently offline Urs Beeli
Messages: 330
Registered: October 2012
Location: Bern, Switzerland
Senior Member
I have a smart field which I use to select items that are then added to a table.

I wanted to check if the currently selected value in the smart field is already in the table and on the one hand disable the "add to table" button, show an error message on the smartfield and clear the value from the smart field.

The first two, I could do in the execChangedValue() method, but trying to do setValue(null) in execChangedValue() doesn't work (loop detection).

So I though I'd use execValidateValue instead. However, SmartField.execValidateValue() is final and can't be overwritten. In this case, I find it strange that the SDK offers me the possibility to overwrite this function.

Is there a deeper reasoning behind this or should I file a bug?

And if anyone has a suggestion how to have my smartfield set to null in the above case, I'd appreciate any hints.
Re: SmartField.execValidateValue cannot be used [message #1065660 is a reply to message #1065592] Thu, 27 June 2013 05:00 Go to previous messageGo to next message
Jeremie Bresson is currently offline Jeremie Bresson
Messages: 701
Registered: October 2011
Senior Member
There is a reason:

execValidateValue is about converting a rawValue of type <T> to the value <T> that will be set. (see ValueField > Input Validation).

In a SmartField you can not have a rawValue, because the value is taken from the key of the selected LookupRow (generated by the LookupCall).

Depending on your case, you might consider:
- execChangedValue() on the SmartField
- getDataByText() on the LookupCall (or LookupService) if you want to influence the way the value is generated.
Re: SmartField.execValidateValue cannot be used [message #1065670 is a reply to message #1065660] Thu, 27 June 2013 05:47 Go to previous messageGo to next message
Urs Beeli is currently offline Urs Beeli
Messages: 330
Registered: October 2012
Location: Bern, Switzerland
Senior Member
Jeremie, thanks for your answer. So I gather that making execValidateValue on SmartFields is intentionaly, I think in that case the SDK should not offer this method and have opened Bug 411729.

As for your suggestion: I do not so much want to check the value being generated, rather I would like to check the chosen value against another element and "clear" the smart field if it already exists in that field (a table in my case). However, calling setValue(null) in execChangedValue() does not work. Is there a workaround (other than starting in async job to clear the field a few milliseconds later?).
Re: SmartField.execValidateValue cannot be used [message #1065677 is a reply to message #1065670] Thu, 27 June 2013 06:19 Go to previous messageGo to next message
Urs Beeli is currently offline Urs Beeli
Messages: 330
Registered: October 2012
Location: Bern, Switzerland
Senior Member
Ok, so I've tried clearing the field using an AsynJob:
      protected void execChangedValue() throws ProcessingException {
        clearErrorStatus();
        if (getValue() != null) {
          Long key = getValue();
          if (getMappingTableField().getTable().findRowByKey(new Object[] { key }) == null) {
            getAddButton().setEnabled(true);
            getAddButton().requestFocus();
          } else {
            setErrorStatus("Mapping with ID " + key + " already in table");
            getAddButton().setEnabled(false);

            new ClientAsyncJob("SmartField clearer", ClientSession.get()) {
              @Override
              protected void runVoid(IProgressMonitor aMonitor) throws Throwable {
                Thread.sleep(50);
                setValue(null); // this doesn't work
                requestFocus();
              }
            }.schedule();
          }
        } else {
          getAddButton().setEnabled(false);
        }
      }


However, this causes the following exception:
!MESSAGE queueing swt runnable from outside scout thread: org.eclipse.scout.rt.ui.swt.basic.SwtScoutComposite$P_ScoutPropertyChangeListener$1@8d1300
!STACK 0
java.lang.IllegalStateException: queueing swt runnable from outside scout thread: org.eclipse.scout.rt.ui.swt.basic.SwtScoutComposite$P_ScoutPropertyChangeListener$1@8d1300
at org.eclipse.scout.rt.ui.swt.concurrency.SwtScoutSynchronizer.invokeSwtLater(SwtScoutSynchronizer.java:81)
at org.eclipse.scout.rt.ui.swt.AbstractSwtEnvironment.invokeSwtLater(AbstractSwtEnvironment.java:1372)
at org.eclipse.scout.rt.ui.swt.basic.SwtScoutComposite$P_ScoutPropertyChangeListener.propertyChange(SwtScoutComposite.java:464)
at org.eclipse.scout.commons.beans.BasicPropertySupport.firePropertyChangeImpl(BasicPropertySupport.java:408)
at org.eclipse.scout.commons.beans.BasicPropertySupport.processChangeBuffer(BasicPropertySupport.java:438)
at org.eclipse.scout.commons.beans.BasicPropertySupport.setPropertiesChanging(BasicPropertySupport.java:107)
at org.eclipse.scout.rt.client.ui.form.fields.AbstractFormField.setFieldChanging(AbstractFormField.java:1019)
at org.eclipse.scout.rt.client.ui.form.fields.AbstractValueField.setValue(AbstractValueField.java:319)
at org.eclipse.minicrm.client.ui.forms.StammdatenForm$MainBox$BahnhofField$1.runVoid(StammdatenForm.java:126)
at org.eclipse.scout.rt.client.ClientJob.runStatus(ClientJob.java:189)
at org.eclipse.scout.rt.client.ClientJob.runTransactionWrapper(ClientJob.java:172)
at org.eclipse.scout.rt.client.ClientJob.run(ClientJob.java:159)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)


I recall a similar problem discussed in this thread, but back there it was a question of doing something in the client thread from the SWT thread, which doesn't seem to be the solution here.

What do I need to do, in order to clear that pesky smart field?
Re: SmartField.execValidateValue cannot be used [message #1065679 is a reply to message #1065677] Thu, 27 June 2013 06:29 Go to previous messageGo to next message
Urs Beeli is currently offline Urs Beeli
Messages: 330
Registered: October 2012
Location: Bern, Switzerland
Senior Member
Alternatively, is there a way to enforce the selection of the text in the smart field, so the user can overwrite it with just one keypress?
Re: SmartField.execValidateValue cannot be used [message #1065688 is a reply to message #1065679] Thu, 27 June 2013 07:27 Go to previous messageGo to next message
Jeremie Bresson is currently offline Jeremie Bresson
Messages: 701
Registered: October 2011
Senior Member
What are the choices in your smart field?

Assuming the values should be:
- key_1 "Text one"
- key_2 "Text two"
- key_3 "Text three"

From what I understood, if you have key_2 in your table, the valid options are:
- key_1 "Text one"
- key_3 "Text three"

Why do you need to validate this later? I think one approach is to remove the invalid proposal from the list of lookup-rows.

If your lookup-rows comes from the server (that is not aware of the values in your table) or from a code-type (and you do not have access to the CodeLookupCall), you can also remove the invalid lookup-rows in the SmartField with execFilterLookupResult(..).
Re: SmartField.execValidateValue cannot be used [message #1065697 is a reply to message #1065688] Thu, 27 June 2013 07:59 Go to previous messageGo to next message
Urs Beeli is currently offline Urs Beeli
Messages: 330
Registered: October 2012
Location: Bern, Switzerland
Senior Member
Jeremie

Thanks, I hadn't thought of that solution, which is even better! My values come from the server using a lookup service. I'll have a look at the execFilterLookupResult() method.
Re: SmartField.execValidateValue cannot be used [message #1065752 is a reply to message #1065697] Thu, 27 June 2013 11:35 Go to previous message
Urs Beeli is currently offline Urs Beeli
Messages: 330
Registered: October 2012
Location: Bern, Switzerland
Senior Member
I've had a look at execFilterLookupResult() and I've found an even better solution than removing entries already in the table: If a key is already contained in the table, then instead of removing this entry, I'm keeping it in the result list but set it to disabled, to make it clear that it is already in the table.
      @Override
      protected void execFilterLookupResult(LookupCall call, List<LookupRow> result) throws ProcessingException {
        ITable table = getMappingTableField().getTable();
        for (LookupRow row : result) {
          if (table.findRowByKey(new Object[] { row.getKey() }) != null) {
            row.setIconId(Icons.MarkedError);
            row.setEnabled(false);
          } else {
            row.setIconId(Icons.Empty);
          }
        }
      }


Thanks for your help on this!
Previous Topic:Listen for changes of the checked state in the embedded table of an AbstractTableField
Next Topic:Missing elements in Scout Explorer
Goto Forum:
  


Current Time: Fri Sep 19 13:57:07 GMT 2014

Powered by FUDForum. Page generated in 0.01776 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software