mxGraph绘制机构图
简单介绍一下使用的依赖:
JGraphX is a Java Swing diagramming (graph visualisation) library licensed under the BSD license (see https://github.com/jgraph/jgraphx)
Unfortunately JGraphX is not available at Maven Central, and this project solves that.
Value added by jgraph-publish
:
- jar, javadoc, and sources are published to Maven Central
- Gradle build (the code imports in IDEA automatically)
- OSGI manifest entries
- Automatic-Module-Name
<dependency>
<groupId>com.github.vlsi.mxgraph</groupId>
<artifactId>jgraphx</artifactId>
<version>4.2.2</version>
</dependency>
Javadoc: Manual: https://jgraph.github.io/mxgraph/docs/manual_javavis.html Examples: https://github.com/jgraph/jgraphx/tree/master/examples/com/mxgraph/examples/swing
BSD
JGraphX: JGraph Ltd
Packaging: Vladimir Sitnikov sitnikov.vladimir@gmail.com
Copyright (c) 2001-2014, Vladimir Sitnikov All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the JGraph nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JGRAPH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
效果如下:
代码区(作废):
/** * 画图 * @param boxW * @param boxH * @param width * @param height * @return */ private BufferedImage structure(Integer boxW,Integer boxH,Integer width,Integer height,GroupNode node) { // 创建一个mxGraph实例 mxGraph graph = new mxGraph(); // 设置默认样式 Object parent = graph.getDefaultParent(); //设置四个定位大小的点 graph.insertVertex(parent, null, "", 0, 0, 1, 1); graph.insertVertex(parent, null, "", 0, height, 1, 1); graph.insertVertex(parent, null, "", width, 0, 1, 1); graph.insertVertex(parent, null, "", width, height, 1, 1); /** * n * x1 = width/2-cWidth * 添加根节点 abs(x(n+1)-x1)=abs(x(n+2)-x1) ..... = cWidth * if((n-1)>2) x((n-1)/2+1) = x1 */ //设置边框为无填充无边框 String box = "fillColor=none;strokeColor=white;"; //设置连线样式为居中直角折线 String line = mxConstants.STYLE_EDGE + "=" + mxConstants.EDGESTYLE_ELBOW + ";"+mxConstants.STYLE_ENDARROW+"="+mxConstants.NONE+";"; Queue<GroupNode> nodes = new LinkedList<>(); nodes.offer(node); Map<String,List<Object>> map = new HashMap<>(); Integer y = 0; int size = 0; while (!nodes.isEmpty()) { y++; size = Math.max(size,nodes.size()); for(int i=0;i<size;i++) { if(nodes.isEmpty()) break; GroupNode poll = nodes.poll(); Integer mx = (width/size)*i+width/size/2-boxW/2; Integer my = y*boxW; //创建框 Object o = graph.insertVertex(parent, null, poll.name, mx, my, boxW, boxH, box); map.put(poll.id,Arrays.asList(o,mx,my)); //创建线 if(ObjectUtil.isNotEmpty(poll.parent)) { List<Object> list = map.get(poll.parentId); //父框下中心点 Object p = graph.insertVertex(parent, null, null, (Integer)list.get(1)+boxW/2, (Integer)list.get(2)+boxW/2,0,0); //子框上中心点 Object c = graph.insertVertex(parent, null,null, mx+boxW/2, my-boxW/2, 0,0); graph.insertEdge(parent, null, "", list.get(0), p, line); graph.insertEdge(parent, null, "", p, c, line); graph.insertEdge(parent, null, "", c, o, line); } for (GroupNode child : poll.childs) { nodes.offer(child); } } } // 渲染图形到BufferedImage return mxCellRenderer.createBufferedImage(graph, null, 1, Color.WHITE, false, null); }
代码区(新):
/** * 画图 * @param boxW * @param boxH * @param width * @param height * @return */ private BufferedImage structure(Integer boxW,Integer boxH,Integer width,Integer height,GroupNode node) { // 创建一个mxGraph实例 mxGraph graph = new mxGraph(); // 设置默认样式 Object parent = graph.getDefaultParent(); //设置四个定位大小的点 graph.insertVertex(parent, null, "", 0, 0, 1, 1); graph.insertVertex(parent, null, "", 0, height, 1, 1); graph.insertVertex(parent, null, "", width, 0, 1, 1); graph.insertVertex(parent, null, "", width, height, 1, 1); /** * n * x1 = width/2-cWidth * 添加根节点 abs(x(n+1)-x1)=abs(x(n+2)-x1) ..... = cWidth * if((n-1)>2) x((n-1)/2+1) = x1 */ //设置边框为无填充无边框 String box = "fillColor=none;strokeColor=white;"; //设置连线样式为居中直角折线 String line = mxConstants.STYLE_EDGE + "=" + mxConstants.EDGESTYLE_ELBOW + ";"+mxConstants.STYLE_ENDARROW+"="+mxConstants.NONE+";"; Queue<GroupNode> nodes = new LinkedList<>(); Queue<GroupNode> nexts = new LinkedList<>(); nodes.offer(node); Map<String,List<Object>> map = new HashMap<>(); Integer y = 0; int size = 0; while (!nodes.isEmpty()) { y++; size = Math.max(size,nodes.size()); for(int i=0;i<size;i++) { if(nodes.isEmpty()) break; GroupNode poll = nodes.poll(); Integer mx = (width/size)*i+width/size/2-boxW/2; Integer my = y*boxW; //创建框 Object o = graph.insertVertex(parent, null, poll.name, mx, my, boxW, boxH, box); map.put(poll.id,Arrays.asList(o,mx,my)); //创建线 if(ObjectUtil.isNotEmpty(poll.parent)) { List<Object> list = map.get(poll.parentId); //父框下中心点 Object p = graph.insertVertex(parent, null, null, (Integer)list.get(1)+boxW/2, (Integer)list.get(2)+boxW/2,0,0); //子框上中心点 Object c = graph.insertVertex(parent, null,null, mx+boxW/2, my-boxW/2, 0,0); graph.insertEdge(parent, null, "", list.get(0), p, line); graph.insertEdge(parent, null, "", p, c, line); graph.insertEdge(parent, null, "", c, o, line); } for (GroupNode child : poll.childs) { nexts.offer(child); } } nodes.addAll(nexts); } // 渲染图形到BufferedImage return mxCellRenderer.createBufferedImage(graph, null, 1, Color.WHITE, false, null); }
GroupNode数据部分:
private class GroupNode { String id; String parentId; String name; GroupNode parent; List<GroupNode> childs; private GroupNode(String id,String parentId,String name) { this.id = id; this.parentId = parentId; this.name = name; this.parent = null; this.childs = new ArrayList<>(); } //写个简单的列表转树 O(1) public GroupNode(List<GroupNode> groupList) { if(ObjectUtils.isNotEmpty(groupList)) { for (GroupNode node : groupList) { node.childs = groupList.stream().filter(p -> node.id.equals(p.parentId)).map(p->{p.parent=node;return p;}).collect(Collectors.toList()); } GroupNode node = groupList.stream().filter(p -> ObjectUtil.isEmpty(p.parent)).findFirst().get(); this.id = node.id; this.parentId = node.parentId; this.name = node.name; this.parent = node.parent; this.childs = node.childs; } } /** * 节点最大深度 * @return */ public Integer depth() { int maxChildDepth = 0; for (GroupNode child : this.childs) { maxChildDepth = Math.max(maxChildDepth, child.depth()); } return maxChildDepth + 1; } /** * 阶段最大宽度 * @return */ public Integer breadth() { Queue<GroupNode> queue = new LinkedList<>(); queue.offer(this); int maxCount = 0; int currentLevelSize; while (!queue.isEmpty()) { currentLevelSize = queue.size(); if (currentLevelSize > maxCount) { maxCount = currentLevelSize; } for (int i = 0; i < currentLevelSize; i++) { GroupNode node = queue.poll(); for (GroupNode child : node.childs) { queue.offer(child); } } } return maxCount; } }
优化后的代码,width=min(boxW)*树的宽度,第一次的boxW传参请用width:
private BufferedImage structure(Integer boxW,Integer boxH,Integer width,Integer height,GroupNode node) { // 创建一个mxGraph实例 mxGraph graph = new mxGraph(); // 设置默认样式 Object parent = graph.getDefaultParent(); //设置四个定位大小的点 graph.insertVertex(parent, null, "", 0, 0, 1, 1); graph.insertVertex(parent, null, "", 0, height, 1, 1); graph.insertVertex(parent, null, "", width, 0, 1, 1); graph.insertVertex(parent, null, "", width, height, 1, 1); /** * n * x1 = width/2-cWidth * 添加根节点 abs(x(n+1)-x1)=abs(x(n+2)-x1) ..... = cWidth * if((n-1)>2) x((n-1)/2+1) = x1 */ //设置边框为无填充无边框 String box = "fillColor=none;strokeColor=white;"; // String box = ""; //设置连线样式为居中直角折线 String line = mxConstants.STYLE_EDGE + "=" + mxConstants.EDGESTYLE_ELBOW + ";"+mxConstants.STYLE_ENDARROW+"="+mxConstants.NONE+";"; Queue<GroupNode> nodes = new LinkedList<>(); nodes.offer(node); Map<String,List<Object>> map = new HashMap<>(); Integer y = 0; int size = 0; while (!nodes.isEmpty()) { y++; size = Math.max(size,nodes.size()); Queue<GroupNode> nexts = new LinkedList<>(); Integer my = y*boxH*2; Integer mx = 0; for(int i=0;i<size;i++) { if(nodes.isEmpty()) break; GroupNode poll = nodes.poll(); if(ObjectUtils.isNotEmpty(poll.parentId)) { List<Object> list = map.get(poll.parentId); if(ObjectUtils.isNotEmpty(list)) { int w = (Integer)list.get(4); int s = ((GroupNode)list.get(1)).childs.size(); boxW = w/s; mx = (Integer) list.get(2) + boxW*poll.index; if(((GroupNode)list.get(1)).childs.size() == 1 ) mx = (Integer) list.get(2); if(((GroupNode)list.get(1)).childs.size() == 1 ) boxW = (Integer) list.get(4); } } //创建框 Object o = graph.insertVertex(parent, null, poll.name, mx, my, boxW, boxH, box); map.put(poll.id,Arrays.asList(o,poll,mx,my,boxW,boxH,box)); //创建线 if(ObjectUtil.isNotEmpty(poll.parent)) { List<Object> list = map.get(poll.parentId); if(ObjectUtils.isNotEmpty(list)) { //父框下中心点 Object p = graph.insertVertex(parent, null, null, (Integer)list.get(2)+(Integer)list.get(4)/2, my-boxH/2,0.1,0.1); //子框上中心点 int piex=((GroupNode)list.get(1)).childs.size()<=1?0:1; Object c = graph.insertVertex(parent, null,null, mx+boxW/2+piex, my-boxH/2, 0.1,0.1); graph.insertEdge(parent, null, "", list.get(0), p, line); graph.insertEdge(parent, null, "", p, c, line); graph.insertEdge(parent, null, "", c, o, line); } } int index = 0; for (GroupNode child : poll.childs) { child.index = index; nexts.offer(child); index++; } } nodes.addAll(nexts); } // 渲染图形到BufferedImage return mxCellRenderer.createBufferedImage(graph, null, 1, Color.WHITE, false, null); }
欢迎扫描头像加我好友【瞎聊】或者一起【象棋】大战!
以下是一些凑字数的散文:
1、朱自清《荷塘月色》片段
路上只我一个人,背着手踱着。这一片天地好像是我的;我也像超出了平常旳自己,到了另一世界里。我爱热闹,也爱冷静;爱群居,也爱独处。像今晚上,一个人在这苍茫旳月下,什么都可以想,什么都可以不想,便觉是个自由的人。白天里一定要做的事,一定要说的话,现在都可不理。这是独处的妙处,我且受用这无边的荷香月色好了。
曲曲折折的荷塘上面,弥望旳是田田的叶子。叶子出水很高,像亭亭旳舞女旳裙。层层的叶子中间,零星地点缀着些白花,有袅娜(niǎo,nuó)地开着旳,有羞涩地打着朵儿旳;正如一粒粒的明珠,又如碧天里的星星,又如刚出浴的美人。微风过处,送来缕缕清香,仿佛远处高楼上渺茫的歌声似的。这时候叶子与花也有一丝的颤动,像闪电般,霎时传过荷塘的那边去了。叶子本是肩并肩密密地挨着,这便宛然有了一道凝碧的波痕。叶子底下是脉脉(mò)的流水,遮住了,不能见一些颜色;而叶子却更见风致了。
月光如流水一般,静静地泻在这一片叶子和花上。薄薄的青雾浮起在荷塘里。叶子和花仿佛在牛乳中洗过一样;又像笼着轻纱的梦。虽然是满月,天上却有一层淡淡的云,所以不能朗照;但我以为这恰是到了好处——酣眠固不可少,小睡也别有风味的。月光是隔了树照过来的,高处丛生的灌木,落下参差的斑驳的黑影,峭楞楞如鬼一般;弯弯的杨柳的稀疏的倩影,却又像是画在荷叶上。塘中的月色并不均匀;但光与影有着和谐的旋律,如梵婀(ē)玲(英语violin小提琴的译音)上奏着的名曲。
荷塘的四面,远远近近,高高低低都是树,而杨柳最多。这些树将一片荷塘重重围住;只在小路一旁,漏着几段空隙,像是特为月光留下的。树色一例是阴阴的,乍看像一团烟雾;但杨柳的丰姿,便在烟雾里也辨得出。树梢上隐隐约约的是一带远山,只有些大意罢了。树缝里也漏着一两点路灯光,没精打采的,是渴睡人的眼。这时候最热闹的,要数树上的蝉声与水里的蛙声;但热闹是它们的,我什么也没有。
2、鲁迅《从百草园到三味书屋》片段
不必说碧绿的菜畦,光滑的石井栏,高大的皂荚树,紫红的桑椹;也不必说鸣蝉在树叶里长吟,肥胖的黄蜂伏在菜花上,轻捷的叫天子(云雀)忽然从草间直窜向云霄里去了。单是周围的短短的泥墙根一带,就有无限趣味。油蛉在这里低唱,蟋蟀们在这里弹琴。翻开断砖来,有时会遇见蜈蚣;还有斑蝥,倘若用手指按住它的脊梁,便会拍的一声,从后窍喷出一阵烟雾。何首乌藤和木莲藤缠络着,木莲有莲房一般的果实,何首乌有拥肿的根。有人说,何首乌根是有象人形的,吃了便可以成仙,我于是常常拔它起来,牵连不断地拔起来,也曾因此弄坏了泥墙,却从来没有见过有一块根象人样。如果不怕刺,还可以摘到覆盆子,象小珊瑚珠攒成的小球,又酸又甜,色味都比桑椹要好得远。
3、陈从周《说园》片段
园有静观、动观之分,这一点我们在造园之先,首要考虑。何谓静观,就是园中予游者多驻足的观赏点;动观就是要有较长的游览线。二者说来,小园应以静观为主,动观为辅,庭院专主静观。大园则以动观为主,静观为辅。前者如苏州网师园,后者则苏州拙政园差可似之。人们进入网师园宜坐宜留之建筑多,绕池一周,有槛前细数游鱼,有亭中待月迎风,而轩外花影移墙,峰峦当窗,宛然如画,静中生趣。至于拙政园径缘池转,廊引人随,与“日午画船桥下过,衣香人影太匆匆”的瘦西湖相仿佛,妙在移步换影,这是动观。立意在先,文循意出。动静之分,有关园林性质与园林面积大小。象上海正在建造的盆景园,则宜以静观为主,即为一例。
中国园林是由建筑、山水、花木等组合而成的一个综合艺术品,富有诗情画意。叠山理水要造成“虽由人作,宛自天开”的境界。山与水的关系究竟如何呢?简言之,模山范水,用局部之景而非缩小(网师园水池仿虎丘白莲池,极妙),处理原则悉符画本。山贵有脉,水贵有源,脉源贯通,全园生动。我曾经用“水随山转,山因水活”与“溪水因山成曲折,山蹊随地作低平”来说明山水之间的关系,也就是从真山真水中所得到的启示。明末清初叠山家张南垣主张用平冈小陂、陵阜陂阪,也就是要使园林山水接近自然。如果我们能初步理解这个道理,就不至于离自然太远,多少能呈现水石交融的美妙境界。
4、梁实秋《雅舍》片段
“雅舍”最宜月夜——地势较高,得月较先。看山头吐月,红盘乍涌,一霎间,清光四射,天空皎洁,四野无声,微闻犬吠,坐客无不悄然!舍前有两株梨树,等到月升中天,清光从树间筛洒而下,地下阴影斑斓,此时尤为幽绝。直到兴阑人散,归房就寝,月光仍然逼进窗来,助我凄凉。细雨蒙蒙之际,“雅舍”亦复有趣。推窗展望,俨然米氏章法,若云若雾,一片弥漫。但若大雨滂沱,我就又惶悚不安了,屋顶浓印到处都有,起初如碗大,俄而扩大如盆,继则滴水乃不绝,终乃屋顶灰泥突然崩裂,如奇葩初绽,砉然一声而泥水下注,此刻满室狼藉,抢救无及。此种经验,已数见不鲜。
5、冰心《图画》
信步走下山门去,何曾想寻幽访胜?
转过山坳来,一片青草地,参天的树影无际。树后弯弯的石桥,桥后两个俯蹲在残照里的狮子。回过头来,只一道的断瓦颓垣,剥落的红门,却深深掩闭。原来是故家陵阙!何用来感慨兴亡,且印下一幅图画。
半山里,凭高下视,千百的燕子,绕着殿儿飞。城垛般的围墙,白石的甬道,黄绿琉璃瓦的门楼,玲珑剔透。楼前是山上的晚霞鲜红,楼后是天边的平原村树,深蓝浓紫。暮霭里,融合在一起。难道是玉宇琼楼?难道是瑶宫贝阙?何用来搜索诗肠,且印下一幅图画。
低头走着,—首诗的断句,忽然浮上脑海来。“四月江南无矮树,人家都在绿阴中。”何用苦忆是谁的著作,何用苦忆这诗的全文。只此已描画尽了山下的人家!
6、徐志摩《我所知道的康桥》片段
康桥的灵性全在一条河上;康河,我敢说是全世界最秀丽的一条水。河的名字是葛兰大(Granta),也有叫康河(Kiver Cam)的,许有上下流的区别,我不甚清楚。河身多的是曲折,上游是有名的拜伦潭——“Byron’s Pool”——当年拜伦常在那里玩的;有一个老村子叫格兰骞斯德,有一个果子园,你可以躺在累累的桃李树荫下吃茶,花果会掉入你的茶杯,小雀子会到你桌上来啄食,那真是别有一番天地。这是上游;下游是从骞斯德顿下去,河面展开,那是春夏间竞舟的场所。上下河分界处有一个坝筑,水流急得很,在星光下听水声,听近村晚钟声,听河畔倦牛刍草声,是我康桥经验中最神秘的一种:大自然的优美、宁静,调谐在这星光与波光的默契中不期然的淹入了你的性灵。
7、周作人《乌篷船》片段
倘若出城,走三四十里路(我们那里的里程是很短,一里才及英里三分之一),来回总要预备一天。你坐在船上,应该是游山的态度,看看四周物色,随处可见的山,岸旁的乌柏,河边的红寥和白殇,渔舍,各式各样的桥,困倦的时候睡在舱中拿出随笔来看,或者冲一碗清茶喝喝。偏门外的鉴湖一带,贺家池,壶筋左近,我都是喜欢的,或者往娄公埠骑驴去游兰亭(但我劝你还是步行,骑驴或者于你不很相宜),到得暮色苍然的时候进城上都挂着薛荔的东门来,倒是颇有趣味的事。倘若路上不平静,你往杭州去时可于下午开船,黄昏时候的景色正最好看,只可惜这一带地方的名字我都忘记了。夜间睡在舱中,听水声橹声,来往船只的招呼声,以及乡间的犬吠鸡鸣,也都很有意思。雇一只船到乡下去看庙戏,可以了解中国旧戏的真趣味,而且在船上行动自如,要看就看,要睡就睡,要喝酒就喝酒,我觉得也可以算是理想的行乐法。只可惜讲维新以来这些演剧与迎会都已禁止,中产阶级的低能人别在“布业会馆”等处建起“海式”的戏场来,请大家买票看上海的猫儿戏。这些地方你千万不要去。--你到我那故乡,恐怕没有一个人认得,我又因为在教书不能陪你去玩,坐夜船,谈闲天,实在抱歉而且惆怅。川岛君夫妇现在偁山下,本来可以给你绍介,但是你到那里的时候他们恐怕已经离开故乡了。初寒,善自珍重,不尽。
《假如今天是我生命中的最后一天……》
假如今天是我生命中的最后一天。
我要如何利用这最后、最宝贵的一天呢?首先,我要把一天的时间珍藏好,不让一分一秒的时间滴漏。我不为昨日的不幸叹息,过去的已够不幸,不要再陪上今日的运道。
时光会倒流吗?太阳会西升东落吗?我可以纠正昨天的错误吗?我能抚平昨日的创伤吗?我能比昨天年轻吗?一句出口的恶言,一记挥出的拳头,一切造成的痛,能收回吗?
不能!过去的永远过去了,我不再去想它。
假如今天是我生命中的最后一天。
我该怎么办?忘记昨天,也不要痴想明天。明天是一个未知数,为什么要把今天的精力浪费在未知的事上?想着明天的种种,今天的时光也白白流失了。祈盼今早的太阳再次升起,太阳已经落山。走在今天的路上,能做明天的事吗?我能把明天的金币放进今天的钱袋吗?明日瓜熟,今日能蒂落吗?明天的死亡能将今天的欢乐蒙上阴影吗?我能杞人忧天吗?明天和明天一样被我埋葬。我不再想它。
今天是我生命中的最后一天。
这是我仅有的一天,是现实的永恒。我像被赦免死刑的囚犯,用喜悦的泪水拥抱新生的太阳。我举起双手,感谢这无与伦比的一天。当我想到昨天和我一起迎接日出的朋友,今天已不复存在时,我为自己的幸存,感激上苍。我是无比幸运的人,今天的时光是额外的奖赏。许多强者都先我而去,为什么我得到这额外的一天?是不是因为他们已大功告成,而我尚在旅途跋涉?如果这样,这是不是成就我的一次机会,让我功德圆满?造物主的安排是否别具匠心?
今天是不是我超越他人的机会?今天是我生命中的最后一天。
生命只有一次,而人生也不过是时间的累积。我若让今天的时光白白流失,就等于毁掉人生最后一页。因此,我珍惜今天的一分一秒,因为他们将一去不复返。我无法把今天存入银行,明天再来取用。时间像风一样不可捕捉。每一分一秒,我要用双手捧住,用爱心抚摸,因为他们如此宝贵。垂死的人用毕生的钱财都无法换得一口生气。我无法计算时间的价值,它们是无价之宝!
今天是我生命中的最后一天。
我憎恨那些浪费时间的行为。我要摧毁拖延的习性。我要以真诚埋葬怀疑,用信心驱赶恐惧。我不听闲话,不游手好闲,不与不务正业的人来往。我终于醒悟到,若是懒惰,无异于从我所爱之人手中窃取食物和衣裳。我不是贼,我有爱心,今天是我最后的机会,我要证明我的爱心和伟大。
今天是我生命中的最后一天。
今日事今日毕。今天我要趁孩子还小的时侯,多加爱护,明天他们将离我而去,我也会离开。今天我要深
情地拥抱我的妻子,给她甜蜜的热吻,明天她会离去,我也是。今天我要帮助落难的朋友,明天他不再求援,我也听不到他的哀求。我要乐于奉献,因为明天我无法给予,也没有人来领受了。
今天是我生命中的最后一天。
如果这是我的末日,那么它就是不朽的纪念日。我把它当成最美好的日子。我要把每分每秒化为甘露,一口一口,细细品尝,满怀感激。我要每一分钟都有价值。我要加倍努力,直到精疲力竭。即使这样,我还要继续努力。今天的每一分钟都胜过昨天的每一小时,最后的也是最好的。
假如今天是我生命中的最后一天??
如果不是的话,我要跪倒在上苍面前,深深致谢。
《夏夜晚风》
明月多情应笑我,笑我如今,孤负春心,独自闲行独自吟。
近来怕说当时事,结遍兰襟,月浅灯深,梦里云归何处寻??
伶仃长夜,万籁俱寂。我站在窗前,凝望着远方的苍穹。晚风徐来,吹过脸颊,吹过发梢,吹过思绪。我想象着,我对你的思念,会不会也随着这轻柔的风,飘向夜空??
是谁说过,思念是一种痛,一种无可名状,又难以痊愈的痛。
我想,回忆也是。
你曾说过,我象风,放浪不羁,快意人生,时常吹得你的心,无所适从。
你也说过,你象水,微风乍起时,荡起的涟漪中止了你宁静的生活;而当风平浪静后,你也只能端坐如云,重新静守那一湖的寂寞??
我笑了,对你说我要做伴你一生的夏夜晚风;你也笑了,水晶般的眸子里潜藏着淡淡的忧伤。
现在我有点懂了,时光变幻,四季交替,哪里又有永远的夏夜和不息的晚风呢?也许当真是“天意如此,安复强求”吧。我们的故事,注定是一场失速的流离,一场彷徨的关注,一场风花的悲哀,一场美丽的闹剧??
回身走向钢琴,任琴声在夜空中流淌,任思绪默默飘向远方,任窗外的繁星悄悄然点缀这满屋的惆怅。 明月小楼,好风如水,清景无限,相思如梦,一室琴声,寂寞无人见??
谢却荼蘼,起身轻叹,一曲《长相思》勾起来伤心。时光沧莽的洪涛中,一曲一调地演绎着那古老的歌谣。 “生死挈阔,与子相悦;执子之手,与子偕老”??
你说,也许我们今生无缘,分手是最好的选择。我默而不答。
今夜,想说给你听,不要说今生无缘,只待来世,不要??不是不相信你,也不是不相信我,不相信的,也许只是那难以预测的明天,那无可抗拒的命运,那无从预知的期待??
而当我与酒相伴,独守一轮明月时。才明白,命运或许只能是一种悲哀;期待,或许真的太奢侈。
晚风不停地吹着,刮进了我记忆的深巷,又有谁懂触景的沉默中,有多少帘后的心事被撩起?
现在,你的身边有了新的依靠,我也回归了原本自在的生活,一切的一切,显得自然又和谐。
我在自怨自艾着什么?在悲哀着什么?
悲哀的是,你我本不该结束的,如此匆匆??
也许一切都在于自己。夏夜的晚风不仅为我们演示了生命无奈的过程,也向我们启示了坚强的意义??春天,永远都是为了走过冬天的人准备的。
每一年夏天,在岑寂的夜里都依然会吹起柔和的晚风,这就是真实。
只要记得,这里有风吹过,就足够了。
《听听那冷雨》
惊蛰一过,春寒加剧。先是料料峭峭,继而雨季开始,时而淋淋漓漓,时而淅淅沥沥,天潮潮地湿湿,即连在梦里,也似乎有把伞撑着。而就凭一把伞,躲过一阵潇潇的冷雨,也躲不过整个雨季。连思想也都是潮润润的。每天回家,曲折穿过金门街到厦门街迷宫式的长巷短巷,雨里风里,走入霏霏令人更想入非非。想这样子的台北凄凄切切完全是黑白片的味道,想整个中国整部中国的历史无非是一张黑白片子,片头到片尾,一直是这样下着雨的。这种感觉,不知道是不是从安东尼奥尼那里来的。不过那—块土地是久违了,二十五年,四
分之一的世纪,即使有雨,也隔着千山万山,千伞万伞。十五年,一切都断了,只有气候,只有气象报告还牵连在一起,大寒流从那块土地上弥天卷来,这种酷冷吾与古大陆分担。不能扑进她怀里,被她的裙边扫一扫也算是安慰孺慕之情吧。
这样想时,严寒里竟有一点温暖的感觉了。这样想时,他希望这些狭长的巷子永远延伸下去,他的思路也可以延伸下去,不是金门街到厦门街,而是金门到厦门。他是厦门人,至少是广义的厦门人,二十年来,不住在厦门,住在厦门街,算是嘲弄吧,也算是安慰。不过说到广义,他同样也是广义的江南人,常州人,南京人,川娃儿,五陵少年。杏花春雨江南,那是他的少年时代了。再过半个月就是清明。安东尼奥尼的镜头摇过去,摇过去又摇过来。残山剩水犹如是,皇天后土犹如是。纭纭黔首、纷纷黎民从北到南犹如是。那里面是中国吗?那里面当然还是中国永远是中国。只是杏花春雨已不再,牧童遥指已不再,剑门细雨渭城轻尘也都已不再。然则他日思夜梦的那片土地,究竟在哪里呢?
在报纸的头条标题里吗?还是香港的谣言里?还是傅聪的黑键白键马恩聪的跳弓拨弦?还是安东尼奥尼的镜底勒马洲的望中?还是呢,故宫博物院的壁头和玻璃柜内,京戏的锣鼓声中太白和东坡的韵里?
杏花,春雨,江南。六个方块字,或许那片土就在那里面。而无论赤县也好神州也好中国也好,变来变去,只要仓颉的灵感不灭,美丽的中文不老,那形象那磁石一般的向心力当必然长在。因为一个方块字是一个天地。太初有字,于是汉族的心灵他祖先的回忆和希望便有了寄托。譬如凭空写一个“雨”字,点点滴滴,滂滂沱沱,淅淅沥沥,一切云情雨意,就宛然其中了。视觉上的这种美感,岂是什么rain也好pluie也好所能满足?翻开一部《辞源》或《辞海》,金木水火土,各成世界,而一入“雨”部,古神州的天颜千变万化,便悉在望中,美丽的霜雪云霞,骇人的雷电霹雹,展露的无非是神的好脾气与坏脾气,气象台百读不厌门外汉百思不解的百科全书。
听听,那冷雨。看看,那冷雨。嗅嗅闻闻,那冷雨,舔舔吧,那冷雨。雨在他的伞上这城市百万人的伞上雨衣上屋上天线上,雨下在基隆港在防波堤海峡的船上,清明这季雨。雨是女性,应该最富于感性。雨气空而迷幻,细细嗅嗅,清清爽爽新新,有一点点薄荷的香味,浓的时候,竟发出草和树林之后特有的淡淡土腥气,也许那竟是蚯蚓的蜗牛的腥气吧,毕竟是惊蛰了啊。也许地上的地下的生命也许古中国层层叠叠的记忆皆蠢蠢而蠕,也许是植物的潜意识和梦紧,那腥气。
第三次去美国,在高高的丹佛他山居住了两年。美国的西部,多山多沙漠,千里干旱,天,蓝似安格罗萨克逊人的眼睛,地,红如印第安人的肌肤,云,却是罕见的白鸟,落基山簇簇耀目的雪峰上,很少飘云牵雾。一来高,二来干,三来森林线以上,杉柏也止步,中国诗词里“荡胸生层云”或是“商略黄昏雨”的意趣,是落基山上难睹的景象。落基山岭之胜,在石,在雪。那些奇岩怪石,相叠互倚,砌一场惊心动魄的雕塑展览,给太阳和千里的风看。那雪,白得虚虚幻幻,冷得清清醒醒,那股皑皑不绝一仰难尽的气势,压得人呼吸困难,心寒眸酸。不过要领略“白云回望合,青露入看无”的境界,仍须来中国。台湾湿度很高,最饶云气氛题雨意迷离的情调。两度夜宿溪头,树香沁鼻,宵寒袭肘,枕着润碧湿翠苍苍交叠的山影和万缀都歇的俱寂,仙人一样睡去。山中一夜饱雨,次晨醒来,在旭日未升的原始幽静中,冲着隔夜的寒气,踏着满地的断柯折枝和仍在流泻的细股雨水,一径探入森林的秘密,曲曲弯弯,步上山去。溪头的山,树密雾浓,蓊郁的水气从谷底冉冉升起,时稠时稀,蒸腾多姿,幻化无定,只能从雾破云开的空处,窥见乍现即隐的一峰半堑,要纵览全貌,几乎是不可能的。至少上山两次,只能在白茫茫里和溪头诸峰玩捉迷藏的游戏。回到台北,世人问起,除了笑而不答心自问,故作神秘之外,实际的印象,也无非山在虚无之间罢了。云绦烟绕,山隐水迢的中国风景,由来予人宋画的韵味。那天下也许是赵家的天下,那山水却是米家的山水。而究竟,是米氏父子下笔像中国的山水,还是中国的山水上只像宋画,恐怕是谁也说不清楚了吧?
雨不但可嗅,可亲,更可以听。听听那冷雨。听雨,只要不是石破天惊的台风暴雨,在听觉上总是一种美感。大陆上的秋天,无论是疏雨滴梧桐,或是骤雨打荷叶,听去总有一点凄凉,凄清,凄楚,于今在岛上回味,则在凄楚之外,再笼上一层凄迷了,饶你多少豪情侠气,怕也经不起三番五次的风吹雨打。一打少年听雨,红烛昏沉。再打中年听雨,客舟中江阔云低。三打白头听雨的僧庐下,这更是亡宋之痛,一颗敏感心灵的一生:楼上,江上,庙里,用冷冷的雨珠子串成。十年前,他曾在一场摧心折骨的鬼雨中迷失了自己。雨,该是一滴湿漓漓的灵魂,窗外在喊谁。
雨打在树上和瓦上,韵律都清脆可听。尤其是铿铿敲在屋瓦上,那古老的音乐,属于中国。王禹的黄冈,破如椽的大竹为屋瓦。据说住在竹楼上面,急雨声如瀑布,密雪声比碎玉,而无论鼓琴,咏诗,下棋,投壶,共鸣的效果都特别好。这样岂不像住在竹和筒里面,任何细脆的声响,怕都会加倍夸大,反而令人耳朵过敏吧。
雨天的屋瓦,浮漾湿湿的流光,灰而温柔,迎光则微明,背光则幽黯,对于视觉,是一种低沉的安慰。至于雨敲在鳞鳞千瓣的瓦上,由远而近,轻轻重重轻轻,夹着一股股的细流沿瓦槽与屋檐潺潺泻下,各种敲击音与滑音密织成网,谁的千指百指在按摩耳轮。“下雨了”,温柔的灰美人来了,她冰冰的纤手在屋顶拂弄着无数的黑键啊灰键,把晌午一下子奏成了黄昏。
在古老的大陆上,千屋万户是如此。二十多年前,初来这岛上,日式的瓦屋亦是如此。先是天黯了下来,城市像罩在一块巨幅的毛玻璃里,阴影在户内延长复加深。然后凉凉的水意弥漫在空间,风自每一个角落里旋起,感觉得到,每一个屋顶上呼吸沉重都覆着灰云。雨来了,最轻的敲打乐敲打这城市。苍茫的屋顶,远远近近,一张张敲过去,古老的琴,那细细密密的节奏,单调里自有一种柔婉与亲切,滴滴点点滴滴,似幻似真,若孩时在摇篮里,一曲耳熟的童谣摇摇欲睡,母亲吟哦鼻音与喉音。或是在江南的泽国水乡,一大筐绿油油的桑叶被啮于千百头蚕,细细琐琐屑屑,口器与口器咀咀嚼嚼。雨来了,雨来的时候瓦这幺说,一片瓦说千亿片瓦说,说轻轻地奏吧沉沉地弹,徐徐地叩吧挞挞地打,间间歇歇敲一个雨季,即兴演奏从惊蛰到清明,在零落的坟上冷冷奏挽歌,一片瓦吟千亿片瓦吟。
在旧式的古屋里听雨,听四月,霏霏不绝的黄梅雨,朝夕不断,旬月绵延,湿黏黏的苔藓从石阶下一直侵到舌底,心底。到七月,听台风台雨在古屋顶上一夜盲奏,千层海底的热浪沸沸被狂风挟挟,掀翻整个太平洋只为向他的矮屋檐重重压下,整个海在他的蝎壳上哗哗泻过。不然便是雷雨夜,白烟一般的纱帐里听羯鼓一通又一通,滔天的暴雨滂滂沛沛扑来,强劲的电琵琶忐忐忑忑忐忐忑忑,弹动屋瓦的惊悸腾腾欲掀起。不然便是斜斜的西北雨斜斜刷在窗玻璃上,鞭在墙上打在阔大的芭蕉叶上,一阵寒潮泻过,秋意便弥湿旧式的庭院了。
在旧式的古屋里听雨,春雨绵绵听到秋雨潇潇,从少年听到中年,听听那冷雨。雨是一种单调而耐听的音乐是室内乐是室外乐,户内听听,户外听听,冷冷,那音乐。雨是一种回忆的音乐,听听那冷雨,回忆江南的雨下得满地是江湖下在桥上和船上,也下在四川在秧田和蛙塘,—下肥了嘉陵江下湿布谷咕咕的啼声,雨是潮潮润润的音乐下在渴望的唇上,舔舔那冷雨。
因为雨是最最原始的敲打乐从记忆的彼端敲起。瓦是最最低沉的乐器灰蒙蒙的温柔覆盖着听雨的人,瓦是音乐的雨伞撑起。但不久公寓的时代来临,台北你怎么一下子长高了,瓦的音乐竟成了绝响。千片万片的瓦翩翩,美丽的灰蝴蝶纷纷飞走,飞入历史的记忆。现在雨下下来下在水泥的屋顶和墙上,没有音韵的雨季。树也砍光了,那月桂,那枫树,柳树和擎天的巨椰,雨来的时候不再有丛叶嘈嘈切切,闪动湿湿的绿光迎接。鸟声减了啾啾,蛙声沉了咯咯,秋天的虫吟也减了唧唧。七十年代的台北不需要这些,一个乐队接一个乐队便遣散尽了。要听鸡叫,只有去诗经的韵里找。现在只剩下一张黑白片,黑白的默片。
正如马车的时代去后,三轮车的夫工也去了。曾经在雨夜,三轮车的油布篷挂起,送她回家的途中,篷里的世界小得多可爱,而且躲在警察的辖区以外,雨衣的口袋越大越好,盛得下他的一只手里握一只纤纤的手。台湾的雨季这么长,该有人发明一种宽宽的双人雨衣,一人分穿一只袖子此外的部分就不必分得太苛。而无论工业如何发达,一时似乎还废不了雨伞。只要雨不倾盆,风不横吹,撑一把伞在雨中仍不失古典的韵味。任雨点敲在黑布伞或是透明的塑胶伞上,将骨柄一旋,雨珠向四方喷溅,伞缘便旋成了一圈飞檐。跟女友共一把雨伞,该是一种美丽的合作吧。最好是初恋,有点兴奋,更有点不好意思,若即若离之间,雨不妨下大一点。真正初恋,恐怕是兴奋得不需要伞的,手牵手在雨中狂奔而去,把年轻的长发的肌肤交给漫天的淋淋漓漓,然后向对方的唇上颊上尝凉凉甜甜的雨水。不过那要非常年轻且激情,同时,也只能发生在法国的新潮片里吧。
大多数的雨伞想不会为约会张开。上班下班,上学放学,菜市来回的途中。现实的伞,灰色的星期三。握着雨伞。他听那冷雨打在伞上。索性更冷一些就好了,他想。索性把湿湿的灰雨冻成干干爽爽的白雨,六角形的结晶体在无风的空中回回旋旋地降下来。等须眉和肩头白尽时,伸手一拂就落了。二十五年,没有受故乡白雨的祝福,或许发上下一点白霜是一种变相的自我补偿吧。一位英雄,经得起多少次雨季?他的额头是水成岩削成还是火成岩?他的心底究竟有多厚的苔藓?厦门街的雨巷走了二十年与记忆等长,—座无瓦的公寓在巷底等他,一盏灯在楼上的雨窗子里,等他回去,向晚餐后的沉思冥想去整理青苔深深的记忆。
前尘隔海。古屋不再。听听那冷雨。
《心愿》
时间好比一把锋利的小刀枣用得不恰当,会在美丽的面孔上刻下深深的纹路,使旺盛的青春月复一月,年复一年地消磨掉;但是,使用恰当的话,它却能将一块普通的石头琢刻成宏伟的雕像。圣玛丽亚女校虽然已有五十年历史,仍是一块只会稍加雕琢的普通白石。随着时光的流逝,它也许会给尘埃染污,受风雨侵蚀,或破裂成片片碎石。另一方面,它也可以给时间的小刀仔细地、缓慢地、一寸一寸地刻成一个奇妙的雕像,置于米开朗琪罗的那些辉煌的作品中亦无愧色。这把小刀不仅为校长、教师和明日的学生所持有,我们全体同学都有权利操纵它。
如果我能活到白发苍苍的老年,我将在炉边宁静的睡梦中,寻找早年所熟悉的穿过绿色梅树林的小径。当然,那时候,今日年轻的梅树也必已进入愉快的晚年,伸出有力的臂膊遮蔽着纵横的小径。饱经风霜的古老钟楼,仍将兀立在金色的阳光中,发出在我听来是如此熟悉的钟声。在那缓慢而庄严的钟声里,高矮不一、脸蛋儿或苍白或红润、有些身材丰满、有些体形纤小的姑娘们,焕发着青春活力和朝气,像小溪般涌入教堂。在那里,她们将跪下祈祷,向上帝低声细诉她们的生活小事:她们的悲伤,她们的眼泪,她们的争吵,她们的喜爱,以及她们的宏愿。她们将祈求上帝帮助自己达到目标,成为作家、音乐家、教育家或理想的妻子。我还可以听到那古老的钟楼在祈祷声中发出回响,仿佛是低声回答她们:“是的,与全中国其他学校相比,圣玛利亚女校的宿舍未必是最大的,校内的花园也未必是最美丽的,但她无疑有最优秀、最勤奋好学的小姑娘,她们将以其日后辉煌的事业来为母校增光!”
听到这话语时,我的感受将取决于自己在毕业后的岁月里有无任何成就。如果我没有克尽本分,丢了荣耀母校的权利,我将感到羞耻和悔恨。但如果我在努力为目标奋斗的路上取得成功,我可以欣慰地微笑,因为我也有份用时间这把小刀,雕刻出美好的学校生活的形象虽然我的贡献是那样微不足道。