Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8092473
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 5, 20262026-06-05T20:17:25+00:00 2026-06-05T20:17:25+00:00

Trying to make a simple number clicker control for BlackBerry 6/7, like this: At

  • 0

Trying to make a simple number clicker control for BlackBerry 6/7, like this:

enter image description here

At heart it’s just a text field and two buttons, with a Manager to space them out.

I know about the unsupported add-on TableManager, but it doesn’t support column scans. And, the notion of using deeply-nested Managers I find… disturbing.

And, this will come up multiple times, so I wanted a simple, reusable component.

So, I built a simple Manager to contain these three components, even allowing you to provide your own textfield or buttons for stylistic reasons. The code is attached below. Obviously fancier than it needs to be but the work is all done in sublayout.

What actually happens is that the upper right of each of the 3 components appears in the correct place, but the 3 components are “shrink wrapped” to the minimum size needed to display their contents, ignoring the requested USE_ALL_WIDTH and USE_ALL_HEIGHT. This is probably a minor goofup, but how can I make these components actually USE ALL WIDTH and USE ALL HEIGHT? I have tried several variations on USE_ALL_* but not found the winning one yet. Of course any other improvements would also be welcome.

Thanks.

package layout;

import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.XYEdges;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.EditField;

/**
 * XXX BROKEN DO NOT USE YET - layout fail, components get shrink-wrapped.
 * 
 * NumberClicker Makes a layout with three components, like this:
 * <pre>
 * +-------------------+ +-------------------+
 * |                   | |          +        |
 * |         3         | |-------------------|
 * |                   | |-------------------|
 * |                   | |          -        |
 * |-------------------| |-------------------|
 * </pre>
 * Note that by default, the buttons are set to increment and decrement the number in the textfield!
 * @author Ian Darwin
 */
public class NumberClicker extends Manager {

    private static final long SUBCOMPONENT_STYLE = Field.USE_ALL_HEIGHT | Field.USE_ALL_WIDTH;
    private static final long MANAGER_STYLE = Field.FIELD_HCENTER | Field.FIELD_VCENTER;

    final XYEdges MARGINS = new XYEdges(10,10,10,10);

    EditField number = new EditField(SUBCOMPONENT_STYLE);
    ButtonField plus = new ButtonField("+", SUBCOMPONENT_STYLE);
    ButtonField minus = new ButtonField("-", SUBCOMPONENT_STYLE);

    public NumberClicker() {
        this(MANAGER_STYLE);
    }
    public NumberClicker(long style) 
    {
        this(null, null, null, style);
    }

    /** Constructor allows you to provide your own three fields */
    public NumberClicker(EditField number, ButtonField plus, ButtonField minus) { 
        this(number, plus, minus, MANAGER_STYLE);
    }

    /** Constructor allows you to provide your own three fields ANd override style.
     * If any of the fields is null, the default value is used.
     */
    public NumberClicker(EditField number, ButtonField plus, ButtonField minus, long style) {
        super(style);
        if (number != null) {
            this.number = number;
        } else {
            this.number.setMargin(MARGINS); // set margins on our default, constructed above.
        }
        setValue(1);
        add(this.number); // Nulls allowed, so must be careful to use "this." throughout this method.

        if (plus != null) {
            this.plus = plus;
        } else {
            this.plus.setMargin(MARGINS);
        }
        add(this.plus);

        if (minus != null) {
            this.minus = minus;
        } else {
            this.minus.setMargin(MARGINS);
        }
        add(this.minus);

        this.plus.setRunnable(new Runnable() {
            public void run() {
                increment();
            }           
        });
        this.minus.setRunnable(new Runnable() {
            public void run() {
                decrement();
            }           
        });
    }

    public void increment() {
        number.setText(Integer.toString(Integer.parseInt(number.getText().trim()) + 1));
    }

    public void decrement() {
        number.setText(Integer.toString(Integer.parseInt(number.getText().trim()) - 1));
    }

    /** Return the integer value of the clicker. Do not call if you are re-using this as a three-component layout manager! */
    public int getValue() {
        return Integer.parseInt(number.getText().trim());
    }

    public void setValue(int value) {
        number.setText(Integer.toString(value));
    }

