Как раскрасить текст LabelField в ListField, когда родительский менеджер имеет фокус?

У меня есть переопределенный LabelField, который позволяет мне изменить цвет шрифта в зависимости от того, должен ли элемент в моем ListField быть подавленным или сейчас. Приглушение цвета LabelField отлично работает. Но когда строка (содержащая мой LabelField) выделена в ListField, я бы хотел, чтобы цвет поля метки был другим или инвертированным.

Вот мой код:

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;

}

В этом примере я хотел бы, чтобы MyLabelField был нарисован серым цветом, но когда строка ListField, в которой он содержится, имеет фокус, я хотел бы, чтобы по умолчанию использовался цвет LabelField, который должен сделать его белым.

Основываясь на тестировании моего кода, кажется, что LabelField не получает фокус, когда его родительская строка имеет фокус. Возможно, нужно изменить что-то еще в моем коде...


person JR Lawhorne    schedule 12.08.2009    source источник


Ответы (1)


Чтобы переключить цвет LabelField, мы можем проверить, выбран ли он в методе paint(). Но даже тогда нам придется перекрашивать каждую строку в ListField. И в этом проблема: каждый раз, когда выбор строки ListField изменяется, есть только два вызова метода ListFieldCallback.drawRow() - первый для предыдущей выбранной строки (все еще в выбранном состоянии) и второй для новой выбранной строки (уже в выбранном состоянии) ...

Я пытался сохранить предыдущий выбранный индекс строки и перерисовывать его при каждом вызове drawRow(), но по какой-то причине метод LabelField.paint() тогда не запускался.

Итак, я предлагаю простое, несколько уродливое решение: Schedule ListField.invalidate() TimerTask. Периода в 100 мс вполне достаточно, и это не влияет на производительность.

Код Джейсона Эмерик я использовал в качестве руководства по расширенному 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);
        }
    }
}
person Maksym Gontar    schedule 14.08.2009