这一篇是前面几篇的综合,前面几篇是基础,文件浏览器无非就是遍历目录,查看文件。J2ME文件浏览器的源码网上已经有了,是MIDP写的,我把它改造为LWUIT版本。这两种方式的文件浏览器我都在真机上测试通过,不过MIDP版本的在读取文本文件时,中文出现乱码,原因是它采用的是GBK编码形式,在源码中把格式换成UTF-8就可以了。

文件浏览器的原理比较简单,手机需要支持JSR75,根据前面的知识还是比较容易做出来的。
下面是简单的流程图:

JFileChooser文件夹 jdim文件夹_j2me

 

用LWUIT做文件浏览器只需要3个Form:

  • ListForm,包含List组件,用于显示文件和文件夹列表
  • ImageForm,包含Button组件,Button用于盛装图片
  • TextForm,包含TextArea组件,用户盛装文本

无图无真相,还是先看看效果:

JFileChooser文件夹 jdim文件夹_image_02

JFileChooser文件夹 jdim文件夹_JFileChooser文件夹_03

JFileChooser文件夹 jdim文件夹_image_04

JFileChooser文件夹 jdim文件夹_j2me_05

JFileChooser文件夹 jdim文件夹_JFileChooser文件夹_06

JFileChooser文件夹 jdim文件夹_JFileChooser文件夹_07

 

 

 

 

 

 

 

源代码下载地址(通过测试)

代码:

IconHelper.java图标帮助类,根据文件扩展名显示相应图标

package main;
/*
	File:
		IconHelper.java
	Purpose:
		图标帮助类
	Functions:
		getIconByExt		public	按照扩展名(不包括'.'符号)获取文件的图标对象
	History:
		%yongsongw% @ 2008-8-1: created.
	Copyright (C) 2008 Fool studio.
	All rights reserved.
*/
import java.util.Hashtable;
import com.sun.lwuit.Image;
import java.io.IOException;
public class IconHelper {
	//图标资源
	private Image imgFolder;
	private Image unknownImage;
	private Image textImage;
	//Audio
	private Image audioImage;
	//Picture
	private Image picImage;
	private Image jpgImage;
	//Video
	private Image sgpImage;
	private Image aviImage;
	private Image wmvImage;
	private Image mpgImage;
	//Web
	private Image zipImage;
	private Image htmlImage;
	private Image xmlImage;
	//Source
	private Image cImage;
	private Image cppImage;
	private Image headerImage;
	//图标管理容器
	private Hashtable iconTable;
	//-------------------------------------------------------------------------
	public IconHelper() {
		iconTable = new Hashtable();
        try {
			//载入图标资源
            imgFolder = Image.createImage("/filetype/folder.png");
            unknownImage = Image.createImage("/filetype/unknown.png");
			textImage = Image.createImage("/filetype/text.png");
			//Audio
            audioImage = Image.createImage("/filetype/audio.png");
			//Picture
            picImage = Image.createImage("/filetype/pic.png");
            jpgImage = Image.createImage("/filetype/jpg.png");
			//Video
            sgpImage = Image.createImage("/filetype/3gp.png");
            aviImage = Image.createImage("/filetype/avi.png");
            wmvImage = Image.createImage("/filetype/wmv.png");
            mpgImage = Image.createImage("/filetype/mpg.png");
			//Web
            zipImage = Image.createImage("/filetype/zip.png");
            htmlImage = Image.createImage("/filetype/html.png");
            xmlImage = Image.createImage("/filetype/xml.png");
			//Source
            cImage = Image.createImage("/filetype/c.png");
            cppImage = Image.createImage("/filetype/cpp.png");
            headerImage = Image.createImage("/filetype/header.png");
        }
		catch (IOException e) {
			//图标资源
			imgFolder = null;
			unknownImage = null;
			textImage = null;
			//Audio
			audioImage = null;
			//Picture
			picImage = null;
			jpgImage = null;
			//Video
			sgpImage = null;
			aviImage = null;
			wmvImage = null;
			mpgImage = null;
			//Web
			zipImage = null;
			htmlImage = null;
			xmlImage = null;
			//Source
			cImage = null;
			cppImage = null;
			headerImage = null;
			e.printStackTrace();
        }
		initTable();
	}
	//-------------------------------------------------------------------------
	private void initTable() {
		//Key为扩展名(不包括'.'符号),值为content type
		iconTable.put("/", imgFolder);
		iconTable.put("", unknownImage);
		iconTable.put("txt", textImage);
		//Source
		iconTable.put("c", cImage);
		iconTable.put("cpp", cppImage);
		iconTable.put("h", headerImage);
		//Web
		iconTable.put("html", htmlImage);
		iconTable.put("htm", htmlImage);
		iconTable.put("xml", xmlImage);
		iconTable.put("zip", zipImage);
		iconTable.put("jar", zipImage);
		//Video
		iconTable.put("mp3", audioImage);
		iconTable.put("wma", audioImage);
		iconTable.put("mid", audioImage);
		iconTable.put("wav", audioImage);
		//Picture
		iconTable.put("gif", picImage);
		iconTable.put("png", picImage);
		iconTable.put("jpg", jpgImage);
		iconTable.put("jepg", jpgImage);
		//Video
		iconTable.put("3gp", sgpImage);
		iconTable.put("avi", aviImage);
		iconTable.put("wmv", wmvImage);
		iconTable.put("mpeg", mpgImage);
		iconTable.put("mpg", mpgImage);
		iconTable.put("mp4", mpgImage);
	}
	//-------------------------------------------------------------------------
	//按照扩展名(不包括'.'符号)获取文件的图标对象
	public Image getIconByExt(final String extension) {
		Image temp = (Image)iconTable.get(extension);
		//是否为空,则使用默认图标替代
		return( (temp == null) ? unknownImage : temp);
	}
	//-------------------------------------------------------------------------
}

 

