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 Contributor
matthew80
Posts: 6
Registered: ‎08-30-2012
My Device: 9700 - Bold
Accepted Solution

Custom Text Field Cursor (Carret) doesn't appear

All;

 

I've created a custom text field based on the standard text field, the changes work great (really just a custom height and width and a border).  The problem is the paint method, which seems to remove the carret from the field when it gets focus.  To be clear the carret never displays at all.

 

public class CustomText extends TextField //cutom text field width
{
    //Custom Height and Width in Pixels
    final static int textwidth=125;
    final static int textheight=25;
     
     CustomText()
     {
     super(); // Call the default constructor    
     
     //Border for text fields
     XYEdges padding = new XYEdges(5, 5, 5, 5); //space between box and border
     Border theborder = BorderFactory.createSimpleBorder(padding, Border.STYLE_SOLID);
     
     //Assign the border to the object
     this.setBorder(theborder);      
     }
     
     public void onFocus( int direction ) 
     {
        super.onFocus( direction ); //invoke parent procedure
        invalidate(); //mark for redraw
     }

     public void onUnfocus()
     {
    super.onUnfocus(); //invoke parent procedure
    invalidate(); //mark for redraw
     }


     
     //Override the layout with the custom Width and Height     
     protected void layout(int width, int height)
     {
        super.layout(textwidth,textheight);
        setExtent(textwidth,textheight);

     }      
    
    //Override the display message such that no message is displayed when the field is full                      
    protected void displayFieldFullMessage()
    {
    }
    
    //Override the default paint method to call the super class constructor and then assign the border
    protected void paint(Graphics graphics)
    {   
       // int prevColor = graphics.getColor(); //Save Previous Color
        graphics.setBackgroundColor(Color.LIGHTGRAY); // Set to Gray
        graphics.clear(); // Clear for redraw
        super.paint(graphics); //Force Redraw of Object
      //  graphics.setColor(prevColor); //restore for cursor paint

        
    }
    
};

 In the paint method the first and last lines that are commented were a soloution I tried after reading about it.  Something along the lines of restoring the default color, but alas no success.   Any ideas would be most helpful

 

Thanks!

Developer
peter_strange
Posts: 19,609
Registered: ‎07-14-2008
My Device: Not Specified

Re: Custom Text Field Cursor (Caret) doesn't appear

Quick thoughts:

 

a) Remove the requirement to override paint by setting the Background to a Color.LIGHTGRAY using the background class

b) You have laid out the Field using this:

super.layout(textwidth,textheight);

If you then do this:

setExtent(textwidth,textheight);

you are likely to confuses the Field.  If you want it to always use all the Height and use all the width, then try setting this as Style, i.e. replace this:

super(); // Call the default constructor

with this

super(TextField.USE_ALL_HEIGHT | TextField.USE_ALL_WIDTH); // Call the default constructor   

c) Why are you overriding onFocus and onUnfocus?  I would remove these if you are not doing anything specific in these methods. 

 

Make these changes and you will have a much simpler TextField.  See if these changes resolve the caret problem too. 

New Contributor
matthew80
Posts: 6
Registered: ‎08-30-2012
My Device: 9700 - Bold

Re: Custom Text Field Cursor (Caret) doesn't appear

Peter;

 

Thank you for your help

 

a)  I've made the changes you suggested (see code below)

 

b) I've removed the setExtent call in the layout

 

