Aardio 第一天:使用虚表和适配器+试融合Java

初识 Aardio

挺洋气的名字,乍看神似arduino的重新排序。不过这是一种国人开发的脚本编程语言,自带基于win32 api的界面框架,可以和其他编程语言沟通,比如调用java或者python代码。

官网下载下来6.5MB的压缩包,解压后,打开集成开发环境,它还会远程下载组件,比如粘贴了vlist的示例代码后,点击硕大的运行按钮,会要求安装vlist组件,确认即可。

也可以从网上下载 .aardio 文件,自己放到lib文件夹中,作为开源库使用。这对于开源很友好,也可以魔改、借此入门,aardio上层都是开源的。

aardio 项目编译之迅速,可以让你暂时忍受其编辑器界面与错误提示界面之简单……

aardio 制作的小工具很赞,可谓精悍,比如Gif123录屏软件,如果你有制作gif动图教程的打算,不妨试试。Gif123可以在多显示器环境下工作,跨越扩展显示屏进行录屏。用SPY++探测了一下,发现界面不是directui,拖动条等控件都有自己的窗口句柄。那么,aardio 显示无限列表的性能如何呢?


使用虚表和适配器

aardio 的 vlist 有 createTableAdapter 方法,里面封装了 getCount,getItem等类似于安卓listview适配器的接口,令人欣慰。但是网上的vlist demo无法正常运行:
请添加图片描述
而且这个命令行窗口也无法复制错误信息,令人烦躁。

好在aardio还有其他更好的虚表示例程序,如: aardio - 【库】虚表增强版。增强了vlist,是一个新的控件了,需要从他博客下载 vlistEx.rar、_.rar,解压出 .aardio 文件放入lib/godking文件夹中。这样就可以运行他博客中的代码了。

但是示例程序中的虚表,与我想象中的不同,仍像是普通的列表,需要提前加装一行行的数据。其实参考库文件中的setTable方法,可以自己写适配器的!代码如下:

import win.ui;

import godking.vlistEx;

import godking
/*DSG{{*/
mainForm = win.form(text="vlistEx - table adapter";right=849;bottom=578)
mainForm.add(
vlist={cls="vlistEx";left=10;top=10;right=840;bottom=570;db=1;dl=1;dr=1;dt=1;edge=1;transparent=1;z=1}
)
/*}}*/

var t = { fields={"序号","姓名","年龄","地址","身份证"} }
 
math.randomize()
for(i=1;100;1){
    var tt={}
	tt["序号"]="[@rowindex]"  // 行序号标记是不允许编辑修改的
	tt["姓名"]=math.random(1000,9999)+"姓名"
	tt["年龄"]=math.random(10,99)
	tt["地址"]=math.random(1000,9999)+"地址"
	tt["身份证"]=math.random(1000,9999)+"身份证"
	..table.push(t,tt)
}

