Question

I have an overridden LabelField that allows me to change the font color based on whether an item in my ListField should be subdued or now. Making the LabelField color subdued works great. But, when the row (that contains my LabelField) is highlighted in the ListField, I would like the label field color to be different or inverted.

Here is my code:

public class MyLabelField extends LabelField{

public MyLabelField (String s, long l){
    super(s, l);
    m_bSubdue = true; // this value does change in implementation but not in this sample
}

protected void paint(Graphics g)
{
    if(m_bSubdue && !this.isFocus()){  // this isFocus() trick is not working
        int color = 0x00696969; // RGB val
        g.setColor(color);
    }
    super.paint(g);
}

boolean m_bSubdue;

}

In this sample, I would like MyLabelField to be drawn with a gray color but when the ListField row its contained in has the focus, I would like the color to default to LabelField paint which should make it white.

Based on testing my code, it seems the LabelField does not get the focus when its parent row has the focus. Maybe a change is needed somewhere else in my code...

Was it helpful?

Solution

To switch color of LabelField we can check if it's selected in it's paint() method. But even then we'll have to repaint every row in ListField. And that's the problem: every time row selection of ListField is changed, there are only two calls of ListFieldCallback.drawRow() method - first for previous selected row (still in selected state) and second for new selected row (already in selected state)...

I've tried to save previous selected row index and redraw it on each call of drawRow(), but by some reason LabelField.paint() method was not triggered then.

So I come with simple, somehow ugly solution: schedule ListField.invalidate() TimerTask. Period in 100 ms is enough and doesn't hit performance as well.

Jason Emerick's code I've been used as a guide to extended ListField.

class LabelListField extends ListField implements ListFieldCallback {
    private Vector mValues;
    private Vector mRows;

    public LabelListField(Vector values) {
        super(0);
        setRowHeight(70);
        setCallback(this);

        mValues = values;
        fillListWithValues(values);

        scheduleInvalidate();
    }

    private void scheduleInvalidate() {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {
                invalidate();
            }
        }, 0, 100);
    }

    private void fillListWithValues(Vector values) {
        mRows = new Vector();
        for (int i = 0; i < values.size(); i++) {
            TableRowManager row = new TableRowManager();
            String title = "Item# " + String.valueOf(i + 1);
            LabelField titleLabel = new LabelField(title);
            titleLabel.setFont(Font.getDefault().derive(Font.BOLD));
            row.add(titleLabel);
            String value = (String) values.elementAt(i);
            ListLabel valueLabel = new ListLabel(this, i, value);
            valueLabel.setFont(Font.getDefault().derive(Font.ITALIC));
            row.add(valueLabel);
            mRows.addElement(row);
        }
        setSize(mRows.size());
    }

    private class TableRowManager extends Manager {
        public TableRowManager() {
            super(0);
        }

        public void drawRow(Graphics g, int x, int y, 
            int width, int height) {
            layout(width, height);
            setPosition(x, y);
            g.pushRegion(getExtent());
            paintChild(g, getField(0));
            paintChild(g, getField(1));
            g.popContext();
        }

        protected void sublayout(int width, int height) {
            int fontHeight = Font.getDefault().getHeight();
            int preferredWidth = getPreferredWidth();
            Field field = getField(0);
            layoutChild(field, preferredWidth - 5, fontHeight + 1);
            setPositionChild(field, 5, 3);
            field = getField(1);
            layoutChild(field, preferredWidth - 5, fontHeight + 1);
            setPositionChild(field, 5, fontHeight + 6);
            setExtent(preferredWidth, getPreferredHeight());
        }

        public int getPreferredWidth() {
            return Display.getWidth();
        }

        public int getPreferredHeight() {
            return getRowHeight();
        }
    }

    public void drawListRow(ListField listField, Graphics g, 
            int index, int y, int width) {
        LabelListField list = (LabelListField) listField;
        TableRowManager rowManager = (TableRowManager) list.mRows
                .elementAt(index);
        rowManager.drawRow(g, 0, y, width, list.getRowHeight());

    }

    public Object get(ListField list, int index) {
        return mValues.elementAt(index);
    }

    public int indexOfList(ListField list, String prefix, int start) {
        for (int x = start; x < mValues.size(); ++x) {
            String value = (String) mValues.elementAt(x);
            if (value.startsWith(prefix)) {
                return x;
            }
        }
        return -1;
    }

    public int getPreferredWidth(ListField list) {
        return Display.getWidth();
    }

    class ListLabel extends LabelField {
        int mIndex = -1;

        public ListLabel(LabelListField list, int index, String text) {
            super(text);
            mIndex = index;
        }

        protected void paint(Graphics graphics) {
            if (getSelectedIndex() == mIndex)
                graphics.setColor(Color.RED);
            else
                graphics.setColor(Color.BLUE);
            super.paint(graphics);
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top