Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
New Developer
lisfolks
Posts: 10
Registered: ‎03-23-2010
My Device: Curve 8900
Accepted Solution

Cursor/Caret not appearing in EditField?

I have an EditField whose cursor/caret is not showing up.  What am I missing?  Here's my code (and I'm using 4.5.0 and the 8300 sim) :

 

myEditField = new EditField( "", "", 7, Field.EDITABLE | Field.FIELD_LEFT ){

// inner class method to set field size (setExtent)
public void layout( int width, int height ) {
  int maxFontWidth = getFont().getAdvance( "W" );
  int fieldSize = myEditField.getMaxSize();
  int newWidth = maxFontWidth * fieldSize;
  setExtent( newWidth, getPreferredHeight() );
}

// inner class methods to handle changes onFocus/onUnfocus
public void onFocus( int direction ) {
  super.onFocus( direction );
  invalidate();
}

public void onUnfocus() {
  super.onUnfocus();
  invalidate();
}

// inner class method to set text/background colors
public void paint( Graphics g ) {
  if (myEditField.isFocus()) {
    g.setBackgroundColor( Color.LIGHTGREY );
  } else {
    g.setBackgroundColor( Color.WHITE );
  }
  g.fillRect( 0, 0, getWidth(), getHeight() );
  g.setColor( Color.NAVY );
  g.clear();
  g.drawText( myEditField.getText(), 0, 0 );
  super.paint( g );
}

}; // end inner class overrides
Please use plain text.
Developer
kanna
Posts: 70
Registered: ‎01-02-2009
My Device: Not Specified

Re: Cursor/Caret not appearing in EditField?

hi lisfolks,

try to remove g.clear() from your paint method and check.

 

 

---------------------
Best Regards,
Kannabiran.
---------------------
Don't forget to mark your post as solved if you got answer. And give kudos.
Please use plain text.
Developer
peter_strange
Posts: 19,601
Registered: ‎07-14-2008
My Device: Not Specified

Re: Cursor/Caret not appearing in EditField?

Another thing to try.  Save the color at the start of paint and make sure it is set back when you call super.paint. 

Please use plain text.
Developer
arkadyz
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: Cursor/Caret not appearing in EditField?

The only part of your code that could give you this kind of trouble is paint().  Your layout() is somewhat risky because you don't care about line feeds in your text, so I would recommend adding NO_NEWLINE style bit just in case.

 

Still, let's concentrate on paint().  This code is, albeit short, very confused and messy.  Here is what is strange:

 

1. You go through the trouble of setting a background color then use a method caring about the foreground (fillRect).

2. You set your foreground color only after your call to fillRect.

3. You nullify your fillRect results by g.clear, which uses the background color to fill the area.  Do you actually need that fillRect?

4. You drawText then call super.paint which will redraw the same text.  Am I missing something?

5. You have references to myEditField inside the code where myEditField is equivalent to this.  Why? This approach only makes your future cut & paste more difficult (believe me, this is a very strong point of consideration).  Remove "myEditField." from your paint() method.

6. You don't need your paint method to be public, just protected; I know there was some post on this forum indicating that protected and public might work differently there, but I suspect there was a bug somewhere else in their code.

 

I'm not sure at what point EditField draws the cursor, so in order to be safe I would do something like this:

myEditField = new EditField( "", "", 7, Field.EDITABLE | Field.FIELD_LEFT | EditField.NO_NEWLINE ){

//... keep your layout/onFocus/onUnfocus methods

// Two methods painting the field
protected void paintBackground( Graphics g ) {
  int prevBg = g.getBackgroundColor();
  int prevColor = g.getColor();
  if (isFocus()) {
    g.setBackgroundColor( Color.LIGHTGREY );
  } else {
    g.setBackgroundColor( Color.WHITE );
  }
  g.setColor(Color.NAVY);
  g.clear();
  super.paintBackground(); // in case they paint cursor here
  g.setBackgroundColor(prevBg);
}

protected void paint(Graphics g) {
  int prevColor = g.getColor();
  g.setColor( Color.NAVY );
  super.paint(g);
  g.setColor(prevColor);
}

};

 

 

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
Please use plain text.
New Developer
lisfolks
Posts: 10
Registered: ‎03-23-2010
My Device: Curve 8900

Re: Cursor/Caret not appearing in EditField?

kanna:  if I remove g.clear(), the field's background comes up black.  If I remove the fillRect AND the clear, the background remains white.  In neither case does the caret appear.

 

peter_strange: I'm not exactly sure what you mean (though it seems straightforward :smileywink:  I added a line at the beginning of the paint method like - int bakColor = g.getBackgroundColor;  Then, I added a line just before super.paint like g.setBackGroundColor( bakColor );  That didn't seem to do anything at all.  If your suggestion worked something like arcadyz' example, I'll get to that in a minute...

 

arcadyz:

-  I changed the myEditField references to 'this' - that was a 'duh' moment.

-  I removed the fillRect, but that didn't seem to do anything at all (except as noted above to kanna)

-  I had the drawText because without it, not even the text shows up!  The text is there (the app recognizes it), but it's invisible.

 

public void paint( Graphics g ) {
  if (this.isFocus()) {
    g.setBackgroundColor( Color.LIGHTGREY );
  } else {
    g.setBackgroundColor( Color.WHITE );
  }
  //g.fillRect( 0, 0, getWidth(), getHeight() );
  g.setColor( Color.NAVY );
  g.clear();
  g.drawText( this.getText(), 0, 0 );
  super.paint( g );
}

 

I didn't think I should have to override the two parts, but...  it worked the same as mine without the drawText:  the background color is correct, but no cursor or text appears, though the app recognizes the text that has been entered.

 

So, in summary:

