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
Regular Contributor
Posts: 91
Registered: ‎11-10-2009
My Device: BB 9810
My Carrier: Generic
Accepted Solution

Scrolling issue in SingleLineTextField

[ Edited ]

img.pngHi,

 

I am facing a verry strang issue in my custom SingleLineTextField,

 

Whenever some other filed is focus other that  SingleLineTextField, and i do key/Trackpad nevigation in touch devices, text in SingleLineTextField getting scroll.

 

I tried even removing/add ScrollChangeListener on field focus, blocking navigation with booleans, but still text in   SingleLineTextField get scroll.

 

I have attached the code.

 

 

 

public class SingleLineTextField extends HorizontalFieldManager {

	private int managerWidth;
	private int managerHeight;
	private EditField _editField;
	private Font font;
	private String mInitialText = null;

	private HorizontalFieldManager horizontalHolderManager;

	private boolean isNavMovement;

	public SingleLineTextField(int width, long style) {
		this(width, style, null);
	}

	public SingleLineTextField(int width, long style, Border border) {
		super(Manager.NO_HORIZONTAL_SCROLL | style);

		managerWidth = width;
		font = Font.getDefault();

		if (border != null) {
			this.setBorder(border);
		}
		initMainScrollManager(style);

	}

	public SingleLineTextField(String initialText, int width, long style, Border border) {
		super(Manager.NO_HORIZONTAL_SCROLL | style);

		managerWidth = width;
		font = Font.getDefault();

		if (border != null) {
			this.setBorder(border);
		}
		initMainScrollManager(style);
		mInitialText = initialText;
	}

	private void initMainScrollManager(long style) {
		horizontalHolderManager = new HorizontalFieldManager(Manager.HORIZONTAL_SCROLL) {
			public void sublayout(int width, int height) {
				managerHeight = this.getFont().getHeight() + 8;

				if (managerWidth == 0) {
					managerWidth = width;
				}
				if (managerHeight == 0) {
					managerHeight = height;
				}
				if (_editField != null && equals(_editField.getManager())) {
					int x = this.getExtent().x;
					int y = this.getExtent().y;

					setPositionChild(_editField, x, y + 4);

				}
				super.sublayout(managerWidth - 8, managerHeight - 2);
				setExtent(managerWidth - 8, managerHeight - 2);
			}
			
			protected boolean navigationMovement(int dx, int dy, int status, int time) {
				if (!_editField.isFocus()) return true;
				if (dx > 0 && (_editField != null) && (_editField.getText().trim().length() < _editField.getCursorPosition())) {
					if (dy != 0) { return super.navigationMovement(dx, dy, status, time); }
					return true;
				} else if (dx > 0 && (_editField != null) && (_editField.getText().trim().length() == _editField.getCursorPosition())) {

				return true; }
				return super.navigationMovement(dx, dy, status, time);
			}
			
		};
		if (mInitialText == null) {
			_editField = new EditField(style | EditField.NO_COMPLEX_INPUT) {
				protected boolean keyChar(char key, int status, int time) {
					if (key == Characters.ENTER)
						return true;
					else
						return super.keyChar(key, status, time);
				}

				public void paint(Graphics graphics) {
					int color = graphics.getBackgroundColor();
					if (color == Color.BLACK) graphics.setBackgroundColor(Color.WHITE);
					graphics.setColor(Color.BLACK);
					graphics.setFont(font);
					super.paint(graphics);

				}
				protected void onFocus(int direction) {
					SingleLineTextField.this.setScrollListener(scrollChangeListener1);
					horizontalHolderManager.setScrollListener(scrollChangeListener);
					super.onFocus(direction);
				};
				
				protected void onUnfocus() {
					SingleLineTextField.this.setScrollListener(null);
					horizontalHolderManager.setScrollListener(null);
					super.onUnfocus();
				};
				
				protected void fieldChangeNotify(int context) {
					super.fieldChangeNotify(context);
					UiApplication.getUiApplication().invokeLater(new Runnable() {
						public void run() {
							counterChange();
						}
					});

				}
				
				protected boolean navigationMovement(int dx, int dy, int status, int time) {
					if (!_editField.isFocus()) return true;					
					return super.navigationMovement(dx, dy, status, time);
				}

				/*protected void drawFocus(Graphics graphics, boolean on) {
					graphics.setColor(Color.ORANGE);
					XYRect xy = new XYRect();
					getFocusRect(xy);
					graphics.fillRect(xy.x, xy.y, xy.width, xy.height);
					paint(graphics);
				}*/

			};
		} else {
			_editField = new EditField("", mInitialText, EditField.DEFAULT_MAXCHARS, style) {
				protected boolean keyChar(char key, int status, int time) {
					if (key == Characters.ENTER)
						return true;
					else
						return super.keyChar(key, status, time);
				}

				public void paint(Graphics graphics) {
					int color = graphics.getBackgroundColor();
					if (color == Color.BLACK) graphics.setBackgroundColor(Color.WHITE);
					graphics.setFont(font);
					super.paint(graphics);

				}

				protected void fieldChangeNotify(int context) {
					super.fieldChangeNotify(context);
					UiApplication.getUiApplication().invokeLater(new Runnable() {
						public void run() {
							counterChange();
						}
					});

				}

				protected void onFocus(int direction) {
					horizontalHolderManager.setScrollListener(scrollChangeListener);
					super.onFocus(direction);
				};
				
				protected void onUnfocus() {
					horizontalHolderManager.setScrollListener(null);
					super.onUnfocus();
				};
				
				protected boolean navigationMovement(int dx, int dy, int status, int time) {
					if (!_editField.isFocus()) return true;					
					return super.navigationMovement(dx, dy, status, time);
				}
				
				/*protected void drawFocus(Graphics graphics, boolean on) {
					graphics.setColor(Color.ORANGE);
					XYRect xy = new XYRect();
					getFocusRect(xy);
					graphics.fillRect(xy.x, xy.y, xy.width, xy.height);
					paint(graphics);
				}*/

			};
		}
		_editField.setPadding(3, 10, 5, 5);

		horizontalHolderManager.add(_editField);
		add(horizontalHolderManager);
	}
 
