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
tklanilkumar
Posts: 206
Registered: ‎02-22-2011
My Device: BB TORCH & 9800
My Carrier: idea

Re: Issue of verticalfieldmanager with the LableField

override getPreferredHeight() in LabelField inorder to restrict height.
*****************************************************************************
* Give kudos when you like it
* Mark it as a solution if it fixes your issue
Please use plain text.
Developer
bskania
Posts: 105
Registered: ‎04-24-2012
My Device: blackberry developer
My Carrier: relience

Re: Issue of verticalfieldmanager with the LableField

Thanks
Please use plain text.
Developer
tklanilkumar
Posts: 206
Registered: ‎02-22-2011
My Device: BB TORCH & 9800
My Carrier: idea

Re: Issue of verticalfieldmanager with the LableField

feel free to give kudos if it works.
*****************************************************************************
* Give kudos when you like it
* Mark it as a solution if it fixes your issue
Please use plain text.
Developer
peter_strange
Posts: 19,603
Registered: ‎07-14-2008
My Device: Not Specified

Re: Issue of verticalfieldmanager with the LableField

You can use setStatus on a MainScreen if you wish to anchor Fields t the bottom.

 

More in here:

http://supportforums.blackberry.com/t5/Java-Development/MainScreen-explained/ta-p/606644

 

Also make sure you are testing this code in a non touchscreen device.  Scrolling works differently on these devices.

Please use plain text.
Developer
pankajace12
Posts: 198
Registered: ‎04-30-2011
My Device: BlackBerry Z10
My Carrier: Airtel

Re: Issue of verticalfieldmanager with the LableField

Hey bskania,

If my code did really help you, then feel free to press kudo.


Please use plain text.
Developer
bskania
Posts: 105
Registered: ‎04-24-2012
My Device: blackberry developer
My Carrier: relience

Re: Issue of verticalfieldmanager with the LableField

Hey I am not able to scroll with this code in the Blackberry 8900.
I mean the device not having touchscreen support.

sorry for disturbing you again.

thanks, In advance.
Please use plain text.
Developer
pankajace12
Posts: 198
Registered: ‎04-30-2011
My Device: BlackBerry Z10
My Carrier: Airtel

Re: Issue of verticalfieldmanager with the LableField

Hey, it was working, after doing i did give you code.

did you test it on device.
Please use plain text.
Developer
peter_strange
Posts: 19,603
Registered: ‎07-14-2008
My Device: Not Specified

Re: Issue of verticalfieldmanager with the LabelField

[ Edited ]

I would just like to issue a note of caution to future readers of this Thread.  There is, in my opinion, some dubious code and options presented here.

 

Remember when using LabelField, that it is either not focusable (default), or if you make it focusable (for example LabelField focusable LabelField = new LabelField("txt",LabelField.FOCUSABLE); ) - the entire field gets focus.  Typically on touch screen devices this is not a problem because you can scroll the Manager using the touch gestures - the Manager takes care of that.  However if you are not on a touchscreen device, or you try using the trackpad on a touchscreen device, the scrolling will probably work funny, if indeed it works at all.

 

As a general rule, I recommend that you use RichTextField instead.  if you do not want the 'focus indicator' to appear, as it does on RichTextField, then you can override drawFocus() I think (though I have never done it). 

 

One option to restrict the amount of space that a Field takes on the screen, but still enable a user to see the whole field, is to add the Field to a VerticalFieldManager and restrict the height of this VFM, but make sure it has vertical scrolling.  This is what has been done in the code from the Post that has been marked as the solution:

http://supportforums.blackberry.com/t5/Java-Development/Issue-of-verticalfieldmanager-with-the-Lable...

 

The relevant code is:

 

VerticalFieldManager _vfm = new VerticalFieldManager(VerticalFieldManager.VERTICAL_SCROLL ){

 protected void sublayout(int width,int height)
 {
  super.sublayout(Display.getWidth(),200);
  super.setExtent(Display.getWidth(),200);
 }
};

 

However I am dubious that this code actually works.  I think the LabelField will still not be scrollable using the trackpad only. 

 

In addition, I would suggest that this code does not need the setExtent, and in fact that could cause issues if the enclosed Field(s) did not reach the magic 200 pixel height (why 200?).  And this code assumes the VFM can use the whole width, which it might not be able to do.  I think this would be better coded as:

 

VerticalFieldManager _vfm = new VerticalFieldManager(VerticalFieldManager.VERTICAL_SCROLL ){

 protected void sublayout(int width,int height)
 {
  super.sublayout(width,Math.min(200,height));
 }
};

 

I think the point of this was to make sure that there was space left at the bottom of the screen for some other Fields.  IN an attempt to do this, another post had this code:

 

 protected void sublayout(int width,int height)
 {
  super.sublayout(Display.getWidth(),(Display.getHeight() -button.getPrefferedheight())); // method name is wrong
  super.setExtent(Display.getWidth(),(Display.getHeight() -button.getPrefferedheight()));
 }

 

