返回 登录
0

用J2SE+CSS开发跨平台的手机云应用

开发第一个HTMLMlet

新型交互面板HTMLMlet,继承J2SE的JPanel,为JComponent设置CSS,以获得CSS强大展示。实例化时,容器将其转换为手机端所需的HTML5+JavaScript+CSS,并将用户响应转换为J2SE的Event,驱动JComponent侦听器。

因此,仅需关注业务界面构造和事件响应,其它则全部交与服务器。

以下我们通过简单四步,用J2SE+CSS来实现如下图所示,可运行于iPhone和Android的云应用。(不精通CSS,界面可能会很丑哟!)

打开服务器的"设计器",如果没有安装,请参阅"附录-安装开发环境"。
设计器缺省打开"MyFirst"工程。

1. 添加HTMLMlet

点击工具条中的"Add Item"按钮,显示如下:

选中"form",点击"下页":

选中"HTMLMlet",点击"确认"。

将"Display Name"改为"HTMLMlet","Target Locator"改为"MyHTMLMlet"。粘贴如下代码到"JRuby Script"区。

#encoding:utf-8

import javax.imageio.ImageIO
import javax.swing.JButton
import javax.swing.JTextArea
import javax.swing.JPanel
import javax.swing.ImageIcon
import javax.swing.SwingConstants
import java.awt.BorderLayout
import java.awt.Dimension
import java.awt.GridLayout
import java.net.URL
import Java::hc.server.ui.ProjectContext

class MyHTMLMlet < Java::hc.server.ui.HTMLMlet
    def initialize
        super #invoke super construct method

        @area = JTextArea.new()
        @area.setEditable(false)
        @btn_light = JButton.new()
        @btn_switch = JButton.new()

        @icon_press_on = ImageIcon.new(ImageIO.read(URL.new("http://homecenter.mobi/images/press_on_64.png")))
        @icon_press_off = ImageIcon.new(ImageIO.read(URL.new("http://homecenter.mobi/images/press_off_64.png")))
        @icon_light_on = ImageIcon.new(ImageIO.read(URL.new("http://homecenter.mobi/images/light_on_64.png")))
        @icon_light_off = ImageIcon.new(ImageIO.read(URL.new("http://homecenter.mobi/images/light_off_64.png")))

        @context = getProjectContext()

        @isLightOn = false
        @btn_switch.setIcon(@icon_press_off)
        @btn_light.setIcon(@icon_light_off)
        @btn_switch.setToolTipText("light,lumière,Licht,빛,свет,灯")#说“灯”便可打开这个界面。(至少打开一次,内置lucene便会记录,供语音命令之用)

        setCSS(@btn_switch, "iconStyle", nil)#iconStyle is defined global CSS (the following section) and is automatically loaded for all HTMLMlet in current project
        setCSS(@btn_light, "iconStyle", nil)

        buttonStyle = ".btnStyle{width:100%;height:100%;border-radius: " + getButtonHeight().to_s() + "px;display: block;transition: all 0.15s ease;border: 0.1em solid #4fc08d;background-color: #fff;color: #42b983;}"
        areaStyle = ".areaStyle{width:100%;height:100%;border: 1px solid #fff;font-size:" + getFontSizeForNormal().to_s() + "px;background-color:#fff;color:#42b983}"
        loadCSS(buttonStyle + areaStyle)

        setCSS(@area, "areaStyle", nil)#areaStyel is defined above.
        #it equals with setCSS(@area, nil, "width:100%;height:100%;border: 1px solid #fff;font-size:" + getFontSizeForNormal().to_s() + "px;background-color:#fff;color:#42b983")

        lightPanel = JPanel.new
        lightPanel.setLayout(GridLayout.new(1, 2))
        lightPanel.add(@btn_light)
        lightPanel.add(@btn_switch)

        @btn_switch.addActionListener{|e|
            @area.append("click switch\n")
            @isLightOn = !@isLightOn
            if @isLightOn
                @context.sendMovingMsg("light on")
                @btn_switch.setIcon(@icon_press_on)
                @btn_light.setIcon(@icon_light_on)
            else
                @context.sendMovingMsg("light off")
                @btn_switch.setIcon(@icon_press_off)
                @btn_light.setIcon(@icon_light_off)
            end
        }

        buttonPanel = JPanel.new()
        buttonPanel.setLayout(GridLayout.new(1, 2))
        buttonPanel.setPreferredSize(Dimension.new(getMobileWidth(), getButtonHeight()))
        setCSS(buttonPanel, nil, "background-color:white;")

        button = JButton.new("Screen")
        setCSSForDiv(button, "btnForDiv", nil)
        setCSS(button, "btnStyle", nil)
        button.addActionListener{|e|
            go(Java::hc.server.ui.Mlet::URL_SCREEN)#打开电脑桌面,远程访问屏幕
        }
        buttonPanel.add(button)

        button = JButton.new("Back")
        setCSSForDiv(button, "btnForDiv", nil)
        setCSS(button, "btnStyle", nil)
        button.addActionListener{|e|
            back()#exit and return back
        }
        buttonPanel.add(button)

        setLayout(BorderLayout.new())
        add(lightPanel, BorderLayout::NORTH)
        add(@area, BorderLayout::CENTER)
        add(buttonPanel, BorderLayout::SOUTH)
    end

    #override empty method onStart
    def onStart
        @area.append("Sys call onStart\n")
    end

    #override empty method onPause
    def onPause
        @area.append("Sys call onPause\n")
    end

    #override empty method onResume
    def onResume
        @area.append("Sys call onResume\n")
    end

    #override empty method onExit
    def onExit
        @context.tipOnTray("Sys call onExit")
    end
