正文

[转]第3章  MIDP高级UI 的使用32006-08-05 08:53:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/sword2008/17265.html

分享到:

3.6.2   ImageItem

下面我们来看ImageItem,ImageItemStringItem其实区别仅仅在于一个是显示图像,一个是文字,它同样有两个构造函数,其中用到最多的是5个参数的构造函数,第一个是该ItemLabel,第二个是图片,第三个是等效线,第四个是取代的文字(图片无法现实时),第五个是外观(和StringItem相同)。

 

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

public class ImageItemMIDlet extends MIDlet

implements ItemCommandListener

{

        private Display display;

        public ImageItemMIDlet()

        {

                display = Display.getDisplay(this);

        }

        public void startApp()

        {

                Image img = null ;

                try

               {

                       img = Image.createImage("/pic.png") ;

               }catch(Exception e){}

 

                Form f = new Form("ImageItem测试") ;

                f.append(img) ;

                ImageItem ii1 =

                 new ImageItem("图片1",img,

Item.LAYOUT_CENTER|Item.LAYOUT_NEWLINE_BEFORE,"图片1取代文字",Item.BUTTON);

                f.append(ii1) ;

                ImageItem ii2 =

                 new ImageItem("图片2",img,

Item.LAYOUT_RIGHT|Item.LAYOUT_NEWLINE_BEFORE,"图片2取代文字",Item.HYPERLINK);

                f.append(ii2) ;

 

                display.setCurrent(f);

        }

        public void commandAction(Command c,Item i)

        {

                System.out.println(c.getLabel());

                System.out.println(i.getLabel());

        }

        public void pauseApp()

        {

        }

        public void destroyApp(boolean unconditional)

        {

        }

}

 

3.7    CustomItem

CustomItemItem中一个比较重要的子类,它最大的优点是提高了Form中的可交互性。它和Canvas有很大的相似处。我们通过改写CustomItem可以实现完全控制在新的子类中条目区域的显示,它可以定义使用的颜色,字体和图形,包括特殊高亮的条目可能有的所有的焦点状态,只有条目的Label是有系统控制生成的,但是Label总是生成在CustomItem的内容区域外。

 

每个CustomItem都负责把它的行为与目标设备上可用的交互模式匹配。一个CustomItem调用方法来观察特定设备所支持的交互模式,这个方法会返回一个支持模式的位标记,支持的模式会的返回对应位会被设置,不支持的不被设置。

 

CustomItem一个比较重要的特性即是Form内部的遍历,即实现可能临时把遍历的责任委派给Item本身,这样可以实现特殊的高亮,动画等等效果。

 

由于customItemForm类里扮演很重要的角色,其内容很庞杂,我们通过三个代码段来教读者如何使用CustomItem,希望大家通过对代码的深刻认识,提高自己对CustomItem的掌握程度。

 

import javax.microedition.lcdui.*;

import javax.microedition.midlet.MIDlet;

 

 

public class CustomItemDemo extends MIDlet implements CommandListener {

    private final static Command CMD_EXIT = new Command("Exit", Command.EXIT, 1);

    private Display display;

   

    private boolean firstTime;

    private Form mainForm;

   

    public CustomItemDemo() {

        firstTime = true;

        mainForm = new Form("Custom Item");

    }

 

    protected void startApp() {

        if(firstTime) {

            display = Display.getDisplay(this);

 

            mainForm.append(new TextField("Upper Item", null, 10, 0));

            mainForm.append(new Table("Table", Display.getDisplay(this)));

            mainForm.append(new TextField("Lower Item", null, 10, 0));

            mainForm.addCommand(CMD_EXIT);

            mainForm.setCommandListener(this);

            firstTime = false;

        }

        display.setCurrent(mainForm);

    }

 

    public void commandAction(Command c, Displayable d) {

        if (c == CMD_EXIT) {

            destroyApp(false);

            notifyDestroyed();

        }

    }

 

