2018年6月

IDEA下开发JavaFx Application

New > project > JavaFx Application

添加SceneBuilder

  1. 下载SceneBuilder
  2. file | setting > JavaFx > add path

设置自定义图标

primaryStage.getIcons().add(new Image("file:res/internet.png"));

打包生成exe

File | project structure > Artifacts > JavaFx >(class | title | Navite Bundle)

注意目录文件要能找到

事件绑定

fxml

onAction add

Java

添加函数

fx:id 对象属性修改

  1. 添加一个fxml成员变量
  2. 调用setText("");

我的代码

MainApp.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.DialogPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.text.Font?>

<FlowPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.thinkmoon.CSMA_CD.MainApp">
<children>
    <Pane prefHeight="400.0" prefWidth="800.0">
        <children>
            <Button layoutX="154.0" layoutY="206.0" mnemonicParsing="false" onAction="#handleSendDataPackage" text="发送数据包">
                <font>
                    <Font size="14.0" />
                </font></Button>
            <Button layoutX="283.0" layoutY="206.0" mnemonicParsing="false" text="重置操作">
                <font>
                    <Font size="14.0" />
                </font></Button>
            <TextArea layoutX="500.0" layoutY="51.0" prefHeight="299.0" prefWidth="277.0" />
            <Label fx:id="host1SendNum" layoutX="43.0" layoutY="70.0" text="主机1所需发送的数据包数:">
                <font>
                    <Font size="17.0" />
                </font>
            </Label>
            <Label layoutX="43.0" layoutY="130.0" text="主机2所需发送的数据包数:">
                <font>
                    <Font size="17.0" />
                </font>
            </Label>
            <Label layoutX="52.0" layoutY="291.0" text="主机1">
                <font>
                    <Font size="18.0" />
                </font>
            </Label>
            <Label layoutX="410.0" layoutY="291.0" text="主机2">
                <font>
                    <Font size="18.0" />
                </font>
            </Label>
            <TextField layoutX="279.0" layoutY="71.0" />
            <TextField layoutX="279.0" layoutY="130.0" />
            <Label layoutX="292.0" layoutY="14.0" text="模拟以太网发送过程">
                <font>
                    <Font size="17.0" />
                </font>
            </Label>
            <Label layoutX="48.0" layoutY="327.0" style="-fx-border-width: 1; -fx-border-color: #218ada;" styleClass="tip" text="信道空闲" textFill="#218ada">
                <padding>
                    <Insets bottom="2.0" left="2.0" right="2.0" top="1.0" />
                </padding>
            </Label>
            <Label layoutX="406.0" layoutY="327.0" style="-fx-border-width: 1; -fx-border-color: #218ada;" styleClass="tip" text="信道空闲" textFill="#218ada">
                <padding>
                    <Insets bottom="2.0" left="2.0" right="2.0" top="1.0" />
                </padding>
            </Label>
            <TextField layoutX="114.0" layoutY="292.0" prefHeight="23.0" prefWidth="19.0" />
            <TextField layoutX="140.0" layoutY="292.0" prefHeight="23.0" prefWidth="19.0" />
            <TextField layoutX="170.0" layoutY="292.0" prefHeight="23.0" prefWidth="19.0" />
            <TextField layoutX="199.0" layoutY="292.0" prefHeight="23.0" prefWidth="19.0" />
            <TextField layoutX="226.0" layoutY="292.0" prefHeight="23.0" prefWidth="19.0" />
            <TextField layoutX="257.0" layoutY="292.0" prefHeight="23.0" prefWidth="19.0" />
            <TextField layoutX="283.0" layoutY="292.0" prefHeight="23.0" prefWidth="19.0" />
            <TextField layoutX="311.0" layoutY="292.0" prefHeight="23.0" prefWidth="19.0" />
            <TextField layoutX="340.0" layoutY="292.0" prefHeight="23.0" prefWidth="19.0" />
            <TextField layoutX="369.0" layoutY="292.0" prefHeight="23.0" prefWidth="19.0" />
        </children>
    </Pane>
      <DialogPane />
</children>
</FlowPane>

MainApp.java

package cn.thinkmoon.CSMA_CD;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.stage.Stage;

import java.io.IOException;

public class MainApp extends Application {
    private Stage primaryStage;
    @FXML
    private Label host1SendNum;
    @Override
    public void start(Stage primaryStage) throws Exception{
        this.primaryStage = primaryStage;
        initRootLayout();
    }
    /**
     * 初始化主界面布局
     */
    public void initRootLayout() {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("view/MainApp.fxml"));
            primaryStage.setTitle("CSMA/CD协议仿真及演示");
            primaryStage.setScene(new Scene(root, 800, 400));
            primaryStage.setResizable(false);
            primaryStage.getIcons().add(new Image("file:res/internet.png"));
            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        launch(args);
    }
    @FXML
    private void handleSendDataPackage(ActionEvent event) {

    }
}

所需条件

  1. 安卓手机(模拟器我没试过)
  2. 已获ROOT或已安装Virtual Xposed
  3. Xposed框架能安装成功

所需软件

  1. xposed install(安装xposed 框架)
  2. lataclysm(模拟运动位置)
  3. SoDo Hide(对应用隐藏xposed框架)
  4. 运动模拟器(模拟计步传感器)

准备工作

  1. 安装上述软件
  2. 在xposed install里面将模块激活
  3. 重启手机
未完待续,心情好了再续

首先,为什么我们需要这个?

因为微信小程序虽然可以可以绘制svg图片,但是在真机调试的时候却渲染不出来。所以我们需要一个工具(可以将svg转成微信小程序支持的canvas并绘制出来)。

我使用的是touch-wx + vs code 开发。

现已启用该开发模式.因为Ubuntu下经常编译不完整

