Activiti6,java技术面试问题

tempMapList.add(map);

}

}

}

if (!CollectionUtils.isEmpty(tempMapList)) {

// 遍历匹配的集合,取得开始时间最早的一个

long earliestStamp = 0L;

String highLightedFlowId = null;

for (Map<String, Object> map : tempMapList) {

long highLightedFlowStartTime = Long.valueOf(map.get(“highLightedFlowStartTime”).toString());

if (earliestStamp == 0 || earliestStamp >= highLightedFlowStartTime) {

highLightedFlowId = map.get(“highLightedFlowId”).toString();

earliestStamp = highLightedFlowStartTime;

}

}

highLightedFlowIds.add(highLightedFlowId);

}

}

}

return highLightedFlowIds;

}

3.高亮正在进行中的节点+处理过的连接线+处理过的节点

在这里插入图片描述

// 获取流程中已经执行的节点,按照执行先后顺序排序

List historicActivityInstances = historyService.

createHistoricActivityInstanceQuery()

.processInstanceId(processInstanceId)

.orderByHistoricActivityInstanceId().asc().list();

// 高亮已经执行流程节点ID集合

List highLightedActivitiIds = new ArrayList<>();

for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {

highLightedActivitiIds.add(historicActivityInstance.getActivityId());

}

4.自定义商务范配色

绘图原理是调用下面的方法,扩展一波即可。

ProcessDiagramGenerator processDiagramGenerator = new DefaultProcessDiagramGenerator();

processDiagramGenerator.generateDiagram()

核心方法是,DefaultProcessDiagramGenerator.drawActivity 重写它吧

protected void drawActivity(DefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel,

FlowNode flowNode, List highLightedActivities, List highLightedFlows, double scaleFactor) {

在这里插入图片描述

全部代码如下:

涉及到2个类:

LakerProcessDiagramCanvas

继承了DefaultProcessDiagramCanvas

  • 重写定义了这2个值

HIGHLIGHT_COLOR = Color.cyan;// 默认颜色,之前是红色

THICK_TASK_BORDER_STROKE = new BasicStroke(6.0f);// 边框宽度 之前是3.0

  • 新定义了可以传入颜色的方法

public void drawHighLightColor(int x, int y, int width, int height, Color color) {

Paint originalPaint = g.getPaint();

Stroke originalStroke = g.getStroke();

g.setPaint(color);

g.setStroke(THICK_TASK_BORDER_STROKE);

RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20);

g.draw(rect);

g.setPaint(originalPaint);

g.setStroke(originalStroke);

}

LakerProcessDiagramGenerator

继承了DefaultProcessDiagramGenerator

  • 重写了initProcessDiagramCanvas让其返回我们扩展的LakerProcessDiagramCanvas

return new LakerProcessDiagramCanvas((int) maxX + 10, (int) maxY + 10, (int) minX, (int) minY,

imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);

  • 重写了drawActivity,最后一个节点自定义颜色显示

// 画高亮的节点 TODO