    protected void destroyApp(boolean unconditional) {

    }

 

    protected void pauseApp() {

    }

}

 

import javax.microedition.lcdui.*;

public class Table

    extends CustomItem

    implements ItemCommandListener {

 

    private final static Command CMD_EDIT = new Command("Edit",

                                                           Command.ITEM, 1);

    private Display display;

    private int rows = 5;

    private int cols = 3;

    private int dx = 50;

    private int dy = 20;

    private final static int UPPER = 0;

    private final static int IN = 1;

    private final static int LOWER = 2;

    private int location = UPPER;

    private int currentX = 0;

    private int currentY = 0;

    private String[][] data = new String[rows][cols];

   

    // Traversal stuff    

    //indicating support of horizontal traversal internal to the CustomItem

    boolean horz;

   

    //indicating support for vertical traversal internal to the CustomItem.

    boolean vert;

 

    public Table(String title, Display d) {

        super(title);

        display = d;

        setDefaultCommand(CMD_EDIT);

        setItemCommandListener(this);

        int interactionMode = getInteractionModes();

        horz = ((interactionMode & CustomItem.TRAVERSE_HORIZONTAL) != 0);

        vert = ((interactionMode & CustomItem.TRAVERSE_VERTICAL) != 0);

    }

 

    protected int getMinContentHeight() {

 

        return (rows * dy) + 1;

    }

 

    protected int getMinContentWidth() {

 

        return (cols * dx) + 1;

    }

 

    protected int getPrefContentHeight(int width) {

 

        return (rows * dy) + 1;

    }

 

    protected int getPrefContentWidth(int height) {

 

        return (cols * dx) + 1;

    }

 

    protected void paint(Graphics g, int w, int h) {

 

        for (int i = 0; i <= rows; i++) {

            g.drawLine(0, i * dy, cols * dx, i * dy);

        }

 

        for (int i = 0; i <= cols; i++) {

            g.drawLine(i * dx, 0, i * dx, rows * dy);

        }

 

        int oldColor = g.getColor();

        g.setColor(0x00D0D0D0);

        g.fillRect((currentX * dx) + 1, (currentY * dy) + 1, dx - 1, dy - 1);

        g.setColor(oldColor);

 

        for (int i = 0; i < rows; i++) {

 

            for (int j = 0; j < cols; j++) {

 

                if (data[i][j] != null) {

 

                    // store clipping properties

                    int oldClipX = g.getClipX();

                    int oldClipY = g.getClipY();

                    int oldClipWidth = g.getClipWidth();

                    int oldClipHeight = g.getClipHeight();

                    g.setClip((j * dx) + 1, i * dy, dx - 1, dy - 1);

                    g.drawString(data[i][j], (j * dx) + 2, ((i + 1) * dy) - 2,

                                 Graphics.BOTTOM | Graphics.LEFT);

 

                    // restore clipping properties

                    g.setClip(oldClipX, oldClipY, oldClipWidth, oldClipHeight);

                }

            }

        }

    }

 

    protected boolean traverse(int dir, int viewportWidth, int viewportHeight,

                               int[] visRect_inout) {                                

       

        if (horz && vert) {                                 

 

            switch (dir) {

   

                case Canvas.DOWN:

   

                    if (location == UPPER) {

                        location = IN;

                    } else {

   

                        if (currentY < (rows - 1)) {

                            currentY++;

                            repaint(currentX * dx, (currentY - 1) * dy, dx, dy);

                            repaint(currentX * dx, currentY * dy, dx, dy);

                        } else {

                            location = LOWER;

   

                            return false;

                        }

                    }

   

                    break;

   

                case Canvas.UP:

   

                    if (location == LOWER) {

                        location = IN;

                    } else {

   

                        if (currentY > 0) {

                            currentY--;

                            repaint(currentX * dx, (currentY + 1) * dy, dx, dy);

                            repaint(currentX * dx, currentY * dy, dx, dy);

                        } else {

                            location = UPPER;

   

                            return false;

                        }

                    }

   

                    break;

   

                case Canvas.LEFT:

   

                    if (currentX > 0) {

                        currentX--;

                        repaint((currentX + 1) * dx, currentY * dy, dx, dy);

                        repaint(currentX * dx, currentY * dy, dx, dy);

                    }

   

                    break;

   

                case Canvas.RIGHT:

   

                    if (currentX < (cols - 1)) {

                        currentX++;

                        repaint((currentX - 1) * dx, currentY * dy, dx, dy);

                        repaint(currentX * dx, currentY * dy, dx, dy);

                    }

            }

        } else if (horz || vert) {

            switch (dir) {

        

                case Canvas.UP:

                case Canvas.LEFT:

                   

                    if (location == LOWER) {

                        location = IN;

                    } else {

   

                        if (currentX > 0) {

                            currentX--;

                            repaint((currentX + 1) * dx, currentY * dy, dx, dy);

                            repaint(currentX * dx, currentY * dy, dx, dy);

                        } else if (currentY > 0) {

                            currentY--;

                            repaint(currentX * dx, (currentY + 1) * dy, dx, dy);

                            currentX = cols - 1;

                            repaint(currentX * dx, currentY * dy, dx, dy);

                        } else {

                            location = UPPER;

                            return false;

                        }

                    }

   

                    break;

   

                case Canvas.DOWN:

                case Canvas.RIGHT:

                    if (location == UPPER) {

                        location = IN;

                    } else {

   

                        if (currentX < (cols - 1)) {

                            currentX++;

                            repaint((currentX - 1) * dx, currentY * dy, dx, dy);

                            repaint(currentX * dx, currentY * dy, dx, dy);

                        } else if (currentY < (rows - 1)) {

                            currentY++;                    

                            repaint(currentX * dx, (currentY - 1) * dy, dx, dy);

                            currentX = 0;

                            repaint(currentX * dx, currentY * dy, dx, dy);

                        } else {

                            location = LOWER;

                            return false;

                        }

                    }

                       

            }

        } else {

            //In case of no Traversal at all: (horz|vert) == 0

        }

 

        visRect_inout[0] = currentX;

        visRect_inout[1] = currentY;

        visRect_inout[2] = dx;

        visRect_inout[3] = dy;

 

        return true;

    }

 

    public void setText(String text) {

        data[currentY][currentX] = text;

        repaint(currentY * dx, currentX * dy, dx, dy);

    }

 

    public void commandAction(Command c, Item i) {

 

        if (c == CMD_EDIT) {

 

            TextInput textInput = new TextInput(data[currentY][currentX], this,

                                                display);

            display.setCurrent(textInput);

        }

    }

}

 

 

