flowable⼯作流简单请假流程,⾃定义完成的流程图表颜⾊字体以及连接线的颜
⾊字体。
1. 效果图
2. 代码
1.bpmn⽂件l(通过可视化⼯具⽣成【⾮常熟悉也可以⼿动编写】)
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="/spec/BPMN/20100524/MODEL" xmlns:xsi="www.w3/2001/XMLSchema-instance"
xmlns:flowable="flowable/bpmn" xmlns:bpmndi="/spec/BPMN/20100524/DI"
xmlns:omgdc="/spec/DD/20100524/DC" xmlns:omgdi="/spec/DD/20100524/DI"
typeLanguage="www.w3/2001/XMLSchema" expressionLanguage="www.w3/1999/XPath"
targetNamespace="www.flowable/processdef">
<process id="Expen" name="ExpenProcess" isExecutable="true">
<documentation>请假申请</documentation>
<startEvent id="start" name="开始"></startEvent>
<quenceFlow id="flow1" sourceRef="start" targetRef="fillTask"/>
<urTask id="fillTask" name="请假申请" flowable:assignee="${taskUr}"/>
<exclusiveGateway id="judgeTask"></exclusiveGateway>
<quenceFlow id="flow2" sourceRef="fillTask" targetRef="judgeTask"/>
<quenceFlow id="judgeMore" name="⼤于3天" sourceRef="judgeTask" targetRef="bossTask">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${day > 3}]]></conditionExpression>
</quenceFlow>
<urTask id="bossTask" name="⽼板审批" flowable:assignee="${ur2}"/>
<quenceFlow id="bossNotPassFlow" name="驳回" sourceRef="bossTask" targetRef="fillTask">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='驳回'}]]></conditionExpression>
</quenceFlow>
<quenceFlow id="bossPassFlow" name="通过" sourceRef="bossTask" targetRef="end">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression>
</quenceFlow>
<quenceFlow id="judgeLess" name="⼩于等于3天" sourceRef="judgeTask" targetRef="directorTak">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${day <= 3}]]></conditionExpression>
曹德旺简介
</quenceFlow>
<urTask id="directorTak" name="经理审批" flowable:assignee="${ur1}"/>
<quenceFlow id="directorNotPassFlow" name="驳回" sourceRef="directorTak" targetRef="fillTask">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='驳回'}]]></conditionExpression> </quenceFlow>
<quenceFlow id="directorPassFlow" name="通过" sourceRef="directorTak" targetRef="end">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression> </quenceFlow>
<endEvent id="end" name="结束"></endEvent>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_Expen">
<bpmndi:BPMNPlane bpmnElement="Expen" id="BPMNPlane_Expen">
<bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">
<omgdc:Bounds height="30.0" width="30.0" x="85.0" y="85.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="fillTask" id="BPMNShape_fillTask">
<omgdc:Bounds height="80.0" width="100.0" x="205.0" y="60.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="judgeTask" id="BPMNShape_judgeTask">
<omgdc:Bounds height="40.0" width="40.0" x="385.0" y="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="directorTak" id="BPMNShape_directorTak">
<omgdc:Bounds height="80.0" width="100.0" x="535.0" y="60.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="bossTask" id="BPMNShape_bossTask">
<omgdc:Bounds height="80.0" width="100.0" x="355.0" y="205.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end">
<omgdc:Bounds height="28.0" width="28.0" x="571.0" y="231.0"/>
个人所得税申报操作流程
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="115.0" y="100.0"/>
<omgdi:waypoint x="205.0" y="100.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="305.0" y="100.16611295681062"/>
<omgdi:waypoint x="385.4333333333333" y="100.43333333333334"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="judgeLess" id="BPMNEdge_judgeLess">
<omgdi:waypoint x="424.5530726256983" y="100.44692737430168"/>
<omgdi:waypoint x="535.0" y="100.1392757660167"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="directorNotPassFlow" id="BPMNEdge_directorNotPassFlow">
<omgdi:waypoint x="585.0" y="110.0"></omgdi:waypoint>
<omgdi:waypoint x="585.0" y="37.0"></omgdi:waypoint>
<omgdi:waypoint x="255.0" y="37.0"></omgdi:waypoint>
<omgdi:waypoint x="255.0" y="110.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="bossPassFlow" id="BPMNEdge_bossPassFlow">
<omgdi:waypoint x="455.0" y="245.0"/>
<omgdi:waypoint x="571.0" y="245.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="judgeMore" id="BPMNEdge_judgeMore">
<omgdi:waypoint x="405.4340277777778" y="119.56597222222223"/>
太白花<omgdi:waypoint x="405.1384083044983" y="205.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="directorPassFlow" id="BPMNEdge_directorPassFlow">
<omgdi:waypoint x="585.0" y="140.0"/>
<omgdi:waypoint x="585.0" y="231.0"/>
外经贸局
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="bossNotPassFlow" id="BPMNEdge_bossNotPassFlow">
<omgdi:waypoint x="355.0" y="245.0"></omgdi:waypoint>
<omgdi:waypoint x="355.0" y="245.0"></omgdi:waypoint>
<omgdi:waypoint x="255.0" y="245.0"></omgdi:waypoint>
<omgdi:waypoint x="255.0" y="140.0"></omgdi:waypoint>
怎么求最小公倍数</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
2.⾃定义已经⾛过的流程⾼亮连接线和⾼亮图标
(1)重写DefaultProcessDiagramCanvas⽅法
import org.del.AssociationDirection;
import org.del.GraphicInfo;
import org.flowable.image.impl.DefaultProcessDiagramCanvas;
import org.flowable.image.util.ReflectUtil;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
窑洞里的读书人import java.awt.font.TextLayout;
import Ellip2D;
import Path2D;
import Rectangle2D;
import RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
AttributedCharacterIterator;
AttributedString;
/**
* Created by x_zenglengceng on 2019/11/11.
*/
public class DefaultProcessDiagramCanvasExt extends DefaultProcessDiagramCanvas {
//定义⾛过流程连线颜⾊为红⾊
protected static Color HIGHLIGHT_SequenceFlow_COLOR = Color.GREEN;
//设置未⾛过流程的连接线颜⾊
protected static Color CONNECTION_COLOR = Color.BLACK;
//设置flows连接线字体颜⾊red
protected static Color LABEL_COLOR = new Color(0, 0, 0);
//⾼亮显⽰task框颜⾊
protected static Color HIGHLIGHT_COLOR = Color.GREEN;
protected static Color HIGHLIGHT_COLOR1 = Color.RED;
public DefaultProcessDiagramCanvasExt(int width, int height, int minX, int minY, String imageType,
String activityFontName, String labelFontName, Strin g annotationFontName, ClassLoader customClassLoader) {
super(width, height, minX, minY, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);
this.initialize(imageType);
}
/**
* 重写绘制连线的⽅式,设置绘制颜⾊
*/浅尝辄止的反义词
@Override
public void drawConnection(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault, String connectionType, AssociationDirection associationDir ection, boolean highLighted, double scaleFactor) {
Paint originalPaint = Paint();
Stroke originalStroke = Stroke();
if (connectionType.equals("association")) {
} el if (highLighted) {
}
for(int i = 1; i < xPoints.length; ++i) {
Integer sourceX = xPoints[i - 1];
Integer sourceY = yPoints[i - 1];
Integer targetX = xPoints[i];
Integer targetY = yPoints[i];
Line2D.Double line = new Line2D.Double((double)sourceX, (double)sourceY, (double)targetX, (double)targetY);
}
Line2D.Double line;
if (isDefault) {
line = new Line2D.Double((double)xPoints[0], (double)yPoints[0], (double)xPoints[1], (double)yPoints[1]);
this.drawDefaultSequenceFlowIndicator(line, scaleFactor);
}
if (conditional) {
line = new Line2D.Double((double)xPoints[0], (double)yPoints[0], (double)xPoints[1], (double)yPoints[1]);
this.drawConditionalSequenceFlowIndicator(line, scaleFactor);
}
if (associationDirection.equals(AssociationDirection.ONE) || associationDirection.equals(AssociationDirection.BOTH)) {
line = new Line2D.Double((double)xPoints[xPoints.length - 2], (double)yPoints[xPoints.length - 2], (double)xPoints[xPoints.length - 1] , (double)yPoints[xPoints.length - 1]);
this.drawArrowHead(line, scaleFactor);
}
if (associationDirection.equals(AssociationDirection.BOTH)) {
line = new Line2D.Double((double)xPoints[1], (double)yPoints[1], (double)xPoints[0], (double)yPoints[0]);
this.drawArrowHead(line, scaleFactor);
}
}
//设置字体⼤⼩图标颜⾊
@Override
public void initialize(String imageType) {
if("png".equalsIgnoreCa(imageType)) {
小主持this.processDiagram = new BufferedImage(this.canvasWidth, this.canvasHeight, 2);
} el {
this.processDiagram = new BufferedImage(this.canvasWidth, this.canvasHeight, 1);
}
this.g = ateGraphics();
if(!"png".equalsIgnoreCa(imageType)) {
}
//修改图标颜⾊,修改图标字体⼤⼩
Font font = new Font(this.activityFontName, 10, 14);
this.fontMetrics = FontMetrics();
//修改连接线字体⼤⼩
LABEL_FONT = new Font(this.labelFontName, 10, 15);
ANNOTATION_FONT = new Font(this.annotationFontName, 0, 11);
try {
USERTASK_IMAGE = Resource("org/flowable/icons/urTask.png", this.customClassLoader));
SCRIPTTASK_IMAGE = Resource("org/flowable/icons/scriptTask.png", this.customClassLoader));
SERVICETASK_IMAGE = Resource("org/flowable/icons/rviceTask.png", this.customClassLoader));
RECEIVETASK_IMAGE = Resource("org/flowable/icons/receiveTask.png", this.customClassLoader));
SENDTASK_IMAGE = Resource("org/flowable/icons/ndTask.png", this.customClassLoader));
MANUALTASK_IMAGE = Resource("org/flowable/icons/manualTask.png", this.customClassLoader));
BUSINESS_RULE_TASK_IMAGE = Resource("org/flowable/icons/businessRuleTask.png", this.customClassLoader)); SHELL_TASK_IMAGE = Resource("org/flowable/icons/shellTask.png", this.customClassLoader));
DMN_TASK_IMAGE = Resource("org/flowable/icons/dmnTask.png", this.customClassLoader));
CAMEL_TASK_IMAGE = Resource("org/flowable/icons/camelTask.png", this.customClassLoader));
MULE_TASK_IMAGE = Resource("org/flowable/icons/muleTask.png", this.customClassLoader));
HTTP_TASK_IMAGE = Resource("org/flowable/icons/httpTask.png", this.customClassLoader));
TIMER_IMAGE = Resource("org/flowable/icons/timer.png", this.customClassLoader));
COMPENSATE_THROW_IMAGE = Resource("org/flowable/icons/compensate-throw.png", this.customClassLoader)); COMPENSATE_CATCH_IMAGE = R
esource("org/flowable/icons/compensate.png", this.customClassLoader));
ERROR_THROW_IMAGE = Resource("org/flowable/icons/error-throw.png", this.customClassLoader));
ERROR_CATCH_IMAGE = Resource("org/flowable/icons/error.png", this.customClassLoader));
MESSAGE_THROW_IMAGE = Resource("org/flowable/icons/message-throw.png", this.customClassLoader));
MESSAGE_CATCH_IMAGE = Resource("org/flowable/icons/message.png", this.customClassLoader));
SIGNAL_THROW_IMAGE = Resource("org/flowable/icons/signal-throw.png", this.customClassLoader));
SIGNAL_CATCH_IMAGE = Resource("org/flowable/icons/signal.png", this.customClassLoader));
} catch (IOException var4) {
LOGGER.warn("Could not load image for process diagram creation: {}", Message());
}
}
//设置连接线字体
@Override
public void drawLabel(String text, GraphicInfo graphicInfo, boolean centered) {
float interline = 1.0f;
// text
if (text != null && text.length() > 0) {
Paint originalPaint = g.getPaint();
Font originalFont = g.getFont();
g.tPaint(LABEL_COLOR);
g.tFont(LABEL_FONT);
int wrapWidth = 100;
int textY = (int) Y();
// TODO: u drawMultilineText()
AttributedString as = new AttributedString(text);
as.addAttribute(TextAttribute.FOREGROUND, g.getPaint());
as.addAttribute(TextAttribute.FONT, g.getFont());
AttributedCharacterIterator aci = as.getIterator();
FontRenderContext frc = new FontRenderContext(null, true, fal);
LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
while (Position() < text.length()) {
TextLayout tl = Layout(wrapWidth);
textY += tl.getAscent();
Rectangle2D bb = tl.getBounds();
double tX = X();
if (centered) {
tX += (int) (Width() / 2 - bb.getWidth() / 2);
}
tl.draw(g, (float) tX, textY);
textY += tl.getDescent() + tl.getLeading() + (interline - 1.0f) * tl.getAscent();
}
/
/ restore originals
g.tFont(originalFont);
g.tPaint(originalPaint);