	ScrollChangeListener scrollChangeListener = new ScrollChangeListener() {

		public void scrollChanged(Manager manager, int newHorizontalScroll, int newVerticalScroll) {

			if (Touchscreen.isSupported()) {
				if (!isNavMovement) {
					int editFieldLength = _editField.getFont().getAdvance(_editField.getText());

					if (editFieldLength > managerWidth) {
						int dx = editFieldLength - managerWidth;
						if (newHorizontalScroll > dx && (dx + 20) > 0) {
							horizontalHolderManager.setHorizontalScroll(dx + 20);
						}
					} else if (editFieldLength <= managerWidth) {
						horizontalHolderManager.setHorizontalScroll(0);
					}
				}
			}

		}
	};
	
	
	ScrollChangeListener scrollChangeListener1 = new ScrollChangeListener() {
		
		public void scrollChanged(Manager manager, int newHorizontalScroll, int newVerticalScroll) {
		}
	};
	
	
	public void counterChange() {

	}

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

	public void setCursorPosition(int position) {
		_editField.setCursorPosition(position);
	}

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

	public void setText(String text) {
		_editField.setText(text);
	}

	public void sublayout(int width, int height) {
		if (managerWidth == 0) {
			managerWidth = width;
		}
		if (managerHeight == 0) {
			managerHeight = height;
		}
		if (horizontalHolderManager != null && equals(horizontalHolderManager.getManager())) {
			int y = this.getExtent().y;
			setPositionChild(horizontalHolderManager, 5, y);
		}
		super.sublayout(managerWidth, managerHeight);
		setExtent(managerWidth, managerHeight);
	}

	public void setTextFont(Font font) {
		this.font = font;
	}

	protected boolean navigationMovement(int dx, int dy, int status, int time) {
		if (!_editField.isFocus()) return true;
		isNavMovement = true;
		if (dx > 0 && (_editField != null) && (_editField.getText().trim().length() < _editField.getCursorPosition())) {
			if (dy != 0) { return super.navigationMovement(dx, dy, status, time); }
			return true;
		}
		return super.navigationMovement(dx, dy, status, time);
	}