import javax.microedition.lcdui.*;

import javax.microedition.midlet.MIDlet;

 

 

public class TextInput extends TextBox implements CommandListener {

 

    private final static Command CMD_OK = new Command("OK", Command.OK,   

                                                        1);       

    private final static Command CMD_CANCEL = new Command("Cancel", Command.CANCEL,

                                                        1);

    

    private Table parent;

    private Display display;

 

    public TextInput(String text, Table parent, Display display) {

        super("Enter Text", text, 50, TextField.ANY);

        this.parent = parent;

        this.display = display;

        addCommand(CMD_OK);

        addCommand(CMD_CANCEL);

        setCommandListener(this);

    }

 

    public void commandAction(Command c, Displayable d) {

        if (c == CMD_OK) {

            // update the table's cell and return

            parent.setText(getString());

            display.setCurrentItem(parent);

        } else if (c == CMD_CANCEL) {

            // return without updating the table's cell

            display.setCurrentItem(parent);

        }

    }

   

}

3.8    TextFieldDateField

TextField和我们前面讲的TextBox大同小异,只是它是作为Form的一个子类存在,而TextBox则是和Form平起平坐,因此我们直接给出代码方便大家的学习。

 

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

public class TextFieldWithItemStateListenerMIDlet extends MIDlet