end

return MyHTMLMlet.new

提示:
1. 图片通过网络加载,实际应用时,可存放在jar内,以免网络迟延或故障;
2. 为展示方法API文档,将鼠标移至方法上即可。

2. 设置权限

由于本示例加载网络图片,需要联网权限,请点击左侧“MyFirst”项目节点,点击“Permission”分页,取消“limit socket/connect”勾选。

3. 设置全局CSS

点击左侧树的Resources/CSS Styles,将下面CSS粘贴到"Styles Edit Area"。

.iconStyle {
    text-align:center;
    vertical-align:middle;
    width:100%;
    height:100%;
    transition: all 0.15s ease;
    border: 1px solid #fff;
    background-color: #fff;
    display: inline-block;
    box-sizing: border-box;
}

.btnForDiv {
    padding:0.2em;/*default box-sizing: border-box;*/
    display: table-cell;
    text-align: center;
    vertical-align: center;
}

4. 发布应用

点击工具条中的"Activate"按钮,系统询问是否保存修改,点击"是",成功加载工程后,显示如下:

祝贺您,第一个HTMLMlet已就诸,通过手机端,可以访问啦!(手机端内附演示帐号,点击“演示帐号”,即可访问)

登录手机端后,它以菜单项“HTMLMlet”呈现,点击便显示。

此时工程仅供您的手机访问,您的好友并不能下载并安装到他们自己的服务器上(如果您的用户并不想创建自己的服务器,您可将服务器帐号和密码告诉他们,这台服务器便由您托管了),将可供下载的网址复制到"MyFirst"项目节点下的"Upgrade URL"输入框中,点击工具条中的"Save As",就可导出工程。(如果您已在"Developer Certificates"创建了证书,导出的同时进行签名)

将导出的har和had两文件上传,生成had的下载网址的二维码图片,好友即可扫描,安装到各自的服务器上了。

更多惊喜

  1. 喜欢JavaScript特效,我们为您预备了ScriptPanel。
  2. 内置分词lucane,后台分析HTMLMlet,根据语音命令打开匹配度最高的界面。(仅需一行代码,如上:setToolTipText(“light,lumière,Licht,빛,свет,灯”),说“灯”,即可语音打开本HTMLMlet)
  3. 手机语音命令编程接口,轻松响应语音指令,让手机成为专属、贴心的智能助手(图灵机器人开发示例及体验帐号)。
  4. 内置Cron表达式的Quartz任务调度包和HSQLDB数据库,优化并封装原编程接口(示例),用企业级利器解决家庭级定时任务,简洁又不失强劲!
  5. 通过工具条上的"Demo"按钮,加载演示工程,它涵盖了80%以上的JRuby语法和90%以上的常用功能。
  6. 服务器内置Java 8 API文档和CSS文档,自动代码提示和API显示。
  7. HAR无需任何修改,便能运行于安卓平台上,因为安卓版使用了"J2SE for Android"开源包(如工程内含有标准的jar库,会在安装时,转码成dex)。
  8. 关注、下载最新服务器源代码,请转至https://github.com/javalovercn/homecenter

附录-安装开发环境

  1. 确保已安装Java运行环境(Java Runtime Environment)或Java开发环境(Java SE Development Kit),没安装,从https://www.java.com/下载安装。
  2. 安装HomeCenter启动器,打开https://github.com/javalovercn/hc_server_dist,下载相应操作系统压缩包,比如Windows系统,则是"HC_Server_For_Win.zip"。
  3. 手机端下载,请打开https://github.com/javalovercn/client
  4. 解压包,双击可执行脚本。例如:Windows系统是"HomeCenter.bat";Mac系统则是"HomeCenter.command"。
  5. 启动器在运行时,会检查、下载最新的服务器内核。
  6. 下载成功后,系统显示软件使用许可协议对话框,点选"我同意"项,点击"同意"继续。
  7. 输入电子邮箱作为帐号。注:账号创建完后,并不能表明你是该邮箱的拥有者,稍后可进行邮箱验证。
  8. 服务器上线成功后,弹出如下信息:

  1. 初次安装,服务器会在后台下载JRuby引擎。JRuby引擎是一个jar包,约20M,下载校验后,系统提示如下:

  1. 祝贺您,现在可以开始编写第一个HAR工程了!(如果您是最终用户,且不需开发HAR,手机登录后,扫描好友或供应商的二维码以安装HAR工程包,即加即用。)
  2. 点击"确认",进入设计器,界面如下:

附录-服务器的基本机理

服务器加载单元是HAR(Home Archive)工程包,采用jar格式封装应用的脚本、图标或所依赖的可执行jar。无需担忧如何发布工程包,点击"Save As"按钮即可完成HAR包的导出和签名。服务器既是运行容器,也是设计器,即HAR的开发环境(注:Android版的服务器除外,这是因为Android并不适合脚本编写,所以Android版仅供运行,而非开发。特别说明:此处的Android版为服务器端,而非手机端的Android版本)。HAR工程运行在JRuby解释器上。JRuby是采用纯Java实现的Ruby解释器,它结合了Ruby语言的简易性和功能强大的JVM的执行机制,包括与Java库全面集成。

版权许可

本文采用「保持署名—非商用」创意共享 4.0 许可证。
只要保持原作者署名和非商用,您可以自由地阅读、分享、修改本书。
详细的法律条文请参见创意共享网站。

评论