if (highLightedActivities.contains(flowNode.getId())) {

if (highLightedActivities.get(highLightedActivities.size() - 1).equalsIgnoreCase(flowNode.getId())) {

LakerProcessDiagramCanvas lakerProcessDiagramCanvas = ((LakerProcessDiagramCanvas) processDiagramCanvas);

lakerProcessDiagramCanvas.drawHighLightColor((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(), Color.YELLOW);

} else {

processDiagramCanvas.drawHighLight((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight());

}

}

全部源码
  • 继承DefaultProcessDiagramCanvas

package com.laker.workflow.controller;

import org.activiti.image.impl.DefaultProcessDiagramCanvas;

import java.awt.*;

import java.awt.geom.RoundRectangle2D;

public class LakerProcessDiagramCanvas extends DefaultProcessDiagramCanvas {

public LakerProcessDiagramCanvas(int width, int height, int minX, int minY, String imageType, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) {

super(width, height, minX, minY, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);

HIGHLIGHT_COLOR = Color.cyan;

THICK_TASK_BORDER_STROKE = new BasicStroke(6.0f);

}

public LakerProcessDiagramCanvas(int width, int height, int minX, int minY, String imageType) {

super(width, height, minX, minY, imageType);

HIGHLIGHT_COLOR = Color.cyan;

THICK_TASK_BORDER_STROKE = new BasicStroke(6.0f);

}

public void drawHighLightColor(int x, int y, int width, int height, Color color) {

Paint originalPaint = g.getPaint();

Stroke originalStroke = g.getStroke();

g.setPaint(color);

g.setStroke(THICK_TASK_BORDER_STROKE);

RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20);

g.draw(rect);

g.setPaint(originalPaint);

g.setStroke(originalStroke);

}

}

  • 继承DefaultProcessDiagramGenerator

package com.laker.workflow.controller;

import org.activiti.bpmn.model.Process;

import org.activiti.bpmn.model.*;

import org.activiti.image.impl.DefaultProcessDiagramCanvas;

import org.activiti.image.impl.DefaultProcessDiagramGenerator;

import java.awt.*;

import java.awt.image.BufferedImage;

import java.util.List;

public class LakerProcessDiagramGenerator extends DefaultProcessDiagramGenerator {

private BufferedImage processDiagram;

@Override

protected DefaultProcessDiagramCanvas generateProcessDiagram(BpmnModel bpmnModel, String imageType,

List highLightedActivities, List highLightedFlows,

String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor) {

{

prepareBpmnModel(bpmnModel);

DefaultProcessDiagramCanvas processDiagramCanvas = initProcessDiagramCanvas(bpmnModel, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);

// Draw pool shape, if process is participant in collaboration

for (Pool pool : bpmnModel.getPools()) {

GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());

processDiagramCanvas.drawPoolOrLane(pool.getName(), graphicInfo);

}

// Draw lanes

for (Process process : bpmnModel.getProcesses()) {

for (Lane lane : process.getLanes()) {

GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(lane.getId());

processDiagramCanvas.drawPoolOrLane(lane.getName(), graphicInfo);

}

}

// Draw activities and their sequence-flows

for (FlowNode flowNode : bpmnModel.getProcesses().get(0).findFlowElementsOfType(FlowNode.class)) {

drawActivity(processDiagramCanvas, bpmnModel, flowNode, highLightedActivities, highLightedFlows, scaleFactor);

}

for (Process process : bpmnModel.getProcesses()) {

for (FlowNode flowNode : process.findFlowElementsOfType(FlowNode.class)) {

drawActivity(processDiagramCanvas, bpmnModel, flowNode, highLightedActivities, highLightedFlows, scaleFactor);

}

}

// Draw artifacts

for (Process process : bpmnModel.getProcesses()) {

for (Artifact artifact : process.getArtifacts()) {

drawArtifact(processDiagramCanvas, bpmnModel, artifact);

}

List subProcesses = process.findFlowElementsOfType(SubProcess.class, true);

if (subProcesses != null) {

for (SubProcess subProcess : subProcesses) {

for (Artifact subProcessArtifact : subProcess.getArtifacts()) {

drawArtifact(processDiagramCanvas, bpmnModel, subProcessArtifact);

}

}

}

}

return processDiagramCanvas;

}

}

@Override

protected void drawActivity(DefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel,

FlowNode flowNode, List highLightedActivities, List highLightedFlows, double scaleFactor) {

{

ActivityDrawInstruction drawInstruction = activityDrawInstructions.get(flowNode.getClass());

if (drawInstruction != null) {

drawInstruction.draw(processDiagramCanvas, bpmnModel, flowNode);

// Gather info on the multi instance marker

boolean multiInstanceSequential = false, multiInstanceParallel = false, collapsed = false;

if (flowNode instanceof Activity) {

Activity activity = (Activity) flowNode;

MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics();

if (multiInstanceLoopCharacteristics != null) {

multiInstanceSequential = multiInstanceLoopCharacteristics.isSequential();

multiInstanceParallel = !multiInstanceSequential;

}

}

// Gather info on the collapsed marker

GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());

if (flowNode instanceof SubProcess) {

collapsed = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded();

} else if (flowNode instanceof CallActivity) {

collapsed = true;

}

if (scaleFactor == 1.0) {

// Actually draw the markers

processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(),

multiInstanceSequential, multiInstanceParallel, collapsed);

}

// 画高亮的节点 TODO

if (highLightedActivities.contains(flowNode.getId())) {

if (highLightedActivities.get(highLightedActivities.size() - 1).equalsIgnoreCase(flowNode.getId())) {

LakerProcessDiagramCanvas lakerProcessDiagramCanvas = ((LakerProcessDiagramCanvas) processDiagramCanvas);

lakerProcessDiagramCanvas.drawHighLightColor((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(), Color.YELLOW);

} else {

processDiagramCanvas.drawHighLight((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight());

}

}

}

// Outgoing transitions of activity

for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {

boolean highLighted = (highLightedFlows.contains(sequenceFlow.getId()));

String defaultFlow = null;

if (flowNode instanceof Activity) {

defaultFlow = ((Activity) flowNode).getDefaultFlow();

} else if (flowNode instanceof Gateway) {

defaultFlow = ((Gateway) flowNode).getDefaultFlow();

}

boolean isDefault = false;

if (defaultFlow != null && defaultFlow.equalsIgnoreCase(sequenceFlow.getId())) {

isDefault = true;

}

boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null && !(flowNode instanceof Gateway);

String sourceRef = sequenceFlow.getSourceRef();

String targetRef = sequenceFlow.getTargetRef();

FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef);

FlowElement targetElement = bpmnModel.getFlowElement(targetRef);

List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId());

if (graphicInfoList != null && graphicInfoList.size() > 0) {

graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList);

int xPoints[] = new int[graphicInfoList.size()];

int yPoints[] = new int[graphicInfoList.size()];

for (int i = 1; i < graphicInfoList.size(); i++) {

GraphicInfo graphicInfo = graphicInfoList.get(i);

GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1);

if (i == 1) {

xPoints[0] = (int) previousGraphicInfo.getX();

yPoints[0] = (int) previousGraphicInfo.getY();

}

xPoints[i] = (int) graphicInfo.getX();

yPoints[i] = (int) graphicInfo.getY();

}

processDiagramCanvas.drawSequenceflow(xPoints, yPoints, drawConditionalIndicator, isDefault, highLighted, scaleFactor);

// Draw sequenceflow label

GraphicInfo labelGraphicInfo = bpmnModel.getLabelGraphicInfo(sequenceFlow.getId());

if (labelGraphicInfo != null) {

processDiagramCanvas.drawLabel(sequenceFlow.getName(), labelGraphicInfo, false);

}

}

}