// 直接把 setTable  方法复制到demo中。将this.改成lv.
	setTable = function(lv, dataSource,fields,colwidth,colstyle,toArray=false,toUtf8=false){
		lv.setRedraw(false);
		..table.clear(lv.dataAdapter._dataSource);
		dataSource = ..table.clone(dataSource);
		// 初始化标题栏
		if(!fields){ //如果没有指定标题栏,则自动生成标题栏。
			if (dataSource[["fields"]]) fields=dataSource[["fields"]] //如果指定了fields字段
			else fields = ..table.keys(dataSource[[1]]);// 如果没指定fields字段,且数据为字典型,则字典关键字为字段。
		} 
		if (type(fields)="string") fields=..string.split(fields,",;");//将字符串转换为“表”
		if (type(fields)!="table" or !#fields) fields=null; //取消非法字段指定
		// 填充数据
		if (#fields){ //如果是字典,有了字段
			// 先按字段刷新标题栏。
			var curfields = lv.getColumnText();
			if (#fields!=#curfields or ..table.tostring(curfields)!=..table.tostring(fields)) {
				lv.setColumns(fields,colwidth,colstyle);
			}
			// 判断是否为字典
			if #..table.keys(dataSource[1]){
				if !dataSource["fields"] dataSource.fields=fields;
				// 字典转数组
				if toArray dataSource=lv.dictToArray(dataSource);
			} else {
				// 如果既不是字典,也不是空,则确定为数组。则取消fields字段。否则保持原dataSource的fields设置。
				if #dataSource[1] dataSource.fields = null;
			}
    	}else{ //如果是数组,则按照数组1的成员数,生成列数。
    		if type(dataSource[[1]])!=type.table {
    			lv.setColumns();
    			return lv.setRedraw(true); 
    		}
			if (lv.columnCount!=#(dataSource[[1]])){
				lv.setColumns(..string.split(..string.repeat(#(dataSource[[1]]),' ')),colwidth,colstyle);
			}
		}
		if toUtf8 {
			if dataSource.fields {
				for(i=1;#dataSource;1){
					for(k,v in dataSource[i]){
						if type(v)=type.string dataSource[i][k] = ..string.fromto(v,0,65001);
					}
				}
			} else {
				for(i=1;#dataSource;1){
					for(n=1;#dataSource[i];1){
						if type(dataSource[i][n])=type.string dataSource[i][n] = ..string.fromto(dataSource[i][n],0,65001);
					}
				}
			}
		}
		tableAdapter(lv/*listview*/,dataSource).update();
		lv.setRedraw(true);
	}
	
//自己写适配器!爽歪歪
class tableAdapter {
	ctor (listview,dataSource) {
		this._listview = listview;
		this._dataSource = dataSource;
		if( listview.dataAdapter ) listview.dataAdapter.__close();
		listview.dataAdapter = this; 
		this.update = function(){
			::SendMessageInt(listview.hwnd, 0x102F/*_LVM_SETITEMCOUNT*/,this.count(), 0x2/*_LVSICF_NOSCROLL*/);
		}
		this.__close = function(){ this._listview.dataAdapter = null; };
		this._columns = dataSource.fields;
	};
	count = function () {
		return 100000000; // 一个小目标的数据量,惊不惊喜,
	};
	getItem = function (row, col) {
		return row +','+ col; // 意不意外?
	}
}

 
//mainForm.vlist.setTable(t,,{80,100,100,0,200},0x2/*_LVCFMT_CENTER*/)
//tableAdapter(mainForm.vlist/*listview*/).update();
//tableAdapter(mainForm.vlist/*listview*/, t).update();
setTable(mainForm.vlist, t,,{80,100,100,0,200},0x2/*_LVCFMT_CENTER*/)

mainForm.vlist.setCheckBox(true)
mainForm.vlist.textColor = 0xFF0000;
mainForm.vlist.bkColor = 0xEEEEEE;
mainForm.vlist.setHeaderHeight(50);
mainForm.vlist.lineColorH = 0x008800;
mainForm.vlist.lineColorV = 0xBB9999;
mainForm.vlist.fillParent(4)
 
mainForm.vlist.onEditBegin = true; 
 
mainForm.vlist.onEditEnd = function(row/*行*/,col/*列*/,text/*内容*/){
	/*单元格编辑完毕,是否允许单元格内容改变。返回false不允许,返回true允许,返回文本则改为新文本*/
	/*不定义此事件,则默认允许改变。注意:只有onEditBegin事件返回true,此事件才会触发。*/
 
	// 确保第三列输入数值!
	if col==3 {
		var r = ..tostring((..tonumber(text)):0);
		if r!=text	{
			..win.msgbox(f(`"{text}" 将转为:"{r}"`));
			return r; 
		}
	}
	return true; 
}
 
mainForm.vlist.onSortColumn = function(col,desc){
	/*点击列标题进行排序。col:列号,从1开始。desc:是否倒序。返回true重置标题栏排序图标*/
	..table.sortEx(owner.getTable(),col,desc,/*数据转换*/)
	owner.update()
	return true;
}
 
mainForm.vlist.onRClick = function(row/*行*/,col/*列*/){
	/*鼠标右键点击项目事件*/
	..win.msgbox(f("您鼠标右键点击了:{row}行,{col}列"))
}
 
mainForm.show();
win.loopMessage();

可以看到适配器接口class tableAdapter很简单,但是setTable那一坨东西是在干啥,暂时还没搞明白……

直接运行会出错,因为vListEx.aardio第201行访问了原_dataSource列表数据,注释掉即可。

//if this.dataAdapter._dataSource[item.iItem].checked { …

运行效果:

请添加图片描述

aardio 的虚表似乎还是基于win32原生的列表控件,但是能够实现虚表,令人眼前一亮。aardio 语法像js或者java,比autohotkey脚本的语法好写易懂。

虽然有着悠久的历史,但是对我而言,这是一门新技术、新思路。祝愿这门自带界面框架的脚本语言,引擎越来越快、开源的生态越来越好!

调用 Java 包,由Java层提供列表数据

  1. IDEA新建纯Java项目,写一些类和方法。然后管理项目结构(文件夹+三个小方块的那个图标),在Artifact区域新建Artifact,选择导出编译结果为jar,最后build Artifact,可以在磁盘上找到jar。将生成的mdict-java-core.jar复制到项目的Java文件夹中

  2. 本例测试的是词典库Mdict-Java。脚本代码如下:

import java; 
var jvm = java(); 
Mdict = jvm.import("com.knziha.plod.dictionary.mdict");
var md = Mdict("D:/assets/mdicts/OED2.mdx");

…… 修改适配器代码 ……

getItem = function (row, col) {
	return md.getEntryAt(row); // 获取词条名称
}

效果图:
请添加图片描述
不知道怎么样才能正确导入绝对路径中的class文件,试了好久没成功,最后直接把jar复制到项目java文件夹了,不去管。

列表项目数量超过一亿显示空白,不知是哪里的问题。

感觉性能还可以,快速拖拽滚动条的时候有轻微卡顿,可忽略。资源占用有所增加,但也不是很大。导出exe失败:不能发布,说生成失败,添加资源失败,然而没有资源,纯代码项目而已。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值