c) I was planning on changing the background color of the textfield when it was selected (and then resetting it back to the LIGHTGRAY when it lost focus) to make it stand out.  Reading through (and please correct me if I'm wrong) I needed to override each of the focus functions and mark them as invalid to force a redraw when focus is gained / lost (to change the bg color).

 

I haven't fully decided if I want to go this route yet, since it now appears the carret is working!

 

It would appear something in the paint method (perhaps the clear for redraw) was losing the carret.  Here is the code as it stand now with the carret working

 

public class CustomText extends TextField //cutom text field width
{
    //Custom Height and Width in Pixels
    final static int textwidth=125;
    final static int textheight=25;
     
     CustomText()
     {
     super(TextField.USE_ALL_HEIGHT | TextField.USE_ALL_WIDTH); // Call the default constructor   

    
     
     //Border for text fields
     XYEdges padding = new XYEdges(5, 5, 5, 5); //space between box and border
     Border theborder = BorderFactory.createSimpleBorder(padding, Border.STYLE_SOLID); //create border
     Background bg = BackgroundFactory.createSolidBackground(Color.LIGHTGRAY); //assign solid background
     
     
     this.setBorder(theborder); //Assign the border to the object 
     this.setBackground(bg); //Assign the bg color to the object
     }
     
     //Override the layout with the custom Width and Height     
     protected void layout(int width, int height)
     {
        super.layout(textwidth,textheight);
        
     }      
    
    //Override the display message such that no message is displayed when the field is full                      
    protected void displayFieldFullMessage()
    {
    }
    
   
    
};

 

Developer
arkadyz
Posts: 2,268
Registered: ‎07-08-2009
My Device: various

Re: Custom Text Field Cursor (Caret) doesn't appear

You don't need the onFocus/onUnfocus to change the background - you can tell the system to do it for you.

 

Specifically, look at the

setBackground(int visual, Background background) 

method in Field class. You can specify different backgrounds for, say, VISUAL_STATE_FOCUS and VISUAL_STATE_NORMAL. The same is true for setBorder, but there you have an additional twist - the boolean updateLayout parameter. Make sure all your borders are of the same dimensions, then specify false there.

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

Re: Custom Text Field Cursor (Caret) doesn't appear

[ Edited ]

OK good that the caret is back, then question is what to do about focus background color.

 

The way you are supposed to do this, since OS 4.6 anyway, is to use the Background class and the VISUAL_STATE options.  So you

setBackground(int visual, Background background).

 

Now I think the way you would do is to do a

setBackground(...LIGHTGRAY...).

as the default then

setBackground(Field.VISUAL_STATE_FOCUS, ...other color background...).

so that you got your required color for focus.

 

But I have been coding BB since before this was introduced and I generally use the paintBackground approach, which as you point out means you need to invalidate() the Field in onFocus and onUnfocus.

 

Personally I think you should go new school and try the setBackground().  Let me know how it goes, I may want to use this approach in the future if it works for you!

 

Edit: I see our UI guru has recommended setBackground too while I was editting...  Ah well...,  I suspect my post is now redundant. 

New Contributor
matthew80
Posts: 6
Registered: ‎08-30-2012
My Device: 9700 - Bold

Re: Custom Text Field Cursor (Caret) doesn't appear

Thank you Both for your reply.  The code now looks like this.  The bg color changes onfocus and then back after focus is lost, no need to invalidate or overide paint or paintbackground

 

public class CustomText extends TextField //cutom text field width
{
    //Custom Height and Width in Pixels
    final static int textwidth=125;
    final static int textheight=25;
     
     CustomText()
     {
     super(TextField.USE_ALL_HEIGHT | TextField.USE_ALL_WIDTH); // Call the default constructor   

    
     
     //Border for text fields
     XYEdges padding = new XYEdges(5, 5, 5, 5); //space between box and border
     Border theborder = BorderFactory.createSimpleBorder(padding, Border.STYLE_SOLID); //create border
     
     Background bg = BackgroundFactory.createSolidBackground(Color.LIGHTGRAY); //assign solid background
     Background focus_bg = BackgroundFactory.createSolidBackground(Color.LEMONCHIFFON); //assign solid background
    
     
     this.setBorder(theborder); //Assign the border to the object 
     this.setBackground(Field.VISUAL_STATE_NORMAL, bg); //Assign the bg color to the object (default)
     this.setBackground(Field.VISUAL_STATE_FOCUS, focus_bg); //Assign the bg color to the object (when focused)
     }
     
     //Override the layout with the custom Width and Height     
     protected void layout(int width, int height)
     {
        super.layout(textwidth,textheight);
        
     }      
    
    //Override the display message such that no message is displayed when the field is full                      
    protected void displayFieldFullMessage()
    {
    }
    
   
    
};

 Ignore the color selection for now, just playing with different one's to see what meshes the best.