// Nested elements

if (flowNode instanceof FlowElementsContainer) {

for (FlowElement nestedFlowElement : ((FlowElementsContainer) flowNode).getFlowElements()) {

if (nestedFlowElement instanceof FlowNode) {

drawActivity(processDiagramCanvas, bpmnModel, (FlowNode) nestedFlowElement,

highLightedActivities, highLightedFlows, scaleFactor);

}

}

}

}

}

protected static DefaultProcessDiagramCanvas initProcessDiagramCanvas(BpmnModel bpmnModel, String imageType,

String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) {

// We need to calculate maximum values to know how big the image will be in its entirety

double minX = Double.MAX_VALUE;

double maxX = 0;

double minY = Double.MAX_VALUE;

double maxY = 0;

for (Pool pool : bpmnModel.getPools()) {

GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId());

minX = graphicInfo.getX();

maxX = graphicInfo.getX() + graphicInfo.getWidth();

minY = graphicInfo.getY();

maxY = graphicInfo.getY() + graphicInfo.getHeight();

}

List flowNodes = gatherAllFlowNodes(bpmnModel);

for (FlowNode flowNode : flowNodes) {

GraphicInfo flowNodeGraphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());

// width

if (flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth() > maxX) {

maxX = flowNodeGraphicInfo.getX() + flowNodeGraphicInfo.getWidth();

}

if (flowNodeGraphicInfo.getX() < minX) {

minX = flowNodeGraphicInfo.getX();

}

// height

if (flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight() > maxY) {

maxY = flowNodeGraphicInfo.getY() + flowNodeGraphicInfo.getHeight();

}

if (flowNodeGraphicInfo.getY() < minY) {

minY = flowNodeGraphicInfo.getY();

}

for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {

List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId());

if (graphicInfoList != null) {

for (GraphicInfo graphicInfo : graphicInfoList) {

// width

if (graphicInfo.getX() > maxX) {

maxX = graphicInfo.getX();

}

if (graphicInfo.getX() < minX) {

minX = graphicInfo.getX();

}

// height

if (graphicInfo.getY() > maxY) {

maxY = graphicInfo.getY();

}

if (graphicInfo.getY() < minY) {

minY = graphicInfo.getY();

}

}

}

}

}

List artifacts = gatherAllArtifacts(bpmnModel);

for (Artifact artifact : artifacts) {

GraphicInfo artifactGraphicInfo = bpmnModel.getGraphicInfo(artifact.getId());

if (artifactGraphicInfo != null) {

// width

if (artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth() > maxX) {

maxX = artifactGraphicInfo.getX() + artifactGraphicInfo.getWidth();

}

if (artifactGraphicInfo.getX() < minX) {

minX = artifactGraphicInfo.getX();

}

// height

if (artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight() > maxY) {

maxY = artifactGraphicInfo.getY() + artifactGraphicInfo.getHeight();

}

if (artifactGraphicInfo.getY() < minY) {

minY = artifactGraphicInfo.getY();

}

}

List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(artifact.getId());

if (graphicInfoList != null) {

for (GraphicInfo graphicInfo : graphicInfoList) {

// width

if (graphicInfo.getX() > maxX) {

maxX = graphicInfo.getX();

}

if (graphicInfo.getX() < minX) {

minX = graphicInfo.getX();

}

// height

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

最后

如果觉得本文对你有帮助的话,不妨给我点个赞,关注一下吧!

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

12134756365)]
[外链图片转存中…(img-mSkg75uQ-1712134756365)]
[外链图片转存中…(img-J6trToU2-1712134756365)]
[外链图片转存中…(img-BtTwpzJj-1712134756366)]
[外链图片转存中…(img-Ta89UpuU-1712134756366)]
[外链图片转存中…(img-20OMYcZa-1712134756366)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-CA2yDjIf-1712134756366)]

最后

如果觉得本文对你有帮助的话,不妨给我点个赞,关注一下吧!

[外链图片转存中…(img-QS4GJAEG-1712134756367)]

[外链图片转存中…(img-LfEGm8cN-1712134756367)]

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值