    /** 
     * Compute sizes and positions of subfields.
     * 
     * Required by Manager 
     */
    public void sublayout(int width, int height)  {
        int layoutWidth = width;
        int layoutHeight = Math.min(height, Display.getHeight()); // no scrolling here
System.err.println("Display:" + Display.getWidth() + "x" + Display.getHeight());

        int halfX = layoutWidth / 2;
        int halfY = layoutHeight / 2;
System.err.println("sublayout:" + width + "," + height + "; " + halfX + "," + halfY);

        int numberWidth = halfX - number.getMarginLeft() - number.getMarginRight();
        int numberHeight = layoutHeight - number.getMarginTop() - number.getMarginBottom();
        layoutChild(number, numberWidth, numberHeight);
        setPositionChild(number, 0 + number.getMarginLeft(), 0 + number.getMarginTop());
System.err.println(number + " " + numberWidth + "," + numberHeight + " " +number.getMarginLeft());

        int plusWidth = halfX - plus.getMarginLeft() - plus.getMarginRight();
        int plusHeight = halfY - plus.getMarginTop() - plus.getMarginBottom();
        layoutChild(plus, plusWidth, plusHeight);
        setPositionChild( plus, halfX + plus.getMarginLeft(), plus.getMarginTop());

        int minusWidth = halfX - minus.getMarginLeft() - minus.getMarginRight();
        int minusHeight = halfY - minus.getMarginTop() - minus.getMarginBottom();
        layoutChild(minus, minusWidth, minusHeight);
        // Use plus.getMarginHeight() for better alignment.
        setPositionChild( minus, halfX + plus.getMarginLeft(), halfY + minus.getMarginTop() );

        //setVirtualExtent(layoutWidth, height);
        setExtent(layoutWidth, height);
    }

    public EditField getNumberField() {
        return number;
    }
    public void setNumberField(EditField number) {
        this.number = number;
    }
    public ButtonField getPlusField() {
        return plus;
    }
    public void setPlusField(ButtonField plus) {
        this.plus = plus;
    }
    public Field getMinusField() {
        return minus;
    }
    public void setMinusField(ButtonField minus) {
        this.minus = minus;
    }
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-05T20:17:26+00:00Added an answer on June 5, 2026 at 8:17 pm

    The closest thing to what you are trying to achieve is

    enter image description here

    Few notes:

    1. EditField always use USE_ALL_WIDTH. It doesn’t matter if you requested it or not. Therefore, if you want to limit its width you have override its layout() method. In my code snippet, its width is limited by the maximum chars allowed for this field’s value (see CustomEditField).

    2. ButtonField ignores USE_ALL_WIDTH and USE_ALL_HEIGHT. Its extent depends only on the text within the button. In order to achieve the effect of USE_ALL_WIDTH, you have to add horizontal padding to it.

    3. Unfortunately, the padding trick won’t work if you want to achieve the USE_ALL_HEIGHT effect. When you add vertical padding to a button, at some stage it will repeat its background vertically. If it is required, you will have to write a custom button field for it.

    Also check BlackBerry’s advanced UI components at this page.

    Here is the code:

    import net.rim.device.api.ui.Font;
    import net.rim.device.api.ui.FontMetrics;
    import net.rim.device.api.ui.Manager;
    import net.rim.device.api.ui.UiApplication;
    import net.rim.device.api.ui.XYEdges;
    import net.rim.device.api.ui.component.ButtonField;
    import net.rim.device.api.ui.component.EditField;
    import net.rim.device.api.ui.decor.Border;
    import net.rim.device.api.ui.decor.BorderFactory;
    import net.rim.device.api.ui.text.NumericTextFilter;
    
    public class NumberClicker extends Manager {
    
        private class CustomEditField extends EditField {
            public int getPreferredWidth() {
                FontMetrics fontMetrics = new FontMetrics();
                getFont().getMetrics(fontMetrics);
                return getMaxSize()*fontMetrics.getMaxCharWidth();
            };
    
            public int getPreferredHeight() {
                // forcing the field to be single lined
                return getFont().getHeight();
            }
    
            protected void layout(int width, int height) {
                super.layout(
                    Math.min(width, getPreferredWidth()),
                    Math.min(height, getPreferredHeight())
                );
            }
        }
    
        final XYEdges MARGINS = new XYEdges(2,2,2,2);
    
        EditField _number;
        Manager _numberManager;
    
