Blackberry:具有消失焦点突出显示的自定义按钮字段

Blackberry:具有消失焦点突出显示的自定义按钮字段,blackberry,java-me,focus,field,buttonfield,Blackberry,Java Me,Focus,Field,Buttonfield,我正在尝试创建一个自定义按钮字段,它的焦点(蓝色突出显示颜色)会在不活动几秒钟后消失,就像带触摸屏的BB手机上的原始音乐播放器一样 通过以下示例,我几乎成功地做到了这一点: 以下是east.png和west.png(由openclipart.org提供): 以下是我的测试代码MyFocus.java: import net.rim.device.api.ui.*; import net.rim.device.api.ui.component.*; import net.rim.device

我正在尝试创建一个自定义按钮字段,它的焦点(蓝色突出显示颜色)会在不活动几秒钟后消失,就像带触摸屏的BB手机上的原始音乐播放器一样

通过以下示例,我几乎成功地做到了这一点:

以下是east.png和west.png(由openclipart.org提供):

以下是我的测试代码MyFocus.java:

import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.decor.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.image.*;

public class MyFocus extends UiApplication {
    public static void main(String[] args) {
        MyFocus app = new MyFocus();
        app.enterEventDispatcher();
    }

    public MyFocus() {
        pushScreen(new MyScreen());
    }    
}

class MyScreen extends MainScreen {
    public MyScreen() {       
        setTitle("2nd trackpad click not working");
        getMainManager().setBackground(BackgroundFactory.createLinearGradientBackground(Color.WHITE, Color.GRAY, Color.DARKGRAY, Color.GRAY));

        add(new MyButton(MyButton.EAST));
        add(new MyButton(MyButton.WEST));
        add(NF);
    }

    class MyButton extends ButtonField {
        public final static int EAST  = 0;
        public final static int WEST  = 1;

        public final static int WIDTH  = 100;
        public final static int HEIGHT = 100;

        private final XYEdges EDGES = new XYEdges(0, 0, 0, 0);
        private final Application _app = UiApplication.getUiApplication();
        private final static long FOCUS_DURATION = 3000L;    

        private int _focusTimer = -1;
        private final int _direction;

        public MyButton(int direction) {
            setMargin(EDGES);
            setPadding(EDGES);
            setImageSize(WIDTH, HEIGHT);

            setBorder(VISUAL_STATE_NORMAL, 
BorderFactory.createSimpleBorder(EDGES));
            setBorder(VISUAL_STATE_FOCUS, BorderFactory.createSimpleBorder(EDGES));
            setBorder(VISUAL_STATE_ACTIVE, BorderFactory.createSimpleBorder(EDGES));

            setBackground(VISUAL_STATE_NORMAL, BackgroundFactory.createSolidTransparentBackground(Color.GREEN, 0));
            setBackground(VISUAL_STATE_FOCUS, BackgroundFactory.createSolidTransparentBackground(Color.BLUE, 100));
            setBackground(VISUAL_STATE_ACTIVE, BackgroundFactory.createSolidTransparentBackground(Color.RED, 200));

            _direction = direction;
            switch(_direction) {
                case EAST: 
                    setImage(ImageFactory.createImage("east.png"));
                    break;
                case WEST: 
                    setImage(ImageFactory.createImage("west.png"));
                    break;
            }
        }

        // display red background on long touch and hold            
        protected boolean touchEvent(TouchEvent event) {
            if (event.getEvent() == TouchEvent.CLICK) {
                applyThemeOnStateChange();
                return true;
            }
            return super.touchEvent(event);
        }

        protected void onUnfocus() {
            if (_focusTimer != -1) {
                _app.cancelInvokeLater(_focusTimer);
                _focusTimer = -1;
            }            

            super.onUnfocus();
        }

        protected void onFocus(int direction) {
            if (_focusTimer != -1) {
                _app.cancelInvokeLater(_focusTimer);
                _focusTimer = -1;
            }            

            _focusTimer = _app.invokeLater(new Runnable() {
                public void run() {
                    MyButton.super.onUnfocus();
                    _focusTimer = -1;
                }
            }, FOCUS_DURATION, false);

            super.onFocus(direction);
        }

        public int getPreferredHeight(){
                return HEIGHT;
        }

        public int getPreferredWidth(){
                return WIDTH;
        }

        protected void layout(int width, int height) {
            setExtent(WIDTH, HEIGHT);
        }
    }
}
我的问题在我第一次选择一个按钮并等待几秒钟以使其焦点消失时可见。然后我点击轨迹板,当按下按钮时(确认),你在屏幕上看不到任何东西-它不会变成蓝色或红色

我尝试了navigationClick()和trackwheelUnclick()的所有组合,但无法解决此问题

需要帮忙吗? 亚历克斯

更新1:

我尝试了以下方法,但效果不好(焦点永远消失,可能是因为按钮认为它已经处于所需的视觉状态):

更新2:

尝试使用NullField,但仍无法正常工作:

import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.decor.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.image.*;

public class MyFocus extends UiApplication {
    public static void main(String[] args) {
        MyFocus app = new MyFocus();
        app.enterEventDispatcher();
    }