- fillRect can be removed without any effect

- clear must be there for the background color to paint correctly

- drawText must be there for the text to appear

- and, backing up the colors doesn't seem to have any effect.

 

But, now another question:  where IS the caret drawn?  If I wanted to change the caret's color, say, where would I do this?  (Maybe that'll help me figure out what I've done incorrectly!)

Please use plain text.
Developer
arkadyz
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: Cursor/Caret not appearing in EditField?

OK... so you've tried our suggestions and they did not help.

 

It seems like you are wading into a territory where you might need some "trick" to make it work. Unfortunately, BlackBerry is sometimes like that - you do the simplest change, expecting to see some reasonable results, and suddenly hit a brick wall.

 

I'll try your code tonight in simulator when I get home and will see what it does.  In the mean time, start doing small incremental changes, beginning from something absolutely obvious like this:

 

protected void paintBackground(Graphics g) {
  super.paintBackground(g);
}

protected void paint(Graphics g) {
  super.paint(g);
}

protected void drawFocus(Graphics g, boolean on) {
  super.drawFocus(g, on);
}

 and gradually adding g.setColor() and g.setBackgroundColor() (unconditional at first; start adding your focus indications after the simple stuff works).  If even the above does not show the cursor (or the text - I really can't imagine why super.paint()  would not draw the text), I don't know what will.  If it disappears when you add some particular line of code, report it here.

 

One (maybe not too) crazy thought: BB might draw the cursor with drawFocus by passing the graphics with clipping rectangle containing just the character after cursor and a different on value...

 

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
Please use plain text.
Developer
peter_strange
Posts: 19,601
Registered: ‎07-14-2008
My Device: Not Specified

Re: Cursor/Caret not appearing in EditField?

Try this.  Sorry not sure what I've changed when compared with your code, I randomly went through it changing things that didn't look right.  However the 'trick' is the drawFocus.

 

Anyway, I need to get on with some real work, so please review, compare, test etc. and see how you get on.

 

myEditField = new EditField( "Label", "Text", 7, Field.EDITABLE | Field.FIELD_LEFT ){
  
  boolean _drawFocus = false;

// inner class method to set field size (setExtent)
public void layout( int width, int height ) {
  int maxFontWidth = getFont().getAdvance( "W" );
  int fieldSize = this.getMaxSize() + this.getLabel().length();
  int newWidth = maxFontWidth * fieldSize;
  super.layout( newWidth, height );
}

// inner class methods to handle changes onFocus/onUnfocus
protected void onFocus( int direction ) {
  super.onFocus( direction );
  invalidate();
}

protected void onUnfocus() {
  super.onUnfocus();
  invalidate();
}

protected void drawFocus(Graphics graphics,
                         boolean on) {
  _drawFocus = on;
  super.drawFocus(graphics, on);
  _drawFocus = false;
}

// inner class method to set text/background colors
public void paint( Graphics g ) {
  if ( _drawFocus ) {
    super.paint(g);
    return;
  }
  int currCol = g.getColor();
  if (this.isFocus()) {
    g.setBackgroundColor( Color.LIGHTGREY );
  } else {
    g.setBackgroundColor( Color.WHITE );
  }
  g.fillRect( 0, 0, getWidth(), getHeight() );
  g.clear();
  g.setColor( Color.NAVY );
  super.paint( g );
  g.setColor(currCol);
}

}; // end inner class overrides

 

Please use plain text.
New Developer
lisfolks
Posts: 10
Registered: ‎03-23-2010
My Device: Curve 8900

Re: Cursor/Caret not appearing in EditField?

arcadyz and peter_strange:  I will try your suggestions shortly.  In the meantime, just a note - the only reason I'm changing the background color on focus/unfocus is because of the missing cursor.  I do want a background color, but I would leave it alone if he caret would appear properly.  Just FYI.  I will let you know how my testing with your thoughts goes. And thanks for your patience!

Please use plain text.
New Developer
lisfolks
Posts: 10
Registered: ‎03-23-2010
My Device: Curve 8900

Re: Cursor/Caret not appearing in EditField?

[ Edited ]

I'm working on arkadyz idea of starting with the basics.  Right now, I just have the layout method overridden and I still have a cursor - and I have a question:  I am using super.layout and have not set an extent (based on the values when I debug, it seems to be set by the call to super).  Might that cause me problems later?  I thought an extent always had to be set when overriding layout...?

 

Here's my current code:

 

public void layout( int width, int height ) {
  int labelWidth = getFont().getAdvance( getLabel() );
  int fontHeight = getFont().getHeight();
  int baseNumWidth = getFont().getAdvance( "0" );
  int currentTextWidth = getFont().getAdvance( getText() );
  int currentActualWidth = labelWidth + currentTextWidth;
  int layoutWidth = currentActualWidth + ( baseNumWidth );
  super.layout( layoutWidth, fontHeight );
}

 

Another question, since I'm headed to the paint override next:  is there a way to paint only the text portion of the field, leaving the label at the default?  Or, will I have to separate the label out to do that?

 

[edited]  Added the paint override - super.paint( g ) worked great, setColor( Color.NAVY ) worked great, as soon as I added setBackgroundColor( Color.LIGHTGREY ) and clear() - wham, no cursor.

 

Thanks again for taking the time to help this newbie learn something. 

Please use plain text.
Developer
peter_strange
Posts: 19,601
Registered: ‎07-14-2008
My Device: Not Specified

Re: Cursor/Caret not appearing in EditField?

Look at the code I supplied, that is how I would set the width in layout - you don't actually care about the height, so let the Field sort that out within the constraints you have given it by overriding layout.

 

I would encourage you to review the code I supplied for other things too, as you work through this. 

Please use plain text.