blackberry labelField.getWidth() 0 देता है? ऐसा क्यों होता है?




horizontalfieldmanager (3)

मैं अपने स्वयं के कस्टम मैनेजर पर काम कर रहा हूं, और मैंने इसे अभी तक पूरा कर लिया है, लेकिन यह स्क्रीन के रिजोल्यूशन के प्रतिशत का उपयोग कर मार्जिन सेट करता है।

यहां बताया गया है कि मैं निम्नलिखित कक्षा को कैसे कॉल करता हूं:

LabelIconCommandManager licm3 = new LabelIconCommandManager("Address blah bklahblah ", 0);
licm3.add(new ImageButtonField(b1, b2, b3, Field.FIELD_LEFT | ImageButtonField.CONSUME_CLICK));

यहां क्लास है [मैंने एक टिप्पणी में चिह्नित किया है, जहां यह 0 देता है और जहां यह 21 9 देता है। कृपया मुझे बताएं कि ऐसा क्यों होता है:

public class LabelIconCommandManager extends HorizontalFieldManager implements  BCMSField
{
    LabelIconCommandManager me = this;
    EvenlySpacedHorizontalFieldManager buttonManager = new EvenlySpacedHorizontalFieldManager(0);
    LabelField labelField;
    int side = 0;
    int HPADDING = 3;
    int VPADDING = 4;
    int screenWidth = Display.getWidth();
    int labelField_width = 40;
    public LabelIconCommandManager()
    {
        this("", 0);
    }
    public LabelIconCommandManager(String label, long style)
    {
        super(USE_ALL_WIDTH| FOCUSABLE);
        this.setBorder(BorderFactory.createBitmapBorder(new XYEdges(15, 20, 15, 20),Bitmap.getBitmapResource( "border_edit.png" )));
        this.setMargin(1,10,1,10);
        labelField = new LabelField(label,LabelField.ELLIPSIS)
        {
            public void layout(int width, int height)
            {
                // Done because otherwise ellipses dont work with labelfields
                super.layout((int)(screenWidth * 0.61), getHeight());
                setExtent((int)(screenWidth * 0.61), getHeight());
                labelField_width = labelField.getWidth();
                DisplayDialog.alert("labelField_width = " + labelField_width); // returns 219
            }
        };
        // Top Right Bottom Left
        labelField.setMargin(VPADDING, HPADDING, VPADDING, 0);
        // super because we want this horizontalfieldManager to add it
        super.add(labelField);
        super.add(buttonManager);
    }
    public void alternateConstructor(Attributes atts)
    {
        labelField = new LabelField(atts.getValue("label"), 0);
    }
    public void onFocus(int direction)
    {
        this.setBorder(BorderFactory.createBitmapBorder(new XYEdges(15, 20, 15, 20),Bitmap.getBitmapResource( "border_edit_select.png" )));
        // uses the same color as listStyleButtonField selections
        this.setBackground(BackgroundFactory.createSolidBackground(0x186DEF));
        super.onFocus(direction);
    }
    //Invoked when a field loses the focus.
    public void onUnfocus()
    {
        //top, right,bottom,left
        this.setBorder(BorderFactory.createBitmapBorder(new XYEdges(15, 20, 15, 20),Bitmap.getBitmapResource( "border_edit.png" )));
        this.setBackground(BackgroundFactory.createSolidTransparentBackground(Color.GRAY, 0));
        super.onUnfocus();
        invalidate();
    }
    // Overrride this managers add function
    public void add(Field imageButton)
    {
        // Add a button to the evenly spaced manager
        buttonManager.add(imageButton);
        // Based on how many buttons there are, set the margin of where the manager holding the buttons start [offset from labelField]
        if(buttonManager.getFieldCount() == 1)
        {
            //side = (int)(screenWidth * 0.1388);
            side = screenWidth - labelField_width - 32 - 10 - 15;
            DisplayDialog.alert("Screen Width = " + screenWidth);
            DisplayDialog.alert("labelField_width2 = " + labelField_width); // returns 0
            DisplayDialog.alert("Side = " + side);
        }
        else side = (int)(screenWidth * 0.05);
        buttonManager.setMargin(0,0,0,side);
    }
    public int getLabelWidth()
    {
        return labelField_width;
    }
}  

अधिक स्पष्ट होने के लिए यहां एक तस्वीर है:


नैट पोस्ट से कुछ संक्षिप्त सारांश

जब आप प्रबंधक का निर्माण करते हैं और फ़ील्ड जोड़ते हैं तो यह अपेक्षा नहीं की जाती कि यह सही ढंग से लेआउट हो जाएगा प्रबंधक संदर्भ को नहीं जानता - जहां उसे रखा जाएगा तो फ़ील्ड के लिए लेआउट विधि को केवल तभी बुलाया जाएगा जब आप स्क्रीन पर अपने प्रबंधक को जोड़ दें (जब प्रबंधक के लिए लेआउट भी कहा जाए)। और यह सही है।

layout विधि में अपनी side चर की गणना को स्थानांतरित करें।

यदि प्रबंधक को स्क्रीन पर रखने से पहले आपको वास्तव में side मान की आवश्यकता होती है आप इसे Field.getPrefferedWidth() का उपयोग करके Field.getPrefferedWidth() कर सकते हैं जो मानक फ़ील्ड ( getFont().getAdvance(text) लिए सार्थक मान देता है getFont().getAdvance(text) , संभवत: सीमाओं के साथ भी स्वयं की जांच करें)। लेकिन इस मूल्यों से सावधान रहें


कृपया नीचे कोड की समीक्षा करें। यह प्रबंधक है जिसमें लेबल और बटन हैं और यह दाएं तरफ बाईं ओर और बटन पर लेबल डालता है

import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.decor.Border;

import java.util.Vector;

public class TabFieldManager extends Manager {

public TabFieldManager(long style) {
    super(style);
}

protected void sublayout(int width, int height) {
    LabelField label = null;

    Vector tabs = new Vector();
    int tabsWidth = 0;
    int tabHeight = 0;
    int tabPaddingTop = 0;
    int tabPaddingLeft = 0;

    for (int i=0; i < getFieldCount(); i++) {
        Field field = getField(i);
        if (field instanceof LabelField) {
            label = (LabelField) field;
        } else if (field instanceof ButtonField){
            tabs.addElement(field);

            layoutChild(field, width, height);

            int fieldwidth = field.getWidth() > 0 ? field.getWidth() : field.getPreferredWidth() ;
            tabsWidth += fieldwidth + getBorderAndPaddingWidth(field);

            int fieldHeight = field.getHeight() > 0 ? field.getHeight() : field.getPreferredHeight();
            if (fieldHeight > tabHeight) {
                tabHeight = getBorderAndPaddingHeight(field) + fieldHeight;
            }

            int fieldPaddingTop = field.getPaddingTop();
            if (fieldPaddingTop > tabPaddingTop) {
                tabPaddingTop = fieldPaddingTop;
            }

            int fieldPaddingLeft = field.getPaddingLeft();
            if (fieldPaddingLeft > tabPaddingLeft) {
                tabPaddingLeft = fieldPaddingLeft;
            }
        }
    }

    if (label != null) {
        layoutChild(label, width - tabsWidth, height);
        int y = tabHeight - label.getHeight() >> 1;
        setPositionChild(label, tabPaddingLeft , y);
    }
    for (int i = 0; i < tabs.size(); i++) {
        Field tabField = (Field) tabs.elementAt(i);
        setPositionChild(tabField, width - tabsWidth, getBorderAndPaddingHeight(tabField));
        tabsWidth -= tabField.getWidth() + getBorderAndPaddingWidth(tabField);
    }

    setExtent(width, tabHeight);
}

private int getBorderAndPaddingHeight( Field field ) {
    int height = field.getPaddingTop() + field.getPaddingBottom();
    Border border = field.getBorder();
    if( border != null ) {
        height += border.getTop() + border.getBottom();
    }

    return height;
}

private int getBorderAndPaddingWidth( Field field ){
    int width = field.getPaddingLeft() + field.getPaddingRight();
    Border border = field.getBorder();
    if( border != null ) {
        width += border.getLeft() + border.getRight();
    }
    return width;
}

protected int moveFocus(int amount, int status, int time) {
    if ((status & Field.STATUS_MOVE_FOCUS_VERTICALLY) == Field.STATUS_MOVE_FOCUS_VERTICALLY && amount > 0) {
        return amount;
    } else
        return super.moveFocus(amount, status, time);
}

protected int nextFocus(int amount, int axis) {
    if (amount > 0 && axis == Field.AXIS_VERTICAL)
        return -1;
    else
        return super.nextFocus(amount, axis);
}

}


नोट: जब मैंने आपका कोड चलाया था, तो मैंने वास्तव में labelField_width नहीं देखा था labelField_width को 0 सेट किया गया था। आप ऊपर पोस्ट किए गए कोड में 40 को शुरू करते हैं तो, मैं कभी-कभी इसे 40 या 21 9 (एक 360 पिक्सेल चौड़ी स्क्रीन पर) पर सेट करता हूं।

लेकिन, समस्या यह है कि मुझे लगता है कि आप labelField_width के मूल्य को जल्द ही उपयोग करने का प्रयास कर रहे हैं। यह ठीक तरह से असाइन किया गया एकमात्र स्थान आपके अनाम LabelField के layout() विधि में है सिर्फ इसलिए कि आप तात्कालिकता के साथ layout() विधि को घोषित और कार्यान्वित करते हैं, इसका अर्थ यह नहीं है कि जब LabelField बनाया जाता है यह वास्तव में एक वजह है कि मुझे अज्ञात कक्षाएं पसंद नहीं हैं।

वैसे भी, यह कोड:

LabelIconCommandManager licm3 = new LabelIconCommandManager("Address blah bklahblah ", 0); 
licm3.add(new ImageButtonField(b1, b2, b3, Field.FIELD_LEFT | ImageButtonField.CONSUME_CLICK));

पहले LabelField ( LabelIconCommandManager कन्स्ट्रक्टर के अंदर) इन्स्तांत करेगा जैसा कि मैंने कहा, वह layout() विधि ट्रिगर नहीं करता है दूसरी पंक्ति ऊपर ( add() ) आपके अधिरोहित विधि को गति देगा:

// Overrride this managers add function 
public void add(Field imageButton) 
{ 

यह वह जगह है जहां आप labelField_width लिए खराब मान देखते हैं। उस विधि को layout() से पहले कहा जाता है layout() । यही समस्या है।

चूंकि ऐसा लगता है कि आप केवल उस buttonManager उपयोग buttonManager मार्जिन सेट करने के लिए करते हैं, आप ऐसा करने के लिए थोड़ी देर इंतजार कर सकते हैं। यदि आप LabelIconCommandManager sublayout() विधि को बुलाए जाने तक प्रतीक्षा करते हैं, तो आपके LabelField को इसकी layout() विधि layout() कहा जाता था, और labelField_width को सही ढंग से असाइन किया गया था:

protected void sublayout(int maxWidth, int maxHeight) {
   // make sure to call superclass method first!
   super.sublayout(maxWidth, maxHeight);

   // now, we can reliably use the label width:
   side = screenWidth - labelField_width - 32 - 10 - 15; 
   buttonManager.setMargin(0,0,0,side); 
}

यह विधि LabelIconCommandManager कक्षा में चला जाता है। और फिर, आप दूसरे स्थान को हटा सकते हैं, जिसे आप buttonManager.setMargin()buttonManager.setMargin()