implements ItemStateListener

{

        private Display display;

        public TextFieldWithItemStateListenerMIDlet()

        {

                display = Display.getDisplay(this);

        }

        TextField name ;

        TextField tel ;

        TextField summary ;

        public void startApp()

        {

                Form f = new Form("TextField测试") ;

 

                name = new TextField("姓名","",8,TextField.ANY) ;

                tel = new TextField("电话","",14,TextField.PHONENUMBER) ;

                summary = new TextField("总结","",30,TextField.UNEDITABLE) ;

 

                f.append(name) ;

                f.append(tel) ;

                f.append(summary) ;

                f.setItemStateListener(this);

                display.setCurrent(f);

        }

        public void itemStateChanged(Item item)

        {

                if(item==name)

                {

                        summary.setString("输入的姓名为:"+name.getString());

                }else if(item==tel)

                {

                        summary.setString("输入的电话为:"+tel.getString());

                }else

                {

                       summary.setString("");

                }

        }

        public void pauseApp()

        {

        }

        public void destroyApp(boolean unconditional)

        {

        }

}

 

DateField的目的是方便用户输入时间,它的构造函数共有三个参数,一个是Label,一个是输入模式,一个是java.util.TimeZone对象,也可以省去第三个参数,只使用前两个。

3.9    GaugeSpacer,ChoiceGroup

3.9.1   Gauge

Alert有一套方法可以显示进度,利用setIndicator()/getIndicator()这组函数,可以显示进度的画面。Gauge的最大用处就是拿来当进度显示使用。

 

 

拿来当进度显示用的Gauge对象必须满足如下要求:

l         控制与用户交互的构造函数的第二个参数必须为flase

l         不能被其他的Form或者Alert使用

l         不能加入Command

l         不能有Label

l         不能自己设定等效线的位置。

l         不能自己设定组件的大小。

 

大家可以参考如下的代码:

import javax.microedition.lcdui.*;

import javax.microedition.midlet.*;

public class AlertWithIndicatorMIDlet extends MIDlet

implements CommandListener

{

        private Display display;

        public AlertWithIndicatorMIDlet()

        {

                display = Display.getDisplay(this);

        }

        Gauge g ;

        public void startApp()

        {

                Alert al = new Alert("处理中");

                al.setType(AlertType.INFO);

                al.setTimeout(Alert.FOREVER);

                al.setString("系统正在处理中");

 

                g = new Gauge(null,false,10,0) ;

                al.setIndicator(g);

 

                Command start = new Command("开始",Command.OK,1) ;

                Command stop = new Command("停止",Command.STOP,1) ;

                al.addCommand(start);

                al.addCommand(stop);

                al.setCommandListener(this);

                display.setCurrent(al);

        }

        public void commandAction(Command c,Displayable s)

        {

                String cmd = c.getLabel() ;

                if(cmd.equals("开始"))

                {

                        for(int i=0 ; i <11 ; i++)

                        {

                                g.setValue(i);

                                try

                                {

                                        Thread.sleep(500);

                                }catch(Exception e){}

                        }

                }else if(cmd.equals("停止"))

                {

                        notifyDestroyed() ;

                }

        }

        public void pauseApp()

        {

        }

        public void destroyApp(boolean unconditional)

        {

        }

}

 

3.9.2   Spacer

Spacer的用处很简单,就是加一处空白,大家可以参考API文档进行实际开发。

 

3.9.3   ChoiceGroup

ChoiceGroupList大同小异,因为二者都实现了Choice接口,所以在很多地方是一样的,但是请注意一点,在这里我们不能使用Choice.IMPLICIT类型,只能用Choice.EXCLUSIVE,Choice.MUTIPLE,Choice.POPUP,三种类型,与List的区别即第三种弹出式菜单。

阅读(2728) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册