    public MyFocus() {
        pushScreen(new MyScreen());
    }    
}

class MyScreen extends MainScreen {
    static NullField NF = new NullField();
    HorizontalFieldManager hfm = new HorizontalFieldManager() {
        int lastFocused = -1;

        protected int firstFocus(int direction) {
            lastFocused = super.firstFocus(direction);
            System.out.println("XXX firstFocus: " + lastFocused);
            return lastFocused;
        }

        protected int nextFocus(final int direction, final int axis) {

            if (getFieldWithFocus() == NF) {
                return lastFocused;
            } 

            lastFocused = super.nextFocus(direction, axis);
            System.out.println("XXX nextFocus: " + lastFocused);
            return lastFocused;
        }
    };

    public MyScreen() {       
        setTitle("2nd trackpad click not working");
        getMainManager().setBackground(BackgroundFactory.createLinearGradientBackground(Color.WHITE, Color.GRAY, Color.DARKGRAY, Color.GRAY));

        hfm.add(new MyButton(MyButton.WEST));
        hfm.add(new MyButton(MyButton.EAST));
        hfm.add(new MyButton(MyButton.EAST));
        hfm.add(NF);

        add(hfm);
    }

    class MyButton extends ButtonField {
        public final static int EAST  = 0;
        public final static int WEST  = 1;

        public final static int WIDTH  = 100;
        public final static int HEIGHT = 100;

        private final XYEdges EDGES = new XYEdges(0, 0, 0, 0);
        private final Application _app = UiApplication.getUiApplication();
        private final static long FOCUS_DURATION = 3000L;    

        private int _focusTimer = -1;
        private final int _direction;

        public MyButton(int direction) {
            setMargin(EDGES);
            setPadding(EDGES);
            setImageSize(WIDTH, HEIGHT);

            setBorder(VISUAL_STATE_NORMAL, BorderFactory.createSimpleBorder(EDGES));
            setBorder(VISUAL_STATE_FOCUS, BorderFactory.createSimpleBorder(EDGES));
            setBorder(VISUAL_STATE_ACTIVE, BorderFactory.createSimpleBorder(EDGES));

            setBackground(VISUAL_STATE_NORMAL, BackgroundFactory.createSolidTransparentBackground(Color.GREEN, 0));
            setBackground(VISUAL_STATE_FOCUS, BackgroundFactory.createSolidTransparentBackground(Color.BLUE, 100));
            setBackground(VISUAL_STATE_ACTIVE, BackgroundFactory.createSolidTransparentBackground(Color.RED, 200));

            _direction = direction;
            switch(_direction) {
                case EAST: 
                    setImage(ImageFactory.createImage("east.png"));
                    break;
                case WEST: 
                    setImage(ImageFactory.createImage("west.png"));
                    break;
            }
        }

        protected boolean touchEvent(TouchEvent event) {
            if (event.getEvent() == TouchEvent.CLICK) {
                applyThemeOnStateChange();
                return true;
            }
            return super.touchEvent(event);
        }

        protected void onUnfocus() {
            if (_focusTimer != -1) {
                _app.cancelInvokeLater(_focusTimer);
                _focusTimer = -1;
            }            

            super.onUnfocus();
        }

        protected void onFocus(int direction) {
            if (_focusTimer != -1) {
                _app.cancelInvokeLater(_focusTimer);
                _focusTimer = -1;
            }            

            _focusTimer = _app.invokeLater(new Runnable() {
                public void run() {
                    MyScreen.NF.setFocus();
                    _focusTimer = -1;
                }
            }, FOCUS_DURATION, false);

            super.onFocus(direction);
        }

        public int getPreferredHeight(){
                return HEIGHT;
        }

        public int getPreferredWidth(){
                return WIDTH;
        }

        protected void layout(int width, int height) {
            setExtent(WIDTH, HEIGHT);
        }
    }
}


在调用
super.drawFocus()
之前,我可能会跳过
drawFocus()
方法来检查标志
\u showFocus
,然后在
onFocus()
中,将标志设置为true,并安排Runnable将
\u showFocus
标志更改为false并使其失效(在
onFocus()中也将其设置为false)
)。也不必担心取消计时器或以这种方式进行的任何操作,因为它只会更改一个标志并使其无效,并将其保持在适当的状态

在调用
super.drawFocus()
之前,我可能会跳过
drawFocus()
方法来检查标志
\u showFocus
,然后在
onFocus()
中,将标志设置为true,并安排Runnable以将
\u showFocus
标志更改为false并使其失效(在
onFocus()中也将其设置为false)
)。也不必担心取消计时器或以这种方式进行的任何操作,因为它只会更改一个标志并使其无效,并将其保持在适当的状态

