Sample Code - Scrollable one-line text input field

by Developer on ‎07-29-2010 12:29 PM - edited on ‎09-20-2010 04:58 PM by BlackBerry Development Advisor (15,431 Views)

One of the standard graphical input gadgets is a one-line text input field, potentially scrollable (because it might contain more characters than can be displayed on the screen yet the GUI designed does not want it to start wrapping around and pushing other fields down).  Anyone who has ever edited PATH environment variable under Windows® has seen this kind of a UI element.

 

On BlackBerry® device, the default implementation of TextField and its descendants wraps around once the text advance inside exceeds the maximum available width.  Besides, pressing ENTER key inserts a new line which requires some new vertical space all by itself.  How do we address these two points?  Can we manage without resorting to some sophisticated paint(), layout() and keyChar() overrides?

 

The answer is a resounding "Yes!"  We can do both using only the BlackBerry device primitives (which are written in native code and are thus much more efficient than custom fields we might create).

 

1.  Making the field never wrap to the next line:

This is achieved by telling the input field that it has enough width for all the characters it can hold.  A HorizontalFieldManager with HORIZONTAL_SCROLL style bit set will let its managed fields have next to unlimited width (for a total of 0x3FFFFFFF, I believe).  And, naturally, it will handle scrolling of the field(s) just fine - that's what HORIZONTAL_SCROLL is for.

2. Disabling ENTER key:

NO_NEWLINE style bit of the TextField disables having new lines in the input completely, including stripping them from initial values and copy/pasted text.  Just what we wanted!

 

Let's create some code:

 

public class OneLineTextField extends HorizontalFieldManager {
    private EditField _editField;

    public OneLineTextField(String label, String initialValue, int maxChars, long style) {
        super(HORIZONTAL_SCROLL);
        editField = new EditField(label, initialValue, maxChars, style | EditField.NO_NEWLINE | EditField.FOCUSABLE | EditField.EDITABLE);
        add(editField);
    }

    public String getText() {
        return editField.getText();
    }
    ...
}

 

Ellipsis denotes other methods potentially delegated to the editField just like getText above.

 

Wow!  Is that it?  Let's test and see:

2940i5107D31F34064BF3

 

Gray field is a label field where I redisplay the content of the OneLineTextField in order to see that it is stored and extracted correctly.

 

Let's type some more:

2941iE01E9F5E1B0667DC

 

Oops! Where is our label?  Hey, it scrolled along with the rest of the field!  Was that what we wanted?

 

Let's specify our goal a little more formally.  Now we want a non-scrolling (docked) label with the scrolling one-line input field.  IHow do we achieve this goal?

 

In order for the label to be non-scrolling, it has to be managed by a non-scrolling manager.  On the other hand, input text needs a scrolling manager around it.  After thinking for a while we decide that our whole field will be a non-scrollable HorizontalFieldManager (for the label to be beside the text and not above/below) with a LabelField (label) and a scrollable HorizontalFieldManager in turn managing an EditField.  Something like this:

 

public class OneLineTextField extends HorizontalFieldManager {
    private EditField _editField;

    public OneLineTextField(String label, String initialValue, int maxChars, long style) {
        super(NO_HORIZONTAL_SCROLL);
        HorizontalFieldManager textMgr = new HorizontalFieldManager(HORIZONTAL_SCROLL);
        add(new LabelField(label));
        _editField = new EditField("", initialValue, maxChars, style | EditField.NO_NEWLINE | EditField.FOCUSABLE | EditField.EDITABLE);
        textMgr.add(_editField);
        add(textMgr);
    }

    public String getText() {
        return _editField.getText();
    }
}

 Let's look at the results:

2942i899327C0B7A2944F

 

Same as before.  How about typing a little more?

 

2943iB677CE9C2DC626F7

 

Hey, that's better!  The label stayed put this time while the input text scrolled as it should.  And everything under 20 (!) lines of code.