MainPanel主面板,显示文件、文件夹列表,浏览文件:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main;
import com.sun.lwuit.Button;
import com.sun.lwuit.Command;
import com.sun.lwuit.Component;
import com.sun.lwuit.Container;
import com.sun.lwuit.Dialog;
import com.sun.lwuit.Form;
import com.sun.lwuit.Image;
import com.sun.lwuit.Label;
import com.sun.lwuit.List;
import com.sun.lwuit.TextArea;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.layouts.BorderLayout;
import com.sun.lwuit.list.ListCellRenderer;
import com.sun.lwuit.plaf.Border;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Vector;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.io.file.FileSystemRegistry;
/**
 *
 * @author Sunny
 */
public class MainPanel implements ActionListener {
    //常量定义
    private final String UP_DIR = "..";
    private final String SEPS_STR = "/";
    private final int SEPS_CHAR = '/';
    private final String ROOT = "/";
    private final String RES_PREFIX = "file://";
    private final int BLOCK_SIZE = 256;
    //扩展名
    private final String TEXT_EXT[] = {".TXT", ".H", ".HPP", ".C", ".CPP", ".INC"};
    private final String IMAGE_EXT[] = {".JPG", ".JPEG", ".PNG", ".GIF"};
    private final String WEB_EXT[] = {".HTM", ".HTML", ".XML", ".CSS"};
    //字符编码
    private final String CHARACTER_CODE = "UTF-8";
    //主MIDlet
    private MainMIDlet let = null;
    //主界面
    private Form listForm = null;
    //内容列表
    private List contentList = null;
    //显示文件用窗体
    private Form textForm = null;
    //装载文本项目用
    private TextArea text = null;
    //显示图片用的窗体
    private Form imageForm = null;
    //命令
    private Command cmdExit = null;//退出程序
    private Command cmdView = null;//浏览目录/文件
    private Command cmdDone = null;//退出浏览文件内容
    //图标帮助类
    private IconHelper helper = null;
    //当前目录路径
    private String currentDir = null;
    public MainPanel(MainMIDlet __let) {
        let = __let;
        //初始化当前目录为根目录
        currentDir = ROOT;
        //初始化图标帮助实例
        helper = new IconHelper();
        listForm = new Form("");
        listForm.setLayout(new BorderLayout());
        //主显示为List
//        contentList = new List();
//        contentList.setListCellRenderer(new MyRenderer());
//        listForm.addComponent(BorderLayout.CENTER, contentList);
        //文本显示窗体
        textForm = new Form("");
        //文本装载项目
        text = new TextArea();
        text.setWidestChar('一');
        //图像显示窗体
        imageForm = new Form("");
        //创建命令
        cmdExit = new Command("退出");
        cmdView = new Command("浏览");
        cmdDone = new Command("返回");
        //添加命令绑定
        listForm.addCommand(cmdExit);
        listForm.addCommand(cmdView);
        listForm.addCommandListener(this);
        //添加文字处理框
        textForm.setLayout(new BorderLayout());
        textForm.addComponent(BorderLayout.CENTER, text);
        //设置文本浏览器窗体的绑定命令
        textForm.addCommand(cmdDone);
        textForm.addCommandListener(this);
        //设置图像浏览窗体的命令绑定
        imageForm.addCommand(cmdDone);
        imageForm.addCommandListener(this);
        //初始化显示
        new BrowseThread(currentDir, true).start();
    }
    class MyContainer extends Container {
        private Label name;
        public MyContainer(String source) {
            name = new Label(source);
            name.getStyle().setBgTransparency(0);
            addComponent(name);
        }
    }
    class MyRenderer implements ListCellRenderer {
        private Label focus;
        public MyRenderer() {
            focus = new Label();
            Border b = Border.createLineBorder(1, 0xff0000);
            focus.getStyle().setBorder(b);
        }
        public Component getListCellRendererComponent(List list, Object value, int index, boolean selected) {
            return (MyContainer) value;
        }
        public Component getListFocusComponent(List list) {
            return focus;
        }
    }
    public void actionPerformed(ActionEvent evt) {
        Command c = evt.getCommand();
        if (c == cmdExit) {
            let.exit();
        } else if (c == cmdView) {//查看命令
            //当前列表中没有目录项
            if (contentList.size() == 0) {
                //启动线程来浏览指定目录
                new BrowseThread(ROOT, true).start();
            } else {
                final String url = ((MyContainer) contentList.getSelectedItem()).name.getText();
                if (url.endsWith(SEPS_STR) == true) {//当前项目为目录,则显示其子项目
                    //启动浏览线程来浏览指定目录
                    new BrowseThread(currentDir + url, true).start();
                } else if (url.endsWith(UP_DIR) == true) {//当前项目为父目录,则需要回退
                    backward();
                } else {//当前项目为文件
                    //启动浏览线程来浏览指定文件
                    new BrowseThread(currentDir + url, false).start();
                }
            }
        } else if (c == cmdDone) {//关闭文本阅读,返回目录浏览
            //启动浏览线程来浏览指定文件
            new BrowseThread(currentDir, true).start();
        }
    }
    //-------------------------------------------------------------------------
    //回退浏览当前目录的父目录内容
    private void backward() {
        //获取当前目录的父目录名称
        int pos = currentDir.lastIndexOf(SEPS_CHAR, currentDir.length() - 2);
        if (pos != -1) { //存在上层目录
            currentDir = currentDir.substring(0, pos + 1);
        } else { //不存在上层目录即根目录
            currentDir = ROOT;
        }
        //启动浏览线程来浏览指定目录
        new BrowseThread(currentDir, true).start();
    }
    class BrowseThread extends Thread {
        private String url = null;
        private boolean isDirectory = false;
        public BrowseThread(final String __url, final boolean __isDirectory) {
            url = __url;
            isDirectory = __isDirectory;
        }
        public void run() {
            //浏览目录或文件
            if (isDirectory) {
                text.setText("");
                imageForm.removeAll();
                showDir(url);
            } else {
                showFile(url);
            }
        }
        //显示指定目录
        public void showDir(final String dir) {
            //设置列表title
            Enumeration em = null;
            FileConnection fc = null;
            //设置当前目录
            currentDir = dir;
            //初始化列表
            listForm.removeAll();
            contentList = new List();
            contentList.setListCellRenderer(new MyRenderer());
            listForm.addComponent(BorderLayout.CENTER, contentList);
            try {
                if (dir.equals(ROOT) == true) {
                    //枚举根目录列表
                    em = FileSystemRegistry.listRoots();
                } else {//非根目录
                    fc = (FileConnection) Connector.open(RES_PREFIX + dir);
                    em = fc.list();
                    //添加上层根目录
                    MyContainer up = new MyContainer(UP_DIR);
                    up.name.setIcon(helper.getIconByExt("/"));
                    contentList.addItem(up);
                }
                while (em.hasMoreElements()) {
                    String fileName = (String) em.nextElement();
                    if (fileName.endsWith(SEPS_STR)) {//如果为目录
                        //v.addElement(fileName);
                        MyContainer c = new MyContainer(fileName);
                        c.name.setIcon(helper.getIconByExt("/"));
                        contentList.addItem(c);
                        System.out.println(fileName);
                        System.out.println("It's OK!");
                    } else {//非目录(文件)
                        MyContainer c = new MyContainer(fileName);
                        c.name.setIcon(helper.getIconByExt(extractExt(fileName)));
                        contentList.addItem(c);
                    }
                }
                listForm.revalidate();
                //初始化选择
                contentList.setSelectedIndex(0, true);
                //关闭文件连接
                if (fc != null) {
                    fc.close();
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            listForm.show();
        }
        //---------------------------------------------------------------------
        //显示指定文件内容
        private void showFile(final String fileName) {
            //Dialog.show(RES_PREFIX, fileName, "ok", "cancel");
            String tempFileName = fileName.toUpperCase();
            try {
                FileConnection fc = (FileConnection) Connector.open(RES_PREFIX + fileName);
                if (isEndWithIn(tempFileName, IMAGE_EXT) == true) {//图片文件
                    //创建流
                    InputStream is = fc.openInputStream();
                    Image img = Image.createImage(is);
                    //设置图片窗体Title
                    imageForm.setTitle(getRelativeName(fileName));
                    imageForm.setLayout(new BorderLayout());
                    imageForm.removeAll();
                    Button b = new Button(img);
                    imageForm.addComponent(BorderLayout.CENTER, b);
                    //关闭流
                    is.close();
                    //关闭文件连接
                    fc.close();
                    imageForm.show();
                } else {//文本文件
                    int rawFileSize = (int) (fc.fileSize());
                    int fileSize = ((rawFileSize / BLOCK_SIZE) + 1) * BLOCK_SIZE;
                    //依据文件内容设置title
                    textForm.setTitle(getRelativeName(fileName) + ", " + rawFileSize + "/" + fileSize);
                    DataInputStream dis = fc.openDataInputStream();
                    byte[] buffer = new byte[rawFileSize];
                    //读取文件内容
                    dis.readFully(buffer);
                    textForm.setLayout(new BorderLayout());
                    textForm.removeAll();
                    text.setText(new String(buffer, "UTF-8"));
                    textForm.addComponent(BorderLayout.CENTER, text);
                    //关闭流
                    dis.close();
                    //关闭文件连接
                    fc.close();
                    textForm.show();
                    
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        //-------------------------------------------------------------------------
        //指定文件名称是否以数组中内容结尾
        private boolean isEndWithIn(final String fileName, final String[] extArray) {
            for (int i = 0; i < extArray.length; ++i) {
                if (fileName.endsWith(extArray[i]) == true) {
                    return (true);
                }
            }
            return (false);
        }
        //-------------------------------------------------------------------------
        //从完整文件名中提取相对文件名
        private String getRelativeName(final String fileName) {
            int pos = fileName.lastIndexOf(SEPS_CHAR);
            if (pos == -1) {
                return ("");
            }
            return (fileName.substring(pos + 1, fileName.length()));
        }
        //-------------------------------------------------------------------------
        //获取扩展名(不包括'.'符号)
        private String extractExt(final String fileName) {
            int pos = fileName.lastIndexOf('.');
            return (fileName.substring(pos + 1, fileName.length()).toLowerCase());
        }
        //---------------------------------------------------------------------
    }
}

 

MIDlet启动类:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main;
import com.sun.lwuit.Display;
import javax.microedition.midlet.*;
/**
 * @author Sunny
 */
public class MainMIDlet extends MIDlet {
    //主显示面板
    private MainPanel panel = null;
    
    public void startApp() {
        Display.init(this);
        panel = new MainPanel(this);
    }
    public void pauseApp() {
    }
    public void destroyApp(boolean unconditional) {
    }
    public void exit(){
        destroyApp(false);
        notifyDestroyed();
    }
}