恐怕使用drawFocus()是不可能的,因为:在聚焦状态下,我的按钮有蓝色不透明背景,而在正常状态下,它是透明的(绿色)。因此,我不知道如何通过扩展drawFocus()来更改背景。您能否从“未聚焦”、“聚焦”和“高光消失”完成整个颜色步骤?我想我还不清楚。1)在正常状态下,背景是透明的2)在活动状态下(当用户按下轨迹板或用手指触摸时),背景是不透明的红色3)在聚焦状态下,背景是不透明的蓝色。我试图模仿BB音乐播放器的行为:一段时间后,蓝色焦点消失。我几乎成功了,但是第二次、第三次等使用轨迹板的点击都不起作用(按钮保持在正常状态),我担心使用drawFocus()是不可能的,因为:在聚焦状态下,我的按钮有蓝色不透明背景,而在正常状态下,它是透明的(绿色)。因此,我不知道如何通过扩展drawFocus()来更改背景。您能否从“未聚焦”、“聚焦”和“高光消失”完成整个颜色步骤?我想我还不清楚。1)在正常状态下,背景是透明的2)在活动状态下(当用户按下轨迹板或用手指触摸时),背景是不透明的红色3)在聚焦状态下,背景是不透明的蓝色。我试图模仿BB音乐播放器的行为:一段时间后,蓝色焦点消失。我几乎成功了,但第二次、第三次等使用轨迹板的点击都不起作用(按钮保持正常状态)
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.decor.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.image.*;

public class MyFocus extends UiApplication {
    public static void main(String[] args) {
        MyFocus app = new MyFocus();
        app.enterEventDispatcher();
    }

    public MyFocus() {
        pushScreen(new MyScreen());
    }    
}

class MyScreen extends MainScreen {
    static NullField NF = new NullField();
    HorizontalFieldManager hfm = new HorizontalFieldManager() {
        int lastFocused = -1;

        protected int firstFocus(int direction) {
            lastFocused = super.firstFocus(direction);
            System.out.println("XXX firstFocus: " + lastFocused);
            return lastFocused;
        }

        protected int nextFocus(final int direction, final int axis) {

            if (getFieldWithFocus() == NF) {
                return lastFocused;
            } 

            lastFocused = super.nextFocus(direction, axis);
            System.out.println("XXX nextFocus: " + lastFocused);
            return lastFocused;
        }
    };

    public MyScreen() {       
        setTitle("2nd trackpad click not working");
        getMainManager().setBackground(BackgroundFactory.createLinearGradientBackground(Color.WHITE, Color.GRAY, Color.DARKGRAY, Color.GRAY));

        hfm.add(new MyButton(MyButton.WEST));
        hfm.add(new MyButton(MyButton.EAST));
        hfm.add(new MyButton(MyButton.EAST));
        hfm.add(NF);

        add(hfm);
    }

    class MyButton extends ButtonField {
        public final static int EAST  = 0;
        public final static int WEST  = 1;

        public final static int WIDTH  = 100;
        public final static int HEIGHT = 100;

        private final XYEdges EDGES = new XYEdges(0, 0, 0, 0);
        private final Application _app = UiApplication.getUiApplication();
        private final static long FOCUS_DURATION = 3000L;    

        private int _focusTimer = -1;
        private final int _direction;

        public MyButton(int direction) {
            setMargin(EDGES);
            setPadding(EDGES);
            setImageSize(WIDTH, HEIGHT);

            setBorder(VISUAL_STATE_NORMAL, BorderFactory.createSimpleBorder(EDGES));
            setBorder(VISUAL_STATE_FOCUS, BorderFactory.createSimpleBorder(EDGES));
            setBorder(VISUAL_STATE_ACTIVE, BorderFactory.createSimpleBorder(EDGES));

            setBackground(VISUAL_STATE_NORMAL, BackgroundFactory.createSolidTransparentBackground(Color.GREEN, 0));
            setBackground(VISUAL_STATE_FOCUS, BackgroundFactory.createSolidTransparentBackground(Color.BLUE, 100));
            setBackground(VISUAL_STATE_ACTIVE, BackgroundFactory.createSolidTransparentBackground(Color.RED, 200));

            _direction = direction;
            switch(_direction) {
                case EAST: 
                    setImage(ImageFactory.createImage("east.png"));
                    break;
                case WEST: 
                    setImage(ImageFactory.createImage("west.png"));
                    break;
            }
        }

        protected boolean touchEvent(TouchEvent event) {
            if (event.getEvent() == TouchEvent.CLICK) {
                applyThemeOnStateChange();
                return true;
            }
            return super.touchEvent(event);
        }

        protected void onUnfocus() {
            if (_focusTimer != -1) {
                _app.cancelInvokeLater(_focusTimer);
                _focusTimer = -1;
            }            

            super.onUnfocus();
        }

        protected void onFocus(int direction) {
            if (_focusTimer != -1) {
                _app.cancelInvokeLater(_focusTimer);
                _focusTimer = -1;
            }            

            _focusTimer = _app.invokeLater(new Runnable() {
                public void run() {
                    MyScreen.NF.setFocus();
                    _focusTimer = -1;
                }
            }, FOCUS_DURATION, false);

            super.onFocus(direction);
        }

        public int getPreferredHeight(){
                return HEIGHT;
        }

        public int getPreferredWidth(){
                return WIDTH;
        }

        protected void layout(int width, int height) {
            setExtent(WIDTH, HEIGHT);
        }
    }
}