        ButtonField _plus;
        ButtonField _minus;
    
    
        public NumberClicker() {
            super(0);
    
            Font font = getFont();
            font = font.derive(Font.BOLD, font.getHeight() + 10);
            _number = new CustomEditField();
            _number.setFilter(new NumericTextFilter());
            _number.setMaxSize(1);
            _number.setFont(font);
            setValue(1);
    
            _numberManager = new Manager(0) {
                protected void sublayout(int width, int height) {           
                    layoutChild(_number, width, height);
                    setPositionChild(_number, 
                        Math.max(0, (width - _number.getWidth())/2), 
                        Math.max(0, (height - _number.getHeight())/2)
                    );
                    setExtent(width, height);
                }
            };
    
            _numberManager.setBorder(BorderFactory.createRoundedBorder(new XYEdges()));
            _numberManager.setMargin(MARGINS);
            _numberManager.add(_number);
            add(_numberManager);
    
            _plus = new ButtonField("+", 0);
            _plus.setMargin(MARGINS);
            add(_plus);
    
            _minus = new ButtonField("-");
            _minus.setMargin(MARGINS);
            add(_minus);
    
            _plus.setRunnable(new Runnable() {
                public void run() {
                    increment();
                }           
            });
    
            _minus.setRunnable(new Runnable() {
                public void run() {
                    decrement();
                }           
            });
        }
    
        private void increment() {
            synchronized (UiApplication.getEventLock()) { //probably not needed here. overkill.
                _number.setText(Integer.toString(Integer.parseInt(_number.getText().trim()) + 1));
            }
        }
    
        private void decrement() {
            if (Integer.parseInt(_number.getText()) <= 0) {
                return;
            }
    
            synchronized (UiApplication.getEventLock()) { //probably not needed here. overkill.
                _number.setText(Integer.toString(Integer.parseInt(_number.getText().trim()) - 1));
            }
        }
    
        public void setValue(int value) {
            if (value < 0) {
                return;
            }
    
            synchronized (UiApplication.getEventLock()) { // MUST. can be called from non UI thread.
                _number.setText(Integer.toString(value));
            }
        }
    
        /** 
         * Compute sizes and positions of subfields.
         */
        public void sublayout(int width, int height)  {
            int heightUsed = 0;
            int halfX = width / 2;
    
            Border border = _plus.getBorder();
            int plusWidth = halfX - _plus.getMarginLeft() - _plus.getMarginRight();
            int plusHeight = height - _plus.getMarginTop() - _plus.getMarginBottom();
    
            // calculate horizontal padding so the button will look like USE_ALL_WIDTH
            int plusHPadding = (Math.max(0, plusWidth - _plus.getPreferredWidth() - border.getLeft() - border.getRight()))/2;
            _plus.setPadding(0, plusHPadding, 0, plusHPadding);
    
            layoutChild(_plus, plusWidth, plusHeight);
            setPositionChild( _plus, halfX + _plus.getMarginLeft(), _plus.getMarginTop());
            heightUsed += _plus.getHeight() + _plus.getMarginTop() + _plus.getMarginBottom();
    
            border = _minus.getBorder();
            int minusWidth = halfX - _minus.getMarginLeft() - _minus.getMarginRight();
            int minusHeight = height - _plus.getHeight() - _minus.getMarginTop() - _minus.getMarginBottom();
    
            // calculate horizontal padding so the button will look like USE_ALL_WIDTH
            int minusHPadding = (Math.max(0, minusWidth - _minus.getPreferredWidth() - border.getLeft() - border.getRight()))/2; 
            _minus.setPadding(0, minusHPadding, 0, minusHPadding);
    
            layoutChild(_minus, minusWidth, minusHeight);
            setPositionChild( _minus, halfX + _plus.getMarginLeft(), heightUsed + _minus.getMarginTop());
            heightUsed += _minus.getHeight() + _minus.getMarginTop() + _minus.getMarginBottom();
    
            int numberWidth = halfX - _numberManager.getMarginLeft() - _numberManager.getMarginRight();
            int numberHeight = heightUsed - _numberManager.getMarginTop() - _numberManager.getMarginBottom();
            layoutChild(_numberManager, numberWidth, numberHeight);
            setPositionChild(_numberManager, _numberManager.getMarginLeft(), _numberManager.getMarginTop());
    
            setExtent(width, heightUsed);
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Trying to make a simple program to catalogue books. Something like this, for example:
Trying to make a simple program to catalogue books. Something like this, for example:
Trying to make this simple applet - the first part just creates a simple
I am trying to make a simple game. The logic is like this: There
I'm trying to make a simple Cocoa application where a number is input into
I'm trying to make a simple Scheme interpreter in Haskell. As part of this,
I am trying to make a simple guess my number game in c++ but
I'm trying to make a simple Vector class (math) this way: template <int D,
I'm trying to make the cells of a QTableView look like 3D clickable buttons.
I'm trying to make a simple javascript application to pick a random number between

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.