`
etfired
  • 浏览: 36937 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

JAVA Applet 实现工作流设计器

阅读更多

很久没有更新博客了,不是偷懒,而是去年一年的时间都在编写一个快速JAVA开发框架ARK,终于有所小成,才有了闲情逸致没事写点小玩意儿,JAVA Swing自己很少关注,Applet也是如此,从学习Swing和Applet到写出这东西只花了2天时间,算是一些自己的学习心得和成果,希望各位看客多多交流,虽然Applet和Swing不是我工作的重点,偶尔当消遣了。



 

 

 

言归正传,这是一个工作流系统中的流程设计器,整个设计完全面向接口,所以有比较好的扩展性,小弟我水平有限,一些功能就没有加上,有兴趣的XD可以完善这些代码(其实大部分功能都已经实现了,包括流程图路径验证,只是现在只能绘制流程生成XML,没有反向去实现将XML生成流程图),可能自己想起来会再把他翻出来改改,在某个时间将图形转换成HTML能够直接在网页上显示,为什么这么干,你懂得!!

 

package com.applet.flows;

import java.awt.Container;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.event.MouseInputAdapter;

import com.applet.flows.attr.NodeAttribute;
import com.applet.flows.panel.FlowLine;
import com.applet.flows.panel.FlowPanel;

public abstract class NodeButtonSupport extends JButton implements INodeButton {

	private Collection<INodeButton> childs = null;
	
	private Collection<INodeButton> parents = null;
	
	private int id = -1;
	
	protected DropTarget dropTarget = null;
	
	public NodeButtonSupport(){
		this.childs = new Vector<INodeButton>();
		this.parents = new Vector<INodeButton>();
		this.dropTarget = new DropTarget(this,DnDConstants.ACTION_COPY,this,true);
		new MouseApdaterListener(this);
		this.setSize(100, 40);
		this.setLocation(0, 45);
	}
	
	public ImageIcon getIcon(){
		return null;
	}
	
	public final String[] asXML() {
		String xml = "";
		xml = "<Node id=\"" + this.getID() + "\" type=\"" + this.getType() + "\" name=\"" + this.getText() + "\" x=\"" + this.getX() + "\" y=\"" + this.getY() + "\" />";
		String to = "";
		for(INodeButton nb:this.getChilds()){
			to += nb.getID() + ",";
		}
		String line = "";
		if(!to.trim().equals("")){
			line  = "<Line from=\"" + this.getID() + "\" to=\"" + to.substring(0,to.length() - 1) + "\" />";
		}
		return new String[]{xml,line};
	}

	public final void init(int id) {
		this.id = id;
		ImageIcon icon = this.getIcon();
		if(icon != null){
			this.setIcon(icon);
		}
		this.init();
	}
	
	public INodeButton getThis(){
		return this;
	}
	
	/**
	 * 判断当某个对象接入子对象后,是否会成为一个循环流程
	 * @param button 接入后的对象
	 * @return true:是一个循环,false:不是循环
	 */
	public boolean isPathed(INodeButton button){
		for(INodeButton nb : this.getChilds()){
			if(nb == button){
				return true;
			}
			if(nb instanceof NodeButtonSupport){
				return ((NodeButtonSupport)nb).isPathed(button);
			}
		}
		return false;
	}
	
	/**
	 * 找到Frame对象
	 * @param jc
	 * @return
	 */
	public FlowPanel getFrame(Container jc){
		if(jc == null){
			return null;
		}
		if(jc instanceof FlowPanel){
			return (FlowPanel)jc;
		}
		return this.getFrame(jc.getParent());
	}
	
	protected abstract void init();
	
	public int getID(){
		return this.id;
	}
	
	public abstract boolean link(INodeButton button);

	public void addParent(INodeButton nb){
		this.parents.add(nb);
	}
	
	public void addChild(INodeButton nb){
		this.childs.add(nb);
	}

	public void dragEnter(DropTargetDragEvent arg0) {

	}

	public void dragExit(DropTargetEvent arg0) {

	}

	public void dragOver(DropTargetDragEvent arg0) {

	}

	public final void drop(DropTargetDropEvent e) {
		DataFlavor ob = e.getCurrentDataFlavors()[0];
		try {
			if(!e.getTransferable().isDataFlavorSupported(ob)){
				JOptionPane.showMessageDialog(null, "应用程序不支持对象序列化\n[" + ob.toString() + "]","错误",JOptionPane.ERROR_MESSAGE);
				return;
			}
			INodeButton db = (INodeButton)e.getTransferable().getTransferData(ob);
			if(db == null){
				JOptionPane.showMessageDialog(null, "应用程序无法读取对象序列化\n[" + ob.toString() + "]","错误",JOptionPane.ERROR_MESSAGE);
				return;
			}
			if(isPathed(db)){
				return;
			}
			if(db.report(this) && this.link(db)){
				this.addParent(db);
				db.addChild(this);
				FlowPanel frame = this.getFrame(this.getParent());
				if(frame == null){
					JOptionPane.showMessageDialog(null, "程序无法找到父容器","错误",JOptionPane.ERROR_MESSAGE);
				}else{
					FlowLine line = new FlowLine(new JButton[]{(JButton)db,this});
					line.setSize(frame.getSize());
					line.setLocation(0,0);
					frame.add(line);
					frame.setText("[" + this.getText() + "]连线成功");
					frame.repaint();
				}
			}
		} catch (Exception e1) {
			this.getFrame(this.getParent()).setText(e1.getClass().getName());
			JOptionPane.showMessageDialog(null, e1.toString(),"错误",JOptionPane.ERROR_MESSAGE);
			e1.printStackTrace();
		}
	}
	@Override
	public void setToolTipText(String str) {
		str =  "[ID=" + this.getID() + "]\n" + str; 
		super.setToolTipText(str);
	}
	
	public void dropActionChanged(DropTargetDragEvent arg0) {

	}
	
	public final Collection<INodeButton> getChilds(){
		return this.childs;
	}
	
	public final Collection<INodeButton> getParents(){
		return this.parents;
	}

	/**
	 * 获取节点类型
	 * @return 节点类型
	 */
	public abstract String getType();
	
	public final class MouseApdaterListener extends MouseInputAdapter{
		
		private NodeButtonSupport support = null;
		
		private Point point = new Point(0, 0);   
		
		public MouseApdaterListener(NodeButtonSupport support){
			this.support = support;
			this.support.addMouseListener(this);
			this.support.addMouseMotionListener(this);
		}
		
		@Override
		public void mouseClicked(MouseEvent e) {
			new NodeAttribute(this.support).setVisible(true);
		}
		
		public void mousePressed(MouseEvent e) {
			if(e.getButton() != 1){
				JComponent com=(JComponent)e.getSource();
				TransferHandler handler = new TransferHandler("this");
				com.setTransferHandler(handler);
				handler.exportAsDrag(com, e, DnDConstants.ACTION_COPY);
			}else{
				this.point = SwingUtilities.convertPoint(this.support, e.getPoint(), this.support.getParent());
			}
		}
		
		@Override
		public void mouseDragged(MouseEvent e) {
			if(e.getButton() != 1){
				Point newPoint = SwingUtilities.convertPoint(this.support, e.getPoint(), this.support.getParent());
				Point btnPoint = new Point((this.support.getX() + (newPoint.x - this.point.x )),(this.support.getY() + (newPoint.y - this.point.y)));
				this.support.setLocation(btnPoint);
				point = newPoint;
				FlowPanel frame = this.support.getFrame(this.support.getParent());
				frame.repaint();
			}
		}
	}
}

 

强调一下,NodeButtonSupport是所有节点的抽象类,如果希望扩展节点类型的XD在增加类型的时候一定别忘了继承他,里面很多算法我都已经实现好了,当然还有两个接口。

package com.applet.flows;

/**
 * 基本XML流程对象
 * 
 * @author 熊浩华 - xionghh
 *
 * 2011-3-10:下午12:29:47-
 */
public interface IFlow {

	/**
	 * 返回该对象的XML分为{节点,连接线}
	 * @return
	 */
	public String[] asXML();
	
	/**
	 * 判断节点是否是合法
	 * @return 当节点存在异常时抛出节点异常信息,否则返回true
	 */
	public boolean checkNode() throws Exception;
	
}

  

 

 

 导出XML文档的接口,所有的节点都实现该接口用于保存时生成XML文档方便,代码派生起来也容易。

 

package com.applet.flows;

import java.awt.dnd.DropTargetListener;
import java.util.Collection;

/**
 * 流程节点接口,用于处理流程的节点
 * 
 * @author 熊浩华 - xionghh
 *
 * 2011-3-10:上午10:02:53-
 */
public interface INodeButton extends DropTargetListener,IFlow {

	/**
	 * 初始化节点对象
	 * @param id 对象ID
	 */
	public void init(int id);
	
	/**
	 * 某个节点拖入,是否允许他和你进行链接
	 * @param button 发起链接的对象
	 * @return 判断是否允许链接,返回true表示允许,false表示不允许操作
	 */
	public boolean link(INodeButton button);
	
	/**
	 * 通知节点,你被拖动到某个节点上,需要你和他进行链接
	 * @param button 需要链接的对象
	 * @return 允许链接返回true,不允许链接返回false
	 */
	public boolean report(INodeButton button);
	
	/**
	 * 获取对象ID
	 * @return 对象ID
	 */
	public int getID();
	
	/**
	 * 添加一个父对象
	 * @param nb
	 */
	public void addParent(INodeButton nb);
	
	/**
	 * 添加一个子对象
	 * @param nb
	 */
	public void addChild(INodeButton nb);
	
	/**
	 * 获取所有子对象
	 * @return
	 */
	public Collection<INodeButton> getChilds();
	
	/**
	 * 获取所有父对象
	 * @return
	 */
	public Collection<INodeButton> getParents();
	
}

 

INodeButton是所有节点的抽象接口,其实很多方法都是想到的时候补上的,开始打算写这个东西的时候没有想把他做成什么样,就当玩票,没仔细去对接口进行详细的设计,很粗略的就描绘了一下。所以看起来有点似是而非。

 

 

最后说一下Demo,压缩包里有tomcat的工程目录,XFLow直接Copy到tomcat下的webapps里就能运行,里面两个包flows.jar和dom4j-1.6.1.jar是签名过的,否则无法当成Applet运行,源码在src里,修改代码后想要在Applet测试通过记得打成包然后对包进行签名。

 

PS:呵呵,老规矩,CSDN(最近穷疯了,分不够了,希望各位给小弟我捧个场)

 

 

 

 

 下载地址 : http://download.csdn.net/source/3082444

 

  • 大小: 12.6 KB
分享到:

相关推荐

    JAVA Applet 工作流设计器

    JAVA Applet工作流设计器是一种基于JAVA Swing技术开发的工具,用于设计和构建工作流模型。在IT领域,工作流设计器是工作流管理系统的核心组件,它允许用户通过图形化界面定义和编辑业务流程。以下是关于这个主题的...

    JAVA applet car park

    Java Applet的工作原理是通过Java Virtual Machine (JVM) 在用户的浏览器中运行。当用户访问包含Java Applet的网页时,浏览器会下载applet的字节码,并由内置的JVM执行。这种技术在20世纪90年代非常流行,因为它提供...

    Web版工作流流程设计器需求说明书详细.doc

    Web 版工作流流程设计器是指一个基于 Web 的流程设计器,旨在提供一个简洁、易用的工作流设计器,帮助普通用户(非开发技术人员)快速设计和实现业务流程。该设计器基于 Flex+JBPM4.4 实现,完全遵循最新版的 XML ...

    rere.rar_java Applet_java 声音_rere

    首先,我们要理解Java Applet的工作原理。Applets通常由Java源代码(.java文件)编写,然后通过Java编译器(javac)编译成字节码(.class文件)。这些字节码文件在用户访问包含Applet的网页时,由Java Web Start或...

    wav简易音乐播放器java实现

    总的来说,实现一个简单的WAV音乐播放器涉及多个Java技术点,包括音频处理、线程控制、GUI设计以及文件操作等。通过这个项目,开发者不仅可以提升Java编程技能,还能对音频处理有更深入的理解。

    JAVA开发聊天系统(java+applet).zip

    在这个"JAVA开发聊天系统(java+applet)"项目中,开发者使用Java语言和Applet技术来创建了一个可以在Web浏览器上运行的实时聊天应用。 1. **Java基础**:首先,开发者需要对Java的基础语法有深入理解,包括类、对象...

    基于java的约瑟夫环演示Applet源码.zip

    Java是一种广泛使用的面向对象的编程语言,以其跨平台、高性能和丰富的...尽管现代Web开发更多地使用JavaScript和Web框架,但了解Java Applet的历史和工作原理仍然是有价值的,因为它体现了早期Web交互技术的发展历程。

    java源码包---java 源码 大量 实例

     Java绘制图片火焰效果,源代码相关注释:前景和背景Image对象、Applet和绘制火焰的效果的Image对象、Applet和绘制火焰的效果的Graphics对象、火焰效果的线程、Applet的高度,图片到图片装载器、绘制火焰效果的X坐标...

    背景声音applet小程序.zip_applet

    【标题】"背景声音applet小程序.zip_applet" 指的是一款基于Java Applet技术开发的...尽管现代Web技术已经倾向于使用更先进的框架如JavaScript和WebAssembly,但了解和研究Java Applet的历史和工作原理仍然是有价值的。

    图片浏览小程序(java+applet).zip

    【标题】"图片浏览小程序(java+applet)" 是一个基于Java编程语言开发的项目,它包含了一个Applet组件,用于实现网页中的图片浏览功能。Applet是Java的一种小程序,可以在支持Java的浏览器中运行,为用户提供交互式...

    图片浏览小程序(java+applet)130227.rar

    标题中的“图片浏览小程序(java+applet)130227.rar”表明这是一个使用Java技术和Applet开发的图片浏览应用程序。Applet是Java的一种早期Web应用形式,它可以在浏览器中运行,为用户提供互动体验。这个项目可能包含了...

    Java程序设计基础

    Java语言的深入学习还包括数据类型、面向对象特性(如封装、继承和多态)、常用内置包(如java.util和java.io)、集合框架、异常处理、流编程、网络编程、多线程技术和图形用户界面编程(GUI)以及小应用程序...

    java源码包3

     Java绘制图片火焰效果,源代码相关注释:前景和背景Image对象、Applet和绘制火焰的效果的Image对象、Applet和绘制火焰的效果的Graphics对象、火焰效果的线程、Applet的高度,图片到图片装载器、绘制火焰效果的X坐标...

    java源码包2

     Java绘制图片火焰效果,源代码相关注释:前景和背景Image对象、Applet和绘制火焰的效果的Image对象、Applet和绘制火焰的效果的Graphics对象、火焰效果的线程、Applet的高度,图片到图片装载器、绘制火焰效果的X坐标...

    JAVA_API1.6文档(中文)

    java.applet 提供创建 applet 所必需的类和 applet 用来与其 applet 上下文通信的类。 java.awt 包含用于创建用户界面和绘制图形图像的所有类。 java.awt.color 提供用于颜色空间的类。 java.awt.datatransfer ...

    Java程序设计语言

    不过,由于现代Web技术的发展,Applet的使用已逐渐减少,但了解其工作原理对理解Java在网络中的应用仍然有价值。 以上内容构成了一个完整的Java学习路径,从基础语法到高级特性,覆盖了开发Java应用程序所需的关键...

    java实验设计包括程序设计,当学习用不错

    这个"java实验设计"的资源显然旨在帮助学习者深入理解和实践Java编程。实验指导书是学习编程过程中不可或缺的一部分,因为它提供了实际操作的机会,让学生通过编写代码来巩固理论知识。 在"java实验指导书(修订_...

    JAVA程序设计习题库及答案(非常全面)

    ### JAVA程序设计习题库及答案(非常全面) ...Java解释器的工作原理是读取字节码文件(.class文件),并将字节码解释执行。这种解释执行的方式使得Java程序可以在不同平台上运行,而无需重新编译。

    java开源包4

    public class JVMine extends java.applet.Applet 简单实现!~ 网页表格组件 GWT Advanced Table GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag...

Global site tag (gtag.js) - Google Analytics