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
Developer
Developer
Posts: 42
Registered: ‎02-17-2009
My Device: Not Specified
Accepted Solution

EditField / Centering user input

I am using an EditField to get input from a user. I would like to have the input centered within the field. The following code does what I am looking for:

 

 

EditField efName = new EditField(EditField.FIELD_HCENTER | EditField.NO_NEWLINE){
     public void paint(Graphics g){
	g.drawText(efName.getText(), 0, 0, DrawStyle.HCENTER, getWidth());
     }
};

 

The only issue I have with the above code is when I attempt to use the alt key to insert a comma or anything else. When the alt key is pressed the cursor moves to the middle of the screen temporarily until additional text is entered. Is there a way to keep the cursor at the end of the text until I am done with the filed?

 

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

Re: EditField / Centering user input

I have several issues with this code, when testing in 4.2.1 including it not putting the 'cursor' in the right place and the fact that goes horribly wrong when the user enters data that is longer than one line.  But I don't see a problem with the ALT. 

 

I can several options on doing this, some are easy, but not user friendly (for example, don't have an insertion 'caret'), others are a lot (and I mean a lot) more work.  How sophisticated does this Field need to be?

Developer
Developer
Posts: 42
Registered: ‎02-17-2009
My Device: Not Specified

Re: EditField / Centering user input

[ Edited ]

Thanks for the response. I actually noticed after my initial post that the caret just positions itself to length of inputed text from the left. I initially thought the problem was from hitting the shift (ALT) key but when you stop typing, the caret shows up at the length the text normally would be if it was left justified. So while I have managed to the input centered on the fly, the cursor does not remain centered if you pause the input for a second or two. Is there a way to push the cursor to where the input is on the field?

 

The field really doesn't need to be sophisticated. All I am looking to do is take inputed text from the user and center it in the field. I had wanted to do that on the fly but am thinking that is way more work than necessary. My current thought is to center the inputed text after focus on the field was lost. I am not exactly sure on the best way to do that though. I don't have a problem setting up the listener and the event, it is how to manipulate the field after it has the data, determining the padding, and then using a method to put it all back. What are your thoughts?

 

As far as the line length, it is just for a name so I believe I have the field wide enough to accomodate most names and their length. I also have the EditField.NO_NEWLINE set because I don't want more than one line of data. It is just for a name (last name, first initial). The EditField's width is controlled by its manager and I have the manager's width set to 330.

 

Thank you for your time.

 

 

Highlighted
Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: EditField / Centering user input

"Is there a way to push the cursor to where the input is on the field?"

 

If you want the caret in the correct place, I believe that counts as a lot of work, especially if you also want to provide the user with the ability to select, or insert characters in the middle of your text. 

 

"I am not exactly sure on the best way to do that though"

 

I would recommend onUnfocus/onFocus.  You need to invalidate and let the standard paint method paint the Field when it has focus (onFocus()) and invalidate() the Field again when it looses focus (onUnfocus()), but when not focused use your centered drawText method.  However I have never done this, I would be interested in seeing how this works. 

 

"it is just for a name"

 

Some people have long names, especially if you have a small screen.  And some people use big fonts. 

 

"manager's width set to 330"

 

I don't think this will stop an EditField going over two lines. 

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

Re: EditField / Centering user input

 



"I am not exactly sure on the best way to do that though"

 

I would recommend onUnfocus/onFocus.  You need to invalidate and let the standard paint method paint the Field when it has focus (onFocus()) and invalidate() the Field again when it looses focus (onUnfocus()), but when not focused use your centered drawText method.  However I have never done this, I would be interested in seeing how this works. 

 

"manager's width set to 330"

 

I don't think this will stop an EditField going over two lines. 


 

1. onFocus / onUnfocus - maybe right, but since TEP is overriding paint anyway, I'd do it like this:

 

protected void paint(Graphics g) {
    if (isFocus()) {
        super.paint(g);
    } else {
        g.drawText(efName.getText(), 0, 0, DrawStyle.HCENTER, getWidth());
    }
}

 2.  EditField will indeed wrap if it's too long.  In order to limit the number of characters needed, create EditField with that maximum number of characters:

 

EditField yourEditField = new EditField("label", "", <your number of characters - say, 30>, EditField.FOCUSABLE | ...);

 Otherwise EditField will be created with DEFAULT_MAXCHARS, which is a million...

 

 

----------------------------------------------------------
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
Developer
Posts: 42
Registered: ‎02-17-2009
My Device: Not Specified

Re: EditField / Centering user input

Peter / Arkadyz,

 

Thank you both for your help. I was only overriding paint as a way to try and do what I wanted. Using the onFocus, isFocus, and etc. are things I am still learning to use properly. I opted to implement centering the text this way:

 

 

efPName = new EditField("", "", 30, EditField.FIELD_HCENTER | EditField.NO_NEWLINE) {
     public void paint(Graphics g){
          if (isFocus()) {
               super.paint(g);
          } else {
               g.drawText(efName.toString(), 0, 0, DrawStyle.HCENTER, getContentWidth());
	  }
     }
};

 

I chose to implement what I want this way because it seemed easier to just add the little bit extra to what I have already done. However, would implementing onFocus/onUnfocus be the preferred way? Are there any pros / cons for one way over the other?

 

Developer
Developer
Posts: 42
Registered: ‎02-17-2009
My Device: Not Specified

Re: EditField / Centering user input

I added an invalidate() call to this code. On a touch screen, if you touched the editfied but did not click, the text would shift to the left leaving some of the centered text on the screen to the right of the entered data. I am not sure if it did this on any other device but suspect that it did. The below code seems to have resolved the issue:

 

 

efName = new EditField("", "", 30, EditField.FIELD_HCENTER | EditField.NO_NEWLINE) {
	public void paint(Graphics g){
		if (isFocus()) {
			invalidate();
			super.paint(g);
		} else {
			g.drawText(efName.toString(), 0, 0, DrawStyle.HCENTER, getContentWidth());
		}
	}
};

 

 

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

Re: EditField / Centering user input

Oh, no!

invalidate() schedules the field's repaint, which eventually calls paint(), which calls invalidate(), which schedules a repaint, ...

 

See the problem?

You've created a "soft" infinite loop out of thin air.  It will eat CPU, slowing your other tasks and the system overall.

Just clear the field prior to repainting!  Here is the code:

 

efName = new EditField("", "", 30, EditField.FIELD_HCENTER | EditField.NO_NEWLINE) {
	public void paint(Graphics g){
                g.clear();
		if (isFocus()) {
			super.paint(g);
		} else {
			g.drawText(efName.toString(), 0, 0, DrawStyle.HCENTER, getContentWidth());
		}
	}
};

 Let us know whether it works.

 

----------------------------------------------------------
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
Developer
Posts: 42
Registered: ‎02-17-2009
My Device: Not Specified

Re: EditField / Centering user input

Ouch! I certainly don't want to create an infinite loop or slow a system down. I did try your suggestion of using a clear() call but the issue returns. The clear() does not seem to be clearing the field before repainting the field. I had actually tried using the clear() method before switching to invalidate().

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

Re: EditField / Centering user input

You then might need to add this:

 

protected void onFocus(int direction) {
    super.onFocus(direction);
    invalidate(); // or invalidate(getLeft(), getTop(), getWidth(), getHeight());
}

Wait - there might be another reason you are having trouble: the field calculates its extent based on the text's advance (getFont().getAdvance(getText())) and so thinks there is nothing beyond the last character so it never clears there (and thus paint gets a smaller clipping rectangle than the full field's size).  I do sincerely hope that the onFocus above solves your problem; if it doesn't, try overriding your EditField's layout to add something like this:

 

protected void layout(int w, int h) {
    super.layout(w, h);
    int myWidth = getMaxSize() * getFont().getAdvance('_');  // any widest character will do
    setExtent(Math.min(w, myWidth), getHeight());
}

 

 

 

 

 

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!