FreeMind 点亮智慧的明灯(版本号: 0.5.F-$Rev: 77 $ )
-
FreeMind 点亮智慧的明灯(版本号: 0.5.F-$Rev: 77 $ )
- FreeMind 介绍
- 首先了解 MindMap
- 是将思路按照树状的结构进行线索的清理的一种整理思路的方法
- MindMap 的树状组织结构和人脑力的物质基础——神经元的结构惊人的相似 8-)
- Freemind 是 Java 开发的开源项目,提供 MindMap 的编辑和显示
- Freemind 的特色
- Write once, Run everywhere (这是 Java 的特色) 8-)
- 网址链接
- 网站
- FreeMind Wiki <http://freemind.sourceforge.net/wiki/index.php/Main_Page>
- FreeMind@SourceForge <http://sourceforge.net/projects/freemind>
- Java 下载: http://java.sun.com/
- 软件下载
- Whodo 增强版
- for Windows
- update.ossxp.com > Public > Tools > Windows > Freemind
- for Debian Linux
- 添加 Debian 源:
- deb http://YourName:YourPasswd@update.ossxp.com/public testing main
- 导入 群英汇-开源速递 软件升级签名公钥
- wget -q http://update.ossxp.com/public.key -O - | sudo apt-key add -
- 安装 ossxp-freemind
- apt-get update && apt-get install ossxp-freemind
- 注意: 可能需要身份认证,请输入在 WorldHello.net 的注册帐号和口令。
- 代码下载
- WHODO 的 FreeMind 代码补丁
- From WHODO SVN
- svn checkout http://svn.worldhello.net/svn/whodo/trunk/doc/freemind/debian/patches
- From FreeMind Wiki
- http://freemind.sourceforge.net/wiki/index.php/User:Jiangxin
- 官方 CVS 版本库
- cvs -d :pserver:anonymous@cvs.sourceforge.net:/cvsroot/freemind checkout -r FM-0-8-0 freemind
- cvs -d :pserver:anonymous@cvs.sourceforge.net:/cvsroot/freemind checkout freemind
- FreeMind 的 WHODO 修改版
- 为什么 WHODO 要使用修改过的 Freemind?
- 原因正如 Eric Raymond 所形容的那样:被搔到了痒处
- FreeMind 对中文支持不好
- 0.8.0 版本的 FreeMind 对 Unicode 的支持仍然不好(本文档在 FreeMind 0.8.0 下就出现乱码)
- FreeMind 的输出文件中,中文被编码为形如 “&#xxxx;”样子的格式
- 一些易变属性,也保存在文档中(如节点的开、合状态)
- 即使只是展开 FreeMind 思维导图的节点,而没有做修改文字或者字体、颜色等实质改动,输出文件也变化
- 想到了 VC 6.0 和 VC 7.1 的工程文件的差别。VC 7.0 的工程文件就更适合版本控制,因为一些本地相关设置保存在另外的文件中。
- 这些问题,非常不利于 FreeMind 文档的版本控制
- WHODO 所做的修改
- WorldHello扩展功能设置
- 字符编码
- 将中文字符以 UTF8 编码保存在 filename.mm 文件中,而不是 &#HEX; 格式的编码。
- 附加的辅助文件
- 将不适合版本控制的属性保存在 filename.mm 文件之外的一个辅助文件中,辅助文件名为 .filename.mmx (扩展名为.mmx,文件名前加上一个点,在Unix下是隐藏文件)。
- 可以选择哪些属性从 filename.mm 文件移动到 .filename.mmx 文件。默认三个属性 'FOLDED', 'CREATED', 'MODIFIED' 都被移动到附加的辅助文件中。
- 注:“WorldHello扩展”扩展菜单在 FreeMind 0.9.0.Beta.17+wh-13 版本之后引入
- 中文编码补丁
- 为 FreeMind 输出文件添加 XML 文件声明和编码。
- 使用 XML DOM 加载 FreeMind 的 .mm 文件。
- 修正 FreeMind 版本检查的 Bug(原设计:只读取第一行以获取 mmap 版本)
- 易变属性剥离的补丁
- 易变节点设置不再保存在 .mm 文件中,而是单独提取出来,保存在另外的一个文件中(该文件命名为 .mmx )
- 即 FreeMind 保存时,除了建立一个 .mm 文件,还保存另外一个扩展名为 .mmx 的同名文件。(.mmx 文件保存的是附加节点属性)
- FreeMind 加载 .mm 文件时,自动加载 .mmx 文件中的设置
- 综上所述,Freemind 的 WHODO 修改版,提供了 Freemind 更好的中文支持和更易于版本控制的文件格式
- TODO
- 解决加载速度慢的问题 (这个问题已经解决)
- 旧版本中存在的问题
- 1. 加载慢
- 对于比较大的 .mm 文档,合并存储附加节点属性的 .mmx 文档,速度慢,我测试了一个 200KB 的合并,最长要 4 分钟!
-
$ time xsltproc --stringparam mmx_file subject-forum.mmx freemind_join_mm_mmx.xslt subject-forum.mm > jx.mm real 4m33.148s user 4m30.093s sys 0m0.015s
- 搔到了谁的痒处?
- 如上所述,我在匆忙之中做出的修改,在合并附加节点属性中,存在效率问题
- 注:这个问题已经解决。解决方案参见:
- http://freemind.sourceforge.net/wiki/index.php/User:Jiangxin/Patch_load_mm_file_with_mmx_file#the_XSLT
- FreeMind 在网页上的显示
- 两种方法主要方法
- 推荐: Flash viewer
- 来自于 http://www.efectokiwano.net/mm 的一款依靠 JavaScript 和 Flash 的 mindmap 解决方案
- 优势
- Flash, Javascript 本身文件小,网络带宽占用小,加载迅速
- Java Applet
- FreeMind 项目本身提供的一种浏览 .mm 文件的模式
- 缺点
- 该 Java applet 文件本身很大,下载会消耗带宽和时间!
- FreeMind 嵌入到 MediaWiki
- http://meta.wikimedia.org/wiki/User:Jiangxin/Improved_Freemind_Extension
- 本地下载:addon/mediawiki/freemind.php
- FreeMind 嵌入到 phpBB
- 本地下载:addon/phpbb/mindmap.mod
- 转换为 HTML
- 这种方法不是实时的在线显示,而是通过 FreeMind 的导出功能。
- 转换为 HTML 的最主要的好处,应该是更方便的打印。
- 为什么我的浏览器显示不了网页上的 FreeMind 智图?
- Flash 插件的版本不能低于 7.0,否则可能不能正确显示;
- 看看是否由于您的浏览器禁用了 JavaScript;
- 或者浏览器的广告过滤插件把 Flash 屏蔽掉了;
- 疑难解答
- 运行 FreeMind,在显示 Splash 时挂起,不能继续运行
- 如果是在 Windows 平台使用,运行 freemind.bat。
- 如果是在 Linux 平台使用,运行 freemind.sh。
- 不能保存 FreeMind 文件
- 查看一下 JRE 版本: java -version
- 在 Windows 平台不能运行,提示找不到 freemind.jar
- 看看是不是由于目录名中包含了特殊字符(如+号),造成查找 FreeMind 目录失败。
- 从 WordHello.net 下载的软件包名称中可能包含+号,如果在Windows平台直接展开到目录,就会出现这个问题。
例如展开到: C:\Bin\FreeMind-0.9.0BETA17+wh-13\
- 解决办法:修改FreeMind目录名。
例如:将 C:\Bin\FreeMind-0.9.0BETA17+wh-13\ 修改为 C:\Bin\FreeMind\
- Freemind Hacking Howto
- 编译 FreeMind
- 动手修改 Freemind 代码之前,一定要先掌握 Freemind 的编译
- 步骤
- 安装软件
- Java Web Services Developer Pack 2.0
- http://java.sun.com/xml/downloads/jaxb.html
- JAXB
- Java Architecture for XML Binding
- JAXP
- Java API for XML Processing
- JAXR
- Java API for XML Registries (JAXR)
- JAXRPC
- JAX-RPC Version 1.1.3_01 EA (Java API for XML-based RPC)
- SAAJ
- SOAP with Attachments API for Java
- FAQ
- JaxMe
- http://ws.apache.org/jaxme/downloads.cgi
- build.xml 解析
- gen
- xmlbind
- 参数
- <param name="gen.file" value="actions"/>
- <param name="xsd.file" value="freemind_actions.xsd"/>
- 创建目录 ${gen.dir}/${gen.file},即 generated/actions
- xjc
- xjc 定义
- <taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask"
classpath="${jaxb}" />
- schema: ${xsd.dir}/freemind_actions.xsd (.//freemind_actions.xsd)
- 目标: ${gen.dir}/actions (generated/actions)
- package="freemind.controller.${gen.file}.generated.instance" />
- 将会由 ${xsd.dir}/${xsd.file} 生成 generated/actions/freemind/controller/actions/generated/instance/jaxb.properties 文件
- build
- 创建目录 ${build} (即 ../bin/classes)
- build-generated
- 调用 -buildgen
- 参数
- <param name="gen.file" value="actions"/>
- <param name="xsd.file" value="freemind_actions.xsd"/>
- javac 编译
- 源文件 ${gen.dir}/${gen.file}, (即 generated/actions)
- 目标 ${build} (即 ../bin/classes)
- 拷贝文件
- 将 ${gen.dir}/actions/freemind/controller/actions/generated 目录
中的 **/jaxb.properties, **/*.ser 文件
拷贝到 ${build}/freemind/controller/actions/generated
- 代码
- <copy todir="${build}/freemind/controller/${gen.file}/generated" >
<fileset dir="${gen.dir}/${gen.file}/freemind/controller/${gen.file}/generated" >
<include name="**/jaxb.properties" />
<include name="**/*.ser" />
</fileset>
</copy>
- javac 编译
- 源代码 srcdir="${src}"
- 除了 accessories/plugins/**, plugins/**,${gen.dir}/** 的代码
- 代码
- <javac srcdir="${src}"
destdir="${build}"
classpath="${classpath}"
debug="${debug}"
source="${java_source_version}"
target="${java_target_version}"
>
- 执行 accessories/plugins/build.xml,目标 build
- 执行 plugins/build.xml,目标 build
- plugins/build_help.xml, 目标 build
- plugins/build_svg.xml, 目标 build
- plugins/build_time..xml, 目标 build
- jar
- 创建目录 <mkdir dir="${dist.lib}" />
- 创建 ${dist.lib}/freemind.jar,即 freemind 的主要的 jar
- freemind.jar 中打包文件
- ${build} 目录下
- 除了 accessories/** 和 plugins/**
- ${src} 目录下
- **/freemind_version_updater.xslt
- dist
- 拷贝 ${src} 中的 freemind.bat,freemind.sh,license,patterns.xml 到 ${dist} 目录中
- 拷贝 ${src}/user_comment.properties 到 ${dist}/user.properties 中
- 拷贝 ${src}/windows-launcher/Freemind.exe 到 ${dist} 中
- 创建目录 ${dist}/accessories
- 将 ${src}/accessories 除了 ${src}/accessories/plugins 外拷贝其中
- 创建 ${dist.lib} 目录
- 拷贝 ${src}/lib 中 **/jaxb-xjc.jar, jarbundler.jar 拷贝其中
- 执行 accessories/plugins/build.xml,目标 dist
- 执行 plugins/build.xml,目标 dist
- plugins/build_help.xml, 目标 dist
- plugins/build_svg.xml, 目标 dist
- plugins/build_time..xml, 目标 dist
- browser
- 创建目录 <mkdir dir="${dist}/browser" />
- 创建 ${dist}/browser/freemindbrowser.jar,即浏览器 applet
- freemindbrowser.jar 包含文件
- ${build} 目录下
- freemind/view/mindmapview/*
- freemind/modes/browsemode/*
- 拷贝文件
- ${src}/freemind.properties 拷贝到 ${src}/user.properties
- 将 ${src}/html/*.*html 拷贝到 ${dist}/browser 下
- doc
- 将 ${src}/doc/freemind.mm 文件拷贝到 ${dist}/doc
- 将 ${src} 中 freemind.* 的 package 生成 javadoc 到 ${dist}/doc/javadoc 目录
- post
- 创建 ${post}/freemind-bin.tar.gz 和 freemind-bin.zip
- 包含 ${dist} 中除了 browser/,doc/javadoc/,plugins/** 外的文件
- 创建 ${post}/freemind-src.tar.gz 和 freemind-src.zip
- 包含 ${src_base_for_post}(../) 中 freemind/**,.classpath,.project 文件
- 创建 ${post}/freemind-browser.tar.gz 和 freemind-browser.zip
- 执行 plugins/build.xml,目标 post
- plugins/build_help.xml, 目标 post
- plugins/build_svg.xml, 目标 post
- plugins/build_time..xml, 目标 post
- run
- 执行 ${FM.jar} 的 freemind.main.FreeMind
- clean
- 删除目录 build, dist, dist_macos_base, gen.dir, post,
删除文件 src/**/*~
- build.xml 异常处理
- 报错
- E:\Home\WORK\eclipse\freemind\build.xml:23: taskdef class com.loomcom.ant.tasks.jarbundler.JarBundler cannot be found
- 在 Preferences -> Ant -> Runtime -> Classpath 中设置。
- Add jars -> freemind/lib/jarbundler-1.4.jar
- 报错
- E:\Home\WORK\eclipse\freemind\build.xml:35: taskdef class com.sun.tools.xjc.XJCTask cannot be found
- 在 Preferences -> Ant -> Runtime -> Classpath 中设置。
- Add jars -> freemind/lib/ant/lib/jaxb-xjc.jar
- 报错
- E:\Home\WORK\eclipse\freemind\build.xml:75: The following error occurred while executing this line:
java.lang.NoClassDefFoundError: org/apache/xerces/xni/XNIException
- 使用 jwsp2.0 的 lib 取代 freemind/lib 下的 jar 文件
- 报错
- [javac] Compiling 65 source files to E:\Home\WORK\eclipse\bin\classes
[javac] E:\Home\WORK\eclipse\freemind\generated\actions\freemind\controller\actions\generated\instance\AddArrowLinkXmlAction.java:45: -source 1.3 中不支持注释
[javac] (请尝试使用 -source 1.5 以启用注释)
[javac] @XmlAccessorType(AccessType.FIELD)
[javac] ^
- 如何 debug classpath 的值? <fail message="${classpath}"/>
- 解决方法:问题出在 java_target_version 的值,修改为 1.5
- 报错
- [javac] E:\Home\WORK\eclipse\freemind\freemind\preferences\layout\OptionPanel.java:67: 找不到符号
[javac] 符号: 类 OptionPanelWindowConfigurationStorageType
[javac] 位置: 软件包 freemind.controller.actions.generated.instance
[javac] import freemind.controller.actions.generated.instance.OptionPanelWindowConfigurationStorageType;
[javac] ^
- classpath 为 :
lib/ant/lib/jaxb-xjc.jar:lib/ant/lib/jaxb-api.jar:lib/ant/lib/jaxb-impl.jar:lib/ant/lib/jaxb-libs.jar:lib/ant/lib/namespace.jar:lib/ant/lib/relaxngDatatype.jar:lib/ant/lib/xsdlib.jar:lib/ant/lib/jax-qname.jar:lib/ant/lib/sax.jar:lib/ant/lib/dom.jar:lib/commons-lang-2.0.jar:lib/forms-1.0.5.jar
- 创建 Eclipse 工程
- 目录结构
- .classpath
.project
freemind/build.xml
freemind/accessories
freemind/freemind
freemind/plugins
...
- 如何提交更改?
- Wiki
- 在 Wiki 上建立自述页面 User:YOUR_NAME,并将自己的更改作为自述页面的自页面;
- 格式参照: http://freemind.sourceforge.net/wiki/index.php/User:Jiangxin
- 提交到 WHODO Wiki 上,最好在提交到 http://freemind.sourceforge.net/wiki/ 上一份,因为那里是 FreeMind 大本营,有足够多的眼睛帮你找 Bug
- 关于 Freemind.exe
- 实际上是 lib/freemind.jar 的一个 Wrapper
- 实际执行的命令行
- -Xmx256M
- 内存最大占用 256MB。因此如果编辑大文件,存在内存问题,可以从这里入手修改。
- <PATH>\\lib\\freemind.jar
- 如果将来编辑大文件(100MB)存在内存问题,可能需要修改 Freemind.exe 调用 JVM 的参数!
- 处理流程
- 文件打开
- modes/ControllerAdapter.java
- line 660: public void open()
- modes/mindmapmode/MindMapMapModel.java
- line 508: public void load(File file)
- line 544: loadTree(File file)
- 检查文件头 <map version=...,因此如果最前面加上 <?xml ... 会造成版本判断错误!
- 版本正确
- reader = getActualReader(file);
- 版本太旧
- reader = getUpdateReader(file);
- 用 xslt 文件 freemind/modes/mindmapmode/freemind_version_updater.xslt 进行格式转换
- mapElement.parseFromReader(reader);
- 文件保存
- modes/ControllerAdapter.java
- line 699: public boolean saveAs()
- File f = chooser.getSelectedFile();
- 保存文件到 f,并强制扩展名为 .mm
- String ext = Tools.getExtension(f.getName());
if(!ext.equals("mm")) {
f = new File(f.getParent(),f.getName()+".mm"); }
- public boolean save(File file)
- modes/mindmapmode/MindMapMapModel.java
- line 411: boolean saveInternal(File file, boolean isInternal)
- 保存文件
- BufferedWriter fileout = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(file), FreeMind.DEFAULT_CHARSET ) );
- 增加保存 .mmx 文件,用于保存 fold 等属性
- line 445: getXml(fileout)
- modes/mindmapmode/MindMapNodeModel.java
- modes/NodeAdapter.java
- line 829: public XMLElement save(Writer writer, MindMapLinkRegistry registry)
- 不保存 FOLDED 属性
- if (0 == save_attr)
{
if (!isRoot() && !isLeaf()) {
node.setAttribute("FOLDED","true");
}
}
- 写 node
- child.save(writer, registry);
node.writeClosingTag(writer);
- main/XMLElement.java
- line 2193: public void write(Writer writer, boolean withClosingTag)
- 设置 only_attlist
- 只保存 only_attlist 的属性。不再检查 hide_attlist
- 设置 em_attlist
- 设置为强调的 em_attlist,另起一行显示。显示完毕如果还有属性值,换行并缩进
- Hacking
- 版本号
- main/FreeMind.java
- public static final String version = "0.8.0(worldhello.net)";
- controller/Controller.java
- 该文件读取 FreeMind.version,但是由于没有设置依赖关系,造成 About 对话框没有更新。需要 rebuild.
- build.xml
- <property name="ver" value="0_8_0" />
- 中文内容的存储。utf-8 格式的 xml 文件。
- 文件 modes/ControllerAdapter.java
- public boolean save(File file)
- modes/mindmapmode/MindMapMapModel.java
- private boolean saveInternal(File file, boolean isInternal)
- 保存文件接口, isInternal 为 true,则是保存备份
- line 418 增加 charset 设置
-
BufferedWriter fileout = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(file), "UTF-8" ) );
- line 444: public void getXml(Writer fileout)
- 增加一行
- fileout.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
- modes/public XMLElement save(Writer writer, MindMapLinkRegistry registry)
- NODE 格式
- <node CREATED="1143916340296" FOLDED="true" ID="Freemind_Link_747410934" MODIFIED="1143916344265" POSITION="right" TEXT="结束测试">
- main/XMLElement.java
- public void write(Writer writer, boolean withClosingTag)
- this.writeEncoded(writer, this.contents);
- protected void writeEncoded(Writer writer, String str)
- int unicode = (int) ch;
if ((unicode < 32) /*|| (unicode > 126)*/ ) {
writer.write('&'); writer.write('#');
writer.write('x');
writer.write(Integer.toString(unicode, 16));
writer.write(';');
} else {
writer.write(ch);
}
- 写入:String newStr = new String(oldStr.getByte(“GB2312”), “ISO8859_1”);
读出:String newStr = new String(oldStr.getByte(“ISO8859_1”),”GB2312”);
- 示例
- import java.io.*;
public class inputtest {
public static void main(String[] args) {
String outfile = null;
try { convert(args[0], args[1], "GB2312", "UTF8"); } // or "BIG5"
catch (Exception e) {
System.out.print(e.getMessage());
System.exit(1);
}
}
public static void convert(String infile, String outfile, String from, String to)
throws IOException, UnsupportedEncodingException
{
// set up byte streams
InputStream in;
if (infile != null) in = new FileInputStream(infile);
else in = System.in;
OutputStream out;
if (outfile != null) out = new FileOutputStream(outfile);
else out = System.out;
// Use default encoding if no encoding is specified.
if (from == null) from = System.getProperty("file.encoding");
if (to == null) to = System.getProperty("file.encoding");
// Set up character stream
Reader r = new BufferedReader(new InputStreamReader(in, from));
Writer w = new BufferedWriter(new OutputStreamWriter(out, to));
// Copy characters from input to output. The InputStreamReader
// converts from the input encoding to Unicode,, and the OutputStreamWriter
// converts from Unicode to the output encoding. Characters that cannot be
// represented in the output encoding are output as '?'
char[] buffer = new char[4096];
int len;
while((len = r.read(buffer)) != -1)
w.write(buffer, 0, len);
r.close();
w.flush();
w.close();
}
}
- 节点被选择后,输入 ascii 字符,直接替换,但是输入中文则不起作用!
- 其他
- 用户自定义
- 目录: C:\Documents and Settings\<UserName>\.freemind
- user.properties
- C:\Documents and Settings\<UserName>\.freemind\user.properties
- 自动保存
- 自动保存的目录
- user.properties 中的默认配置是 path_to_automatic_saves=freemind_home
- 版本控制
- 版本
- 0.4
- 补充 Debian Linux 下安装 WorldHello 版本的 FreeMind。(2007/06/19)
- 增加 FreeMind Flash player 限制条件。(2007/06/19)
- 0.3
- 修改 whodo svn 地址。 (2007/06/04)
- 添加 freemind 下载地址。 (2007/06/04)
- 0.2
- 补充 FreeMind 在网页上的显示。 (2006/05/03)
//mm2html.xsl FreemindVersion:0.9.0_Beta_8