#1424 (not) reading Label.text

peter Fri 25 Feb 2011

In the clock example, examples/fan/clock.fan, I tried adding a line to the update method:

Void update()
{
  label := Actor.locals[handle] as Label
  if (label != null)
  {
    time := Time.now.toLocale("k:mm:ss a")
    label.text = "It is now $time"
    echo ("Label is: ${label.text}")  // <- attempt to retrieve label text
  }
}

I expected this to print the text that the label is currently showing. Instead, I only get the original text, that the label was initialised with. Is there a reason for this? It appears mysterious to me...

KevinKelley Sat 26 Feb 2011

Looks like a bug in FWT's Label peer class, I think. In src/fwt/java/LabelPeer.java there's this (lines 45..52):

// Str text := ""
public String text(fan.fwt.Label self) { return text.get(); }
public void text(fan.fwt.Label self, String v) { text.set(v); }
public final Prop.StrProp text = new Prop.StrProp(this, "")
{
  public String get(Widget w) { return text.val; } // CLabel doesn't perserve my text
  public void set(Widget w, String v) { ((CLabel)w).setText(v); }
};

The way the Prop classes work, the text prop has an initial val for in case the widget isn't created yet, and it's set in the constructor. The underlying CLabel SWT widget doesn't offer a getter for its text (judging from the comment in the above, anyway; I didn't check the SWT docs). So the above get/set pair doesn't seem to be consistent: set only sets the widget, but get always returns the cached val.

I think that the above set method should be:

public void set(Widget w, String v) { text.val=v; ((CLabel)w).setText(v); }

but I haven't tried to apply that yet.

peter Sat 26 Feb 2011

Kevin, thanks for your help in pointing me at the source - your suggestion worked.

I also tried changing the get method (line 50 of src/fwt/java/LabelPeer.java):

// Str text := ""
public String text(fan.fwt.Label self) { return text.get(); }
public void text(fan.fwt.Label self, String v) { text.set(v); }
public final Prop.StrProp text = new Prop.StrProp(this, "")
{
  public String get(Widget w) { return ((CLabel)w).getText(); } // <- TO THIS
  public void set(Widget w, String v) { ((CLabel)w).setText(v); }
};

and that also lets me retrieve the current text on the label.

Either or both ways seem to resolve the problem. Could this be raised as a bug?

brian Mon 28 Feb 2011

I wish I had beefed up the comment because I can't remember what the original problem really was :-)

I think Kevin's fix is the right one, and pushed a changset

Login or Signup to reply.