Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » scout » Making AbstractDrawLineField persistent(How to allow SQL methods access to the fields)
Making AbstractDrawLineField persistent [message #1012260] Thu, 21 February 2013 08:09 Go to next message
Urs Beeli is currently offline Urs Beeli
Messages: 335
Registered: October 2012
Location: Bern, Switzerland
Senior Member
This is a lengthy post, please bear with me Smile I first describe what I did, the question is at the very bottom of the post (if you want to jump down to have a peak at what this is all about).

There is a howto on the scout Wiki that explpains how to create a custom control (http://wiki.eclipse.org/Scout/HowTo/Add_a_custom_GUI_component) to draw a line. It supports setting the initial coordinates in the SDK (using the getConfiguredStart/EndX/Y methods) as well as drawing the line using the mouse. I've managed to put together an SWT implementation of that customer field (the HowTo only showed a Swing example, I've updated the HowTo to include the SWT solution).

Next, I wanted to look at making this field persistent. I wanted to be able to read the start and end points from the database and store it back there if the user changed the line using the mouse. One of the issues I encountered was that this custom field not only shows one value (like all the derivates of AbstractValueField) but four (the four coordinates of the line endings). I solved this by creating a bean class holding the two points (start, end) which in turn hold the two coordinates (x, y). Based on this class (LinePoints) I then created an AbstractDrawLineFieldData class.

LinePoints
package org.eclipse.minicrm.shared.data.form.fields.ext;

import java.io.Serializable;

public class LinePoints implements Serializable {
  private static final long serialVersionUID = 1L;

  private LinePoint start;
  private LinePoint end;

  public LinePoints() {
    start = null;
    end = null;
  }

  public LinePoints(LinePoint start, LinePoint end) {
    this.start = start;
    this.end = end;
  }

  public LinePoint getStart() {
    return start;
  }

  public void setStart(LinePoint start) {
    this.start = start;
  }

  public LinePoint getEnd() {
    return end;
  }

  public void setEnd(LinePoint end) {
    this.end = end;
  }
}


LinePoint
package org.eclipse.minicrm.shared.data.form.fields.ext;

import java.awt.Point;
import java.io.Serializable;

public class LinePoint implements Serializable {
  private static final long serialVersionUID = 1L;
  private int x;
  private int y;

  public LinePoint(int x, int y) {
    this.x = x;
    this.y = y;
  }

  public LinePoint(Point p) {
    this.x = p.x;
    this.y = p.y;
  }

  public void setX(int x) {
    this.x = x;
  }

  public void setY(int y) {
    this.y = y;
  }

  public int getX() {
    return x;
  }

  public int getY() {
    return y;
  }

  public Point getPoint() {
    return new Point(x, y);
  }
}


AbstractDrawLineFieldData
package org.eclipse.minicrm.shared.data.form.fields.ext;

import java.io.Serializable;

import org.eclipse.scout.commons.TypeCastUtility;
import org.eclipse.scout.commons.holders.IHolder;
import org.eclipse.scout.rt.shared.data.form.fields.AbstractFormFieldData;

public class AbstractDrawLineFieldData extends AbstractFormFieldData implements IHolder<LinePoints>, Serializable {
  private static final long serialVersionUID = 1L;
  private LinePoints m_value;

  public AbstractDrawLineFieldData() {
    super();
  }

  @Override
  public LinePoints getValue() {
    return m_value;
  }

  @Override
  public void setValue(LinePoints o) {
    m_value = o;
    setValueSet(true);
  }

  @SuppressWarnings("unchecked")
  @Override
  public Class<LinePoints> getHolderType() {
    return TypeCastUtility.getGenericsParameterClass(getClass(), IHolder.class);
  }

}


Next, I modified the AbstractDrawLineField class in the client. First I added an annotation about its FormData field:
@FormData(value = AbstractDrawLineFieldData.class, defaultSubtypeSdkCommand = DefaultSubtypeSdkCommand.CREATE, sdkCommand = SdkCommand.USE, genericOrdinal = 0)


The next change was to no longer use the two properties PROP_START, PROP_END for the two line end points I now only use one property PROP_VALUE which holds a LinePoints object.

AbstractDrawLineField:
  @Override
  public Point getEnd() {
    LinePoints value = (LinePoints) propertySupport.getProperty(IValueField.PROP_VALUE);
    return (value == null ? null : value.getEnd() == null ? null : value.getEnd().getPoint());
  }

  @Override
  public void setEnd(Point p) {
    LinePoints oldValue = getValue();
    LinePoints value;
    if (oldValue != null) {
      value = new LinePoints(oldValue.getStart(), oldValue.getEnd());
    }
    else {
      value = new LinePoints();
    }
    value.setEnd(new LinePoint(p));
    boolean changed = propertySupport.setPropertyNoFire(IValueField.PROP_VALUE, value);
    if (changed) {
      propertySupport.firePropertyChange(IValueField.PROP_VALUE, oldValue, value);
    }
  }

  @Override
  public Point getStart() {
    LinePoints value = (LinePoints) propertySupport.getProperty(IValueField.PROP_VALUE);
    return (value == null ? null : value.getStart() == null ? null : value.getStart().getPoint());
  }

  @Override
  public void setStart(Point p) {
    LinePoints oldValue = getValue();
    LinePoints value;
    if (oldValue != null) {
      value = new LinePoints(oldValue.getStart(), oldValue.getEnd());
    }
    else {
      value = new LinePoints();
    }
    value.setStart(new LinePoint(p));
    boolean changed = propertySupport.setPropertyNoFire(IValueField.PROP_VALUE, value);
    if (changed) {
      propertySupport.firePropertyChange(IValueField.PROP_VALUE, oldValue, value);
    }
  }


This lead to small modifications of IDrawLineField (removing the two PROP_* constants) and the Swing and SWT implementations (they now need to trigger on PROP_VALUE)

SwtScoutDrawLineField & SwingScoutDrawLineField
  @Override
  protected void handleScoutPropertyChange(String name, Object newValue) {
    if (name.equals(IValueField.PROP_VALUE)) {  // used to be: if (name.equals(IDrawLineField.PROP_START) || name.equals(IDrawLineField.PROP_END)) {
      updateLineFromScout();
    }
    super.handleScoutPropertyChange(name, newValue);
  }


Other than that, no changes were needed to the rendering implementations.

Now, the remaining methods to be added to AbstracDrawLineField:
First, some new members and constructors:
  private int m_valueChanging;
  private LinePoints m_initValue;
  private EventListenerList m_listeningSlaves;// my slaves

  public AbstractDrawLineField() {
    this(true);
  }

  public AbstractDrawLineField(boolean callInitializer) {
    super(callInitializer);
  }


Next, the methods to import and export formData:
  @Override
  public void exportFormFieldData(AbstractFormFieldData target) throws ProcessingException {
    AbstractDrawLineFieldData v = (AbstractDrawLineFieldData) target;
    v.setValue(this.getValue());
  }

  @SuppressWarnings("unchecked")
  @Override
  public void importFormFieldData(AbstractFormFieldData source, boolean valueChangeTriggersEnabled) {
    AbstractDrawLineFieldData v = (AbstractDrawLineFieldData) source;
    if (v.isValueSet()) {
      try {
        if (!valueChangeTriggersEnabled) {
          setValueChangeTriggerEnabled(false);
        }
        //
        LinePoints newValue;
        Object o = v.getValue();
        if (o != null) {
          Class castType = getHolderType();
          if (castType.isAssignableFrom(o.getClass())) {
            newValue = (LinePoints) o;
          }
          else {
            newValue = (LinePoints) TypeCastUtility.castValue(o, castType);
          }
        }
        else {
          newValue = null;
        }
        this.setValue(newValue);
      }
      finally {
        if (!valueChangeTriggersEnabled) {
          setValueChangeTriggerEnabled(true);
        }
      }
    }
  }


And the methods to store to/load from XML:
  @Override
  public void storeXML(SimpleXmlElement x) throws ProcessingException {
    super.storeXML(x);
    LinePoints value = getValue();
    try {
      x.setObjectAttribute("value", value);
    }
    catch (IOException e) {
      if (LOG.isInfoEnabled()) {
        LOG.info("not serializable value in field " + getClass().getName() + "/" + getLabel() + ": " + e);
      }
    }
  }

  @Override
  public void loadXML(SimpleXmlElement x) throws ProcessingException {
    super.loadXML(x);
    try {
      LinePoints value = TypeCastUtility.castValue(x.getObjectAttribute("value", null), getHolderType());
      setValue(value);
    }
    catch (Exception e) {
      // be lenient, maybe the field was changed
      LOG.warn(null, e);
    }
  }


Next some methods needed to know if the field has changed when aborting the form:
  public void setInitValue(LinePoints initValue) {
    m_initValue = initValue;
  }

  public LinePoints getInitValue() {
    return m_initValue;
  }

  @Override
  protected boolean execIsSaveNeeded() throws ProcessingException {
    LinePoints value = getValue();
    LinePoints initValue = getInitValue();
    if (value == null && initValue == null) {
      return false;
    }
    else if (value == null || initValue == null) {
      return true;
    }
    else {
      if (value.getStart().equals(initValue.getStart()) &&
          value.getEnd().equals(initValue.getEnd())) {
        return false;
      }
      else {
        return true;
      }
    }
  }

  @Override
  protected void execMarkSaved() throws ProcessingException {
    super.execMarkSaved();
    LinePoints value = getValue();
    setInitValue(value);
  }

  @Override
  protected boolean execIsEmpty() throws ProcessingException {
    return getValue() == null;
  }


And finally, the methods to access the property:
  public LinePoints getValue() {
    return (LinePoints) propertySupport.getProperty(IValueField.PROP_VALUE);
  }

  public final void setValue(LinePoints newValue) {
    /**
     * @rn imo, 22.02.2006, set verifyInput flag while firing triggers when a
     *     message box is shown, the doOK of the form might overrun this
     *     command. setting isVerifyInput() cancels the ok task
     */
    if (isValueChanging()) {
      Exception caller1 = new Exception();
      LOG.warn("Loop detection in " + getClass().getName() + " with value " + newValue, caller1);
      return;
    }
    try {
      setFieldChanging(true);
      setValueChanging(true);
      //
      LinePoints oldValue = getValue();
      boolean changed = propertySupport.setPropertyNoFire(IValueField.PROP_VALUE, newValue);
      if (changed) {
        propertySupport.firePropertyChange(IValueField.PROP_VALUE, oldValue, newValue);
        checkSaveNeeded();
      }
    }
    finally {
      setValueChanging(false);
      setFieldChanging(false);
    }
  }

  public boolean isValueChanging() {
    return m_valueChanging > 0;
  }

  private void setValueChanging(boolean b) {
    if (b) {
      m_valueChanging++;
    }
    else {
      m_valueChanging--;
    }
  }

  public Class<LinePoints> getHolderType() {
    return LinePoints.class;
  }


Now I can do the following in the process service:
  @Override
  public DrawLineFormData load(DrawLineFormData formData) throws ProcessingException {
    if (!ACCESS.check(new ReadDrawLinePermission())) {
      throw new VetoException(TEXTS.get("AuthorizationFailed"));
    }

    formData.getDrawLine().setValue(new LinePoints(new LinePoint(100, 100), new LinePoint(200, 200)));

    return formData;
  }


I can also do:
  @Override
  public DrawLineFormData load(DrawLineFormData formData) throws ProcessingException {
    if (!ACCESS.check(new ReadDrawLinePermission())) {
      throw new VetoException(TEXTS.get("AuthorizationFailed"));
    }

    IntegerHolder startX = new IntegerHolder();
    IntegerHolder startY = new IntegerHolder();
    IntegerHolder endX = new IntegerHolder();
    IntegerHolder endY = new IntegerHolder();
    SQL.selectInto("SELECT 100,100,200,200 FROM DUAL INTO :startX, :startY, :endX, :endY",
        new NVPair("startX", startX),
        new NVPair("startY", startY),
        new NVPair("endX", endX),
        new NVPair("endY", endY));
    formData.getDrawLine().getValue().getStart().setX(startX.getValue());
    formData.getDrawLine().getValue().getStart().setY(startY.getValue());
    formData.getDrawLine().getValue().getEnd().setX(endX.getValue());
    formData.getDrawLine().getValue().getEnd().setY(endY.getValue());
    return formData;
  }


However, what I cannot do is the following:
  @Override
  public DrawLineFormData load(DrawLineFormData formData) throws ProcessingException {
    if (!ACCESS.check(new ReadDrawLinePermission())) {
      throw new VetoException(TEXTS.get("AuthorizationFailed"));
    }

    SQL.selectInto("SELECT 100, 100,200, 200 FROM DUAL INTO :drawLine.start.x, :drawLine.start.y, :drawLine.end.x, :drawLine.end.y", formData);

    return formData;
  }


This throws the following exception:
!MESSAGE org.eclipse.scout.rt.shared.services.common.exceptionhandler.LogExceptionHandlerService.differentiatedLog(LogExceptionHandlerService.java:76) ProcessingStatus[ERROR code=0 invoking org.eclipse.minicrm.shared.services.process.IDrawLineProcessService:load / SQL with binds:
SELECT    100,
          100,
          200,
          200
FROM      DUAL
INTO      :drawLine2.start.x,
          :drawLine2.start.y,
          :drawLine2.end.x,
          :drawLine2.end.y / Cannot find output for 'ValueOutputToken[drawLine2.start.x parsed ':drawLine2.start.x', replaced ':drawLine2.start.x' into]' in bind base. When selecting into shared context variables make sure these variables are initialized using CONTEXT.set<i>PropertyName</i>(null)]


Can anyone tell me what I need to change in my solution to allow the dot notation in the SQL methods? I assume that my LinePoints and LinePoint classes need to be modified but have no clue where to start...
Please simplify the problem [message #1012542 is a reply to message #1012260] Thu, 21 February 2013 19:08 Go to previous messageGo to next message
Stathis Alexopoulos is currently offline Stathis Alexopoulos
Messages: 42
Registered: September 2010
Member
Hello Urs,

I suspect that your problem has nothing to do with GUI. It seems that you managed to do everything, but you cannot pass the bind variables to SQL. Indeed, the lengthy description of GUI details does not help to concetrate on real problem.

I am suggesting to concetrate in the behavior of SQL for nested properties.

Quote:
Can anyone tell me what I need to change in my solution to allow the dot notation in the SQL methods? I assume that my LinePoints and LinePoint classes need to be modified but have no clue where to start..

All you have to do is to verify that mentioned properties in your SQL query has the proper get...() and set...() methods.

By the way. Did you noticed that you issue drawLine.start.x but created drawLine2.start.x? Is it a typo or what?

Re: Making AbstractDrawLineField persistent [message #1013891 is a reply to message #1012260] Sun, 24 February 2013 16:18 Go to previous messageGo to next message
Beat Schwarzentrub is currently offline Beat Schwarzentrub
Messages: 43
Registered: November 2010
Member
Urs,

Quote:

However, what I cannot do is the following:
    SQL.selectInto("SELECT 100, 100,200, 200 FROM DUAL INTO :drawLine.start.x, :drawLine.start.y, :drawLine.end.x, :drawLine.end.y", formData);



You cannot do that either:
DrawLineFormData formData = new DrawLineFormData();
formData.getDrawLine().getEnd().setX(10); // NPE!

All fields in the formData are initialized by a "holder" object (FieldData or Property), but the value of such a holder can be null (and they are, when the FormData is created). Scout is able to follow the "bean path" in bind variables, but only if every element really exists. Intermediate objects are not created automatically.

In your case, the problem is that you have two different types of beans, one wrapped into the other. The values on the "inner" beans cannot be set, because the "outer" bean does not exist.

Try that:
DrawLineFormData formData = new DrawLineFormData();
formData.getDrawLine().setValue(new Lines(new LinePoint(), new LinePoint()));
formData.getDrawLine().getEnd().setX(10); // OK!


I usually try to avoid the "bind variable name magic" and specify the binds explicitly. This has the advantage that your code doesn't break when you rename a field (because Eclipse does not refactor the bind variable names). Are you sure that your 3rd last example (the one using the IntegerHolders) works? Because in the default LinePoints contructor you initialize your variables with null. (Maybe you initialized the FormData before.)

I could not look too deep into your example (because it is rather large Smile). If you want to have a more detailed answer to your questions, inspect the code in the method org.eclipse.scout.rt.server.services.common.jdbc.internal.exec.StatementProcessor.createOutputRec(). The parameter 'path' holds the different parts of your bind variable name. Create a breakpoint and observe how Scout handles your data.

Beat
Re: Please simplify the problem [message #1014105 is a reply to message #1012542] Mon, 25 February 2013 07:06 Go to previous messageGo to next message
Urs Beeli is currently offline Urs Beeli
Messages: 335
Registered: October 2012
Location: Bern, Switzerland
Senior Member
Stathis Alexopoulos wrote on Thu, 21 February 2013 20:08
Hello Urs,

I suspect that your problem has nothing to do with GUI. It seems that you managed to do everything, but you cannot pass the bind variables to SQL. Indeed, the lengthy description of GUI details does not help to concetrate on real problem.

You are probably right, but not being sure where exactly I might have gone wrong, I wanted to provide everything I did (for example, I didn't know if it could be a problem of my FormData annotation, the way I set up the beans or just some missing code somewhere...

Stathis Alexopoulos wrote on Thu, 21 February 2013 20:08
By the way. Did you noticed that you issue drawLine.start.x but created drawLine2.start.x? Is it a typo or what?


I have three of those form fields on my form and am populating each one using a different way in the process service. To simplify things I just wanted to use the same name in my post and must have missed one instance when changing the name after copying it out of my code.
Re: Making AbstractDrawLineField persistent [message #1014109 is a reply to message #1013891] Mon, 25 February 2013 07:14 Go to previous messageGo to next message
Urs Beeli is currently offline Urs Beeli
Messages: 335
Registered: October 2012
Location: Bern, Switzerland
Senior Member
Beat Schwarzentrub wrote on Sun, 24 February 2013 17:18
All fields in the formData are initialized by a "holder" object (FieldData or Property), but the value of such a holder can be null (and they are, when the FormData is created). Scout is able to follow the "bean path" in bind variables, but only if every element really exists. Intermediate objects are not created automatically.

In your case, the problem is that you have two different types of beans, one wrapped into the other. The values on the "inner" beans cannot be set, because the "outer" bean does not exist.


Thanks for explaining this.

Beat Schwarzentrub wrote on Sun, 24 February 2013 17:18
Are you sure that your 3rd last example (the one using the IntegerHolders) works? Because in the default LinePoints contructor you initialize your variables with null. (Maybe you initialized the FormData before.)


Yes, this works (it's what I use at the moment). I guess the initialisation is done in the following places before exportFormData is called:
AbstractDrawLineField.initConfig() {
    m_uiFacade = new P_UiFacade();
    super.initConfig();
    setStart(new Point(getConfiguredStartX(), getConfiguredStartY())); // -> new object created here
    setEnd(new Point(getConfiguredEndX(), getConfiguredEndY()));
  }

and
AbstractDrawLineField.setStart(Point p) {
    LinePoints oldValue = getValue();
    LinePoints value;
    if (oldValue != null) {
      value = new LinePoints(oldValue.getStart(), oldValue.getEnd());
    }
    else {
      value = new LinePoints(); // --> new object created here
    }
    value.setStart(new LinePoint(p));
    boolean changed = propertySupport.setPropertyNoFire(IValueField.PROP_VALUE, value);
    if (changed) {
      propertySupport.firePropertyChange(IValueField.PROP_VALUE, oldValue, value);
    }
  }


Beat Schwarzentrub wrote on Sun, 24 February 2013 17:18
If you want to have a more detailed answer to your questions, inspect the code in the method org.eclipse.scout.rt.server.services.common.jdbc.internal.exec.StatementProcessor.createOutputRec(). The parameter 'path' holds the different parts of your bind variable name. Create a breakpoint and observe how Scout handles your data.


Excellent, I'll look into this when I next find some time.

Urs
Re: Making AbstractDrawLineField persistent [message #1014160 is a reply to message #1014109] Mon, 25 February 2013 09:25 Go to previous messageGo to next message
Urs Beeli is currently offline Urs Beeli
Messages: 335
Registered: October 2012
Location: Bern, Switzerland
Senior Member
I just stepped through createOutputRec and found out that apparently I need to write my SQL statement as
SQL.selectInto("SELECT 100, 100,200, 200 FROM DUAL INTO :drawLine.value.start.x, :drawLine.value.start.y, :drawLine.value.end.x, :drawLine.value.end.y", formData);

for the parsing to work.

I haven't quite understood yet, why that is so. My AbstractDrawLineField has all of these getters/setters
get/setValue()
get/setStart()
get/setEnd()


Looking at my form data annotation I thought that maybe that was the problem (I had taken it from one of the groupbox templates I had created):
@FormData(value = AbstractDrawLineFieldData.class, defaultSubtypeSdkCommand = DefaultSubtypeSdkCommand.CREATE, sdkCommand = SdkCommand.USE, genericOrdinal = 0)

So, I changed this to what the form data annotation looks like on a full form:
@FormData(value = AbstractDrawLineFieldData.class, sdkCommand = SdkCommand.USE)

but unfortunately, that doesn't change anything.

I can certainly live with adding the additional ".value" into my SQL statements, but I don't quite understand why they are needed here, but not an the groupbox templats or any of the fields derived from AbstractValueField<T>, even though I copied things more or less from those classes.

Is there an easy change I can make to get rid of this additional term? I thought I might be able to replace the LinePoints m_value member in my AbstractDrawLineFieldData class with two LinePoint m_start/m_end members, but then I get an error that I need to provide a get/setValue() method in it, so it seems that there is more to it...
Re: Making AbstractDrawLineField persistent [message #1016716 is a reply to message #1012260] Thu, 07 March 2013 13:20 Go to previous messageGo to next message
Claudio Guglielmo is currently offline Claudio Guglielmo
Messages: 127
Registered: March 2010
Senior Member
Hi Urs

If you only want to store the line points, why not just use a formData bean instead of creating all these classes? You just have to put the bean into your field and annotate it with @FormData.

@FormData(value = AbstractDrawLineFieldData.class, sdkCommand = SdkCommand.CREATE, defaultSubtypeSdkCommand = DefaultSubtypeSdkCommand.CREATE)
public abstract class AbstractDrawLineField extends AbstractCustomField implements IDrawLineField {

  private LinePoints m_linePoints;

  @Override
  protected String getConfiguredLabel() {
    return TEXTS.get("DrawLine");
  }

  @FormData
  public LinePoints getLinePoints() {
    return m_linePoints;
  }

  @FormData
  public void setLinePoints(LinePoints linePoints) {
    m_linePoints = linePoints;
  }
  ....
}


Or is that not sufficient for your needs? Instead of using AbstractValueField I just extended from an ordinary form field.
Re: Making AbstractDrawLineField persistent [message #1016734 is a reply to message #1016716] Thu, 07 March 2013 13:58 Go to previous messageGo to next message
Urs Beeli is currently offline Urs Beeli
Messages: 335
Registered: October 2012
Location: Bern, Switzerland
Senior Member
Claudio

I'm not sure I understand what you mean with "instead of creating all these classes". The three classes I created were LinePoint, LinePoints and AbstractDrawLineFieldData. If I understand your snippet correctly, I would still need LinePoint and LinePoints but would no longer create AbstractDrawLineFieldData myself but have it generated instead?

You are asking me, why I didn't just put the bean into my field and annotate it with @FormData. The reason for that is simple: I didn't find this information anywhere (it may not exist or I might not have looked in the right places).

Looking at your solution, I am uncertain how to proceed from here.


  • Adding your changes, I now get an error in the @FormData annotation "DefaultSubtypeSdkCommand cannot be resolved to a variable", what do I need to do to fix this?
    If I use @FormData(value = AbstractDrawLineFieldData.class, sdkCommand = SdkCommand.CREATE) instead, then I don't get an error, however, the created FormData is empty and does not contain the LinePoints needed to use in the ProcessService
  • What would my exportFormFieldData() and importFormFieldData() methods need to look like?
  • Changing the store/loadXML() methods would be fairly straight forward, I'd just use get/setLinePoints() instead of get/setValue()
  • with


My main goal is to be able to transfer the line end points between server and client using the FormData. Whatever I tried, I was unable to have a usable FormData created, that's why I ended up creating it myself and then using it.
Re: Making AbstractDrawLineField persistent [message #1016763 is a reply to message #1016734] Thu, 07 March 2013 15:47 Go to previous messageGo to next message
Claudio Guglielmo is currently offline Claudio Guglielmo
Messages: 127
Registered: March 2010
Senior Member
The classes LinePoint and LinePoints are perfectly fine. And yes, AbstractDrawLineFieldData gets created automatically.

Regarding the formData annotation: I must admit it's a little tricky. When using scout sdk you can create property beans by right clicking on the variables folder of the form. Unfortunately, there is no variables folder at the fields, so you have to move the created variables to your field manually. (I think I'll be having a little chat with the sdk guys about that).

Quote:

Adding your changes, I now get an error in the @FormData annotation "DefaultSubtypeSdkCommand cannot be resolved to a variable", what do I need to do to fix this?
If I use @FormData(value = AbstractDrawLineFieldData.class, sdkCommand = SdkCommand.CREATE) instead, then I don't get an error, however, the created FormData is empty and does not contain the LinePoints needed to use in the ProcessService

That's very strange. Actually I only created a template with the scout sdk (Right click on the field, create template), the annotation was added automatically. Could you please check the @FormData annotation? Does it contain the DefaultSubtypeSdkCommand enum?

Quote:
What would my exportFormFieldData() and importFormFieldData() methods need to look like?

You don't have to implement them, the beans are automatically imported and exported, see AbstractForm#exportFormData().

Quote:

Changing the store/loadXML() methods would be fairly straight forward, I'd just use get/setLinePoints() instead of get/setValue()

To just transport the values from client to server you don't need to modify them either. They are used to save the form state into a xml, which is used by the bookmarks to save the search form state.

Hope it helps Smile
Re: Making AbstractDrawLineField persistent [message #1016771 is a reply to message #1016734] Thu, 07 March 2013 16:00 Go to previous messageGo to next message
Arthur vD is currently offline Arthur vD
Messages: 51
Registered: March 2010
Member
Urs Beeli wrote on Thu, 07 March 2013 08:58


  • Adding your changes, I now get an error in the @FormData annotation "DefaultSubtypeSdkCommand cannot be resolved to a variable", what do I need to do to fix this?


That problem can be resolved by either adding the import statement manually or by using the form FormData.DefaultSubtypeSdkCommand.CREATE, making auto resolving the imports work. That's because DefaultSubtypeSdkCommand is an inner class, which sometimes seems to trouble Eclipse when used inside annotations.

[Updated on: Thu, 07 March 2013 16:01]

Report message to a moderator

Re: Making AbstractDrawLineField persistent [message #1017235 is a reply to message #1016771] Mon, 11 March 2013 09:26 Go to previous messageGo to next message
Urs Beeli is currently offline Urs Beeli
Messages: 335
Registered: October 2012
Location: Bern, Switzerland
Senior Member
@Arthur: Thanks, manually adding the import solved the error about DefaultSubtypeSdkCommand

@Claudio: Thanks, I've now removed the import/export methods and no longer have any errors. I realise the store/loadXML methods are only needed to store form data to a file, but that's something I wanted to have, just so I could try it once Smile

With your input I think I should now also be able to get rid of the LinePoints class and have two formData members "start" and "end" of type LinePoint. I'll give that a go next.

I'll let you know how I manage doing that.
Re: Making AbstractDrawLineField persistent [message #1017260 is a reply to message #1017235] Mon, 11 March 2013 11:06 Go to previous message
Urs Beeli is currently offline Urs Beeli
Messages: 335
Registered: October 2012
Location: Bern, Switzerland
Senior Member
Very good, I've now managed to directly attach the "start" and "end" points as FormData to my class. I now also no longer need the ".value." term in the SQL expression and could do away with much of the code I had copied from AbstractValueField without knowing why it was needed Wink

I have adjusted my extension to the Wiki to take these latest simplifications into account: http://wiki.eclipse.org/Scout/HowTo/3.8/Add_a_custom_GUI_component
Previous Topic:Button "OK"
Next Topic:Update / Refresh a TableField after an update / change
Goto Forum:
  


Current Time: Fri Oct 31 08:31:25 GMT 2014

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

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