	protected boolean touchEvent(TouchEvent message) {
		isNavMovement = false;
		return super.touchEvent(message);
	}

	public int getPreferredWidth() {		
		return managerWidth;
	}

	public int getCursorPosition() {
		return _editField.getCursorPosition();
	}

	public void setTextFilter(TextFilter textFilter) {
		_editField.setFilter(textFilter);
	}

	public void setMaxLength(int length) {
		_editField.setMaxSize(length);
	}
	
	
}

 

 

Kamalesh
Highlighted
Super Contributor
Posts: 278
Registered: ‎11-04-2010
My Device: 4.5 and above
My Carrier: none

Re: Scrolling issue in SingleLineTextField

Hi,

 

Check this,,

 

public class TextboxField extends Manager implements FocusChangeListener {
    private int backgroundColor = -1;
    private Bitmap backgroundImage = null;
    private int foregroundColor = -1;
    private int fieldWidth = 0;
    private int fieldHeight = 0;
    private String text = "";
    private Font font = Font.getDefault();
    private EditField editField;
    private PasswordEditField pwdField;
	
	public TextboxField(String text, long style, boolean isPassword, int width, int height) { 
        super(NO_VERTICAL_SCROLL | NO_HORIZONTAL_SCROLL);   
		this.fieldWidth = width;
		this.fieldHeight = height;
		HorizontalFieldManager textMgr = new HorizontalFieldManager(HORIZONTAL_SCROLL);
            if(isPassword){
                pwdField = new PasswordEditField("", text, Integer.MAX_VALUE, style);
                textMgr.add(pwdField);
            } else {
                editField = new EditField("", text, Integer.MAX_VALUE, style | EditField.EDITABLE | EditField.NO_NEWLINE | EditField.FOCUSABLE | EditField.NO_COMPLEX_INPUT);
                textMgr.add(editField);
                editField.setFocusListener(this);
            }
            add(textMgr);
    }
	public void focusChanged(Field field, int eventType) {
        if (eventType == FOCUS_GAINED) {
            invalidate();
        } else if (eventType == FOCUS_LOST) {
            invalidate();
        }
    }
    public void sublayout(int width, int height) {         
        Field field = getField(0);  
        layoutChild(field, this.fieldWidth-15, this.fieldHeight);  
        int fieldYPos = 0;
        if(!isMultiline){
            fieldYPos = (fieldHeight - font.getHeight())/2;
        }
        setPositionChild(field, 10, fieldYPos);
        setExtent(getPreferredWidth(), getPreferredHeight());
    }
    
    public int getPreferredWidth(){
        return this.fieldWidth;
    }
    public int getPreferredHeight(){
        return this.fieldHeight;
    }
    
    public void paint(Graphics g) {
        if(isFocus()){
            g.setColor(Color.DARKBLUE);
            g.fillRect(0, 0, getPreferredWidth(), getPreferredHeight());
        } 
        if(backgroundColor != -1){
            g.setColor(backgroundColor);
            g.fillRect(1, 1, getPreferredWidth()-2, getPreferredHeight()-2);
        }
        if(backgroundImage != null){
            g.setColor(backgroundColor);
            g.fillRect(1, 1, getPreferredWidth()-2, getPreferredHeight()-2);
        }
        if(font != null){
            g.setFont(font);
        }
        if(foregroundColor != -1){
            g.setColor(foregroundColor);
        }else{
            g.setColor(g.getColor());
        }
        super.paint(g);
    }
    public String getText(){
        Manager man = (Manager)getField(0);
        return ((BasicEditField)man.getField(0)).getText();
    }
    public void setText(String text) {
        ((BasicEditField)getField(0)).setText(text);
    } 
    public boolean isFocusable(){
        return true;
    }
    protected void onFocus(int direction) {
        super.onFocus(direction);  
        invalidate(); 
    }
    protected void onUnfocus() {
        super.onUnfocus();   
        invalidate();  
    }
    protected boolean keyChar(char ch, int status, int time){
        if (ch == Characters.ENTER){
            return true;
        } else {
            return super.keyChar(ch, status, time);
        }
    }
	