Touch WX 是什么?

Touch WX

Touch WX是一套完全免费的微信小程序开发框架,包含丰富的UI控件用于官方组件的补充。与Touch UI开发方式很相似,也是通过VSCode编辑器+插件的方式开发,经过编译后输出小程序代码。
与其他小程序框架最主要的区别在于:Touch UI完全是基于小程序官方的自定义组件机制实现,输出的是小程序原始代码,而不是输出开发者完全无法阅读的编译代码。这样当遇到问题时,开发者可以很方便的定位问题所在,还可以基于输出的原始代码继续开发。
当你用Touch UI开发了H5应用,可以直接导入到Touch WX进行转换,稍作调整就能生成小程序。反之也同样,当你Touch WX开发了微信小程序,可以导出为Touch UI工程来生成H5应用。

Touch WX 的特点

Touch WX

我的理解

Touch WX 就是一个可以将特定的nodejs项目编译成微信小程序项目的框架

Touch WX更多操作

更多操作见http://www.touchui.io/touchui_doc_wx/

推荐大家看一下,或许会打开新世界的大门哦!

接下来,我默认你已经看了Touch WX的文档,并且拥有一定的nodejs基础

开始流程

安装parse-svg-path

npm install parse-svg-path --save

引入parse-svg-path

var parse = require('parse-svg-path')

使用parse-svg-path

parse(d)

d为svg中的path值

不了解svg?

请转http://www.w3school.com.cn/svg/svg_intro.asp

如何获得path值?

var options = {
            url:"svg的URL",
            success:function(res){
              const ctx = wx.createCanvasContext('myCanvas')
              ctx.setFillStyle('black')
              var match = res.data.match(/d="(.*?)"/);
              var d = match[1];
              console.log(d);
            }
    }
    wx.request(options); 
上图中d就是path值,我这里使用的是正则表达式查找,而且只有一个path,如不一样,请自行modify

解析后的值

console.log(parse(d));

效果展示

解析之后是一系列的操作序列数组

绘制图形

根据一系列的操作,找到对应的微信小程序绘制API,进行绘制
parse(d).forEach(function (element){
                if(element[0] == "M"){
                  ctx.moveTo(element[1], element[2])
                }else if(element[0] == "Q"){
                  ctx.quadraticCurveTo(element[1], element[2], element[3], element[4])
                }
              });
因为我这里只有M,Q操作所以我只用了两个API,可根据实际情况自行拓展

实例代码

display.wx

<template>
  <view class='page'>
    <canvas canvas-id="myCanvas" style="border: 1px solid;"/>
    <!-- <view class='content'><text class="zhuan" style="font-size:{{fontSize}}pt">{{display}}</text> -->
  <!-- </view> -->
</view>
</template>

<script>
var parse = require('parse-svg-path')
export default {
  config: {
    navigationBarTitleText: '效果展示'
  },
  data: {},
  onLoad: function (options) {
    var str = options.display;
    if(str != null){
      try {
        str=decodeURI(str);
        wx.setStorageSync('display', str)
        console.log("接受到的str:"+str);
      } catch (e) {
        console.log("设置diaplay值错误")
      }
    }  
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
  
  },
  saveTemp(){
    console.log("fdsaf");
    wx.canvasToTempFilePath({
      canvasId: 'myCanvas',
      fail: function(res) {
        console.log(res);
      },
      success: function(res) {
        console.log(res.tempFilePath)
        setTimeout(function(){wx.saveImageToPhotosAlbum({
          filePath:res.tempFilePath,
          fail:function(res){
            console.log(res);
          }
          
          });},5000)
        
      },
       
    })
  },
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    var that = this;
    
    var options = {
            url:"http://mp.thinkmoon.cn:39999?str=我&site=0",
            success:function(res){
              const ctx = wx.createCanvasContext('myCanvas')
              ctx.setFillStyle('black')
              var match = res.data.match(/d="(.*?)"/);
              var d = match[1];
              console.log(parse(d))
              parse(d).forEach(function (element){
                if(element[0] == "M"){
                  ctx.moveTo(element[1], element[2])
                }else if(element[0] == "Q"){
                  ctx.quadraticCurveTo(element[1], element[2], element[3], element[4])
                }
              });
              ctx.fill();
              ctx.draw(false,()=>{setTimeout(() => {that.saveTemp()},5000);});
            }
    }
    wx.request(options); 
    // wx.getStorage({
    //   key: 'display',
    //   success: function (res) {
    //     console.log("display的值为" + res.data)
    //     that.setData({
    //       display: res.data,
    //       fontSize: wx.getStorageSync('pt')
    //     })
    //   }
    // })
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
  
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
  
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
  
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
  
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {
    var str = this.data.display;
    var pages = getCurrentPages()    //获取加载的页面
    var currentPage = pages[pages.length - 1]    //获取当前页面的对象
    var url = currentPage.route
    var inUrl = url + "?display=" + encodeURI(str);
    console.log("分享的链接为"+inUrl);
    return {
      title: '您的好友给您分享了一段篆文',
      path: inUrl,
      success: function (res) {
        // 转发成功
      },
      fail: function (res) {
        // 转发失败
      }
    }
  }
}
</script>

<style lang="less">
.content{
  text-align: center;
}
canvas{
  width: 256px;
  height: 256px;
}

</style>

后记

我这个实例本来是将svg转canvas绘制出来,再转图片,下载到本地的。但是因为draw()函数是异步的所以需要等待。才可以下载成功,否则会出现一片黑的情况,总之感觉各种麻烦。再加上画布的大小难以设置。后我还是选择在服务端生成图片再转发过来。

参考文献

  1. SVG简介
  2. Touch WX开发文档
  3. 微信开发文档Canvas