Unfortunately there are likely to be a number of problems with this code, most likely that at the time the sublayout was called the button had not actually been laid out.  It is more accurate to get the button's actual size (getHeight()) rather than its preferred size.  And buttons change height in different devices so you can't (or shouldn't) fix the height. 

 

If you do want to do this sort of processing, I think you have to manage all the Fields yourself.  And have the Manager layout the Fields that are at the bottom first, then subtract that from the height that it has available.  Only then can you layout the 'middle' areas.

 

Alternatively use existing facilities like MainScreen's setStatus.

 

Just to be clear, I'm not saying anything here is wrong.  What I am saying is future readers of this Thread should treat the code and options supplied here with caution, since, at least to me, it seems they are not as robust as they could be.

 

Hope this helps someone. 

Please use plain text.
Developer
pankajace12
Posts: 198
Registered: ‎04-30-2011
My Device: BlackBerry Z10
My Carrier: Airtel

Re: Issue of verticalfieldmanager with the LabelField

HI peter

 

I am very happy with your suggestion. Its good.

Thanks 

Please use plain text.
Developer
arkadyz
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: Issue of verticalfieldmanager with the LabelField

While I was typing my response, the thread was marked solved. Still, I feel that I can provide enough useful information for the OP and others, so here it goes:

 

Even though this discussion is already long enough, I've seen a lot of strange suggestions here (as Peter Strange has pointed out) and a lot of misunderstanding. Let me try to clear the confusion and explain a few things. My main goal is not just to provide you with a solution but to help you find such solutions on your own in the future. It will be a rather long post, but I'll try to make it useful.

 

To make things clearer, let's move back to square one. I will first restate the problem:

 

Problem

1. You have a LabelField with a very long text, not fitting on the screen (potentially longer than 2 screens - this actually matters, as anything less than that allows some "quick and dirty" solution). You would like to scroll through it so that the user can view the whole text and not just some part(s) of it.

2. In addition, you would like this scrolling text to occupy less than the full screen, leaving some room for a button or two on the bottom.

 

These two are totally separate problems. The second one is in fact much easier to solve, so I'll start with that:

 

Solution for the problem #2

Add the buttons you want to display to a horizontal field manager and use that manager as an argument in your MainScreen's setStatus. Again, as Peter mentioned already, you can find more details here: MainScreen explained

There are also ways to explicitly limit the height of your VerticalFieldManager containing the LabelField. Peter has provided some of that code in his recent reply. For those who are curious, I will explain it in more details in Bonus Section 1.

 

Solution for the problem #1

There is one thing that you should understand before tackling this problem: BlackBerry has its own autoscrolling mechanism which works fine in most cases but not in this specific one. This mechanism works only for scrolling Managers and reacts to setFocus and focusAdd by making sure the currently focused Field's focus rectangle (returned by getFocusRect) is visible.

 

So the first thing you have to do is to make sure your LabelField is added to a scrolling Manager. If you are using MainScreen with all default settings, this will be true automatically - but it might not be the best approach if you are using the setVerticalScroll solution below. Again, read the "MainScreen Explained" article and check "Using style bits for customization" section to find out more.

 

Since LabelField reports its whole extent as focus rectangle, making use of getFocusRect mechanism with it will be a non-trivial exercise. Switching from LabelField to (Rich)TextField, though, gives you this exact solution. If you can live with it, this is the best course of action.

 

However, you don't have to satisfy yourself with the auto-scrolling provided by RIM. All Managers havegetVerticalScroll method to find out the current scrolling position as well as setVerticalScroll method to set it. So you can capture the vertical navigation events and make intelligent decisions about whether to programmatically scroll your Manager or let the system handle it.

So, first of all - make your LabelField FOCUSABLE. Then add it to the following Manager:

VerticalFieldManager speciallyScrollingMgr = new VerticalFieldManager(VERTICAL_SCROLL | VERTICAL_SCROLLBAR) {
  protected boolean navigationMovement(int dx, int dy, int status, int time) {
    // vertical movement while my label is focused?
    if ((getFieldWithFocus() == myLabelField) && (dy != 0)) {
      // Obtain the label rectangle for later checks - see below
      XYRect labelRect = new XYRect();
      myLabelField.getRect(labelRect);

      int fontHeight = myLabelField.getFont().getHeight();
      // shift by the number of text "rows" according to dy
      int newScrollPos = getVerticalScroll() + dy * fontHeight;

      // Next two ifs check whether we've scrolled past the text
      // Down movement and below the bottom of the label?
      if (dy > 0 && newScrollPos >= labelRect.Y2()) {
        newScrollPos = -1; // let the system handle it
      }
      // Up movement and above the top of the label?
      if (dy < 0 && newScrollPos < labelRect.y) {
        newScrollPos = -1; // same treatment
      }
      // still inside the label? scroll
      if (newScrollPos >= 0) {
        setVerticalScroll(newScrollPos);
        return true; // consume event
      }
    }
    // otherwise, let the system handle the event normally
    return super.navigationMovement(dx, dy, status, time);
  }
};

 Notice that I decided not to check status - something you might want to implement. Normally it is zero, but will be non-zero if the user makes movements while holding ALT or SHIFT key.

 

Bonus Section #1

Limiting your Manager's vertical size is actually easier than most people think. VerticalFieldManager (and other built-in managers) always respect the maximums passed to their sublayout and set their extent accordingly, so you delegate most of the job to them!

Suppose you calculate the limit of your Manager's height and put it into myDesiredHeight variable. What is your next step?

If you want to make sure that your Manager takes no more than the calculated height, all you need to do is to override its sublayout like this:

protected void sublayout(int w, int h) {
  super.sublayout(w, Math.min(h, myDesiredHeight));
}

 Wow! That was easy! The use of Math.min is there because you also want to respect those maximums passed to you. If there is not enough room to fit your full desired height, let it take only as much as possible.

Now what if you want your Manager to take exactly the desired height? You use the same code but also tell the Manager to always occupy the whole height by creating it with USE_ALL_HEIGHT style flag (in addition to VERTICAL_SCROLL etc.).

 

That's it! Nothing more, no fancy code, just some parameter substitutions. :smileyhappy:

 

Bonus Section #2

For those worrying that things like setMargin work only since 6.0: no, they are documented since in 6.0! In fact, the've been working since 4.2, so feel free to use them in your code.

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