    public void SetFont(Font font){
        this.font = font;
        super.setFont(font);
    }
    public void setFieldWidth(int fieldWidth){
        this.fieldWidth = fieldWidth;
    }
    public void setFieldHeight(int fieldHeight){
        this.fieldHeight = fieldHeight;
    }
    public void setBackgroundColor(int backgroundColor){
        this.backgroundColor = backgroundColor;
    }
    public int getBackgroundColor(){
        return this.backgroundColor;
    }
    public void setBackgroundImage(Bitmap bg_img){
        if(bg_img != null){
            this.backgroundImage = bg_img;   
        }else{     
            this.backgroundImage = null;
        }
    }
    public Bitmap getBackgroundImage(){
        return backgroundImage;
    }
    public void UpdateLayout(){
        updateLayout();
        invalidate();
    }
    public void Invalidate(){
        invalidate();
    }
	//#ifdef JDE_4_7_0 
    /**
     * <description> handle touch event for above 4.7 device
     * @param message <description>
     * @return <description>
     */
    protected boolean touchEvent( TouchEvent message )
    {
        int x = message.getX( 1 );
        int y = message.getY( 1 );
        if( x < 0 || y < 0 || x > getExtent().width || y > getExtent().height ) {
            // Outside the field
            return false;
        }
        switch( message.getEvent() ) {
       
            case TouchEvent.UNCLICK:
                //clickButton();
                return true;
            case TouchEvent.DOWN:
                {
                    setFocus();
                    invalidate();
                    clickButton();
                    return true;
                }
        }
        return super.touchEvent( message );
    }
    //#endif 
    
    /**
     * <description> handle click events
     * @param status <description>
     * @param time <description>
     * @return <description>
     */
    protected boolean trackwheelClick( int status, int time ){        
        clickButton();    
        return true;
    }
    protected boolean navigationClick( int status, int time ) {
        clickButton(); 
        return true;    
    }
    public void clickButton() {
        fieldChangeNotify( 0 );
    }
}

 Regards,

 pp

Regular Contributor
Posts: 91
Registered: ‎11-10-2009
My Device: BB 9810
My Carrier: Generic

Re: Scrolling issue in SingleLineTextField

Hello PP,

 

I tried your code even but that also have same issue. 

 

Kamalesh
Regular Contributor
Posts: 91
Registered: ‎11-10-2009
My Device: BB 9810
My Carrier: Generic

Re: Scrolling issue in SingleLineTextField

Bump!

Kamalesh
Regular Contributor
Posts: 91
Registered: ‎11-10-2009
My Device: BB 9810
My Carrier: Generic

Re: Scrolling issue in SingleLineTextField

Bump!

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

Re: Scrolling issue in SingleLineTextField

Something immediately suspicious is this line in your navigationMovement:

if (!_editField.isFocus()) return true;

It means that if you are not focused, you consume the event! That's the opposite of how you should handle it. Return false there.

 

Your two adjacent checks of (dx > 0 && _editField != null && _editField.getText().trim()... ) (one checks for less than, another checks for equal, the action is the same) can be combined into one with <= (less than or equal).

 

Your equals._editField.getManager() is redundant - you are not adding _editField to anything else.

 

super.sublayout followed by setExtent is very risky - you are just confusing the super class. Remove setExtent - it is set properly by super.sublayout anyway.

 

So a lot of this code is problematic and it's hard to pinpoint the exact problem. Moreover, there is a knowledge base article which provides a good starting point for exactly this kind of gadget:

Scrollable one-line text input field

 

Make sure to read the comments - they discuss borders and some other stuff. Besides, that article is referenced in many threads here, where people discuss problems and potential fix. See if it suits you.

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
Regular Contributor
Posts: 91
Registered: ‎11-10-2009
My Device: BB 9810
My Carrier: Generic

Re: Scrolling issue in SingleLineTextField

Thanks arkadyz,

 

yah you are right that code is ill written, its got more problematic in order to fix the issue.

 

I will get back once I optimized it with your reference link

Kamalesh
Regular Contributor
Posts: 91
Registered: ‎11-10-2009
My Device: BB 9810
My Carrier: Generic

Re: Scrolling issue in SingleLineTextField

Hello arkadyz,

 

My original problem is solve, thanks for your great help.

 

Now one issue is left in this, on touch devices if I touch and drag the text of edit field its getting invisible from screen.

(in my screen editfield width is half of the screen, you can see the attached image on top)

public class SingleLineTextField extends HorizontalFieldManager {

	private EditField _editField;
	private int managerWidth;
	private int managerHeight;

	public SingleLineTextField(int width, long style) {
		super(Manager.NO_HORIZONTAL_SCROLL | style);
		managerWidth = width;
		init(style);
	}

	public SingleLineTextField(int width, long style, Border border) {
		super(Manager.NO_HORIZONTAL_SCROLL);
		if (border != null) {
			this.setBorder(border);
		}
		init(style);
	}

	HorizontalFieldManager horizontalHolderManager;

	private void init(long style) {
		horizontalHolderManager = new HorizontalFieldManager(HORIZONTAL_SCROLL) {
			public int getPreferredHeight() {
				managerHeight = this.getFont().getHeight() + 5;
				return managerHeight;
			};

			public int getPreferredWidth() {
				return managerWidth;
			};

			protected void sublayout(int width, int height) {
				super.sublayout(getPreferredWidth(), getPreferredHeight());
			};
		};
		_editField = new EditField(style | EditField.NO_NEWLINE | EditField.FOCUSABLE | EditField.EDITABLE) {

			public void paint(Graphics graphics) {
				int color = graphics.getBackgroundColor();
				if (color == Color.BLACK) graphics.setBackgroundColor(Color.WHITE);
				graphics.setColor(Color.BLACK);
				super.paint(graphics);
			}

			protected void fieldChangeNotify(int context) {
				super.fieldChangeNotify(context);
				UiApplication.getUiApplication().invokeLater(new Runnable() {
					public void run() {
						counterChange();
					}
				});
			}

			protected boolean navigationMovement(int dx, int dy, int status, int time) {
				if (dx > 0 && (_editField.getText().trim().length() <= _editField.getCursorPosition())) {
					if (dy != 0) { return super.navigationMovement(dx, dy, status, time); }
					return true;
				}
				return super.navigationMovement(dx, dy, status, time);
			}

		};

		_editField.setPadding(3, 10, 5, 5);
		horizontalHolderManager.add(_editField);

		add(horizontalHolderManager);
	}

	public void counterChange() {

	}

	public void setCursorPosition(int position) {
		_editField.setCursorPosition(position);
	}

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

	public void setText(String text) {
		_editField.setText(text);
	}

	public void setTextFont(Font font) {
		_editField.setFont(font);
	}

	public int getCursorPosition() {
		return _editField.getCursorPosition();
	}

	public void setTextFilter(TextFilter textFilter) {
		_editField.setFilter(textFilter);
	}

	public void setMaxLength(int length) {
		_editField.setMaxSize(length);
	}

}

 

 

I am again posting my refined code.

Kamalesh
Super Contributor
Posts: 278
Registered: ‎11-04-2010
My Device: 4.5 and above
My Carrier: none

Re: Scrolling issue in SingleLineTextField

Hi,

SingleLineTextField should extends Manager and override sublayout to stay child inside it only. and add editfield to hfm and hfm to this SingleLineTextField , Then it works... and also no need to override navigationMovement in editfield. just make changes on onFocus setCursorPosition... some thing like this.

Regards,
pp
Regular Contributor
Posts: 91
Registered: ‎11-10-2009
My Device: BB 9810
My Carrier: Generic

Re: Scrolling issue in SingleLineTextField

[ Edited ]

Hello PP,

 

Despite of all these text inside "SingleLineTextField" gets scroll, if just do a navigation movement on any button/choice field.(you can see the attached image in very first post of this topic)

 

I am unable to find any clue that why even if SingleLineTextField is not focused text is getting scroll.

 

It is happening on 6 OS onward i have checked on 9810, 9900, 9800

 

Kamalesh