项目一:简单计算器的实现

article/2025/10/24 0:42:57
  1. 项目概述

1.1项目目标和主要内容

  1. 学习图形界 面的设计,利用 MFC 应用程序(Java swing 或 QT 框架,或 C#)创建基于对话框的应用程序,添加按钮、编辑框等控件;

  1. 能通过设计的按钮控件输入并实现简单算术运算,要求表达式在编辑框中显示,能将运算结果,输出在编辑框内显示;并保存历史的表达式运算记录。

  1. 也能够实现混合运算的算术表达式求解,算术表达式中包括加、减、乘、除、括号等运算符;并且能够识别括号,优先级正确。

1.2项目的主要功能

1)输入:允许输入带有括号的完整计算式(例 8*(4-95)+5÷2*e-pi)

2)输出:输出Double类型的结果

3)输出:整个运算表达式并保存于历史记录中

4)基本的加,减,乘,除,四则运算

5)平方运算

6)开方运算

7)求余运算

  1. 项目设计

2.1项目总体框架

2.2系统详细设计

  1. 创建一个Calculator类,继承JFrame框架,实现事件监听器接口

public class Calculator extends JFrame implements ActionListener

  1. 设置按键

int x = 20, y = 150;

for (int i = 0; i < KEYS.length; i++)

{

keys[i] = new JButton();

keys[i].setText(KEYS[i]);

keys[i].setBounds(x, y, 60, 40);

if (x < 215) {

x += 65;

}

else {

x = 20;

y += 45;

}

this.add(keys[i]);

}

for (int i = 0; i < KEYS.length; i++)// 每个按钮都注册事件监听器

{

keys[i].addActionListener(this);

}

this.setResizable(false);

this.setBounds(500, 200, 567, 480);

this.setDefaultCloseOperation(EXIT_ON_CLOSE);

this.setVisible(true);

}

  1. 事件处理

public void actionPerformed(ActionEvent e)

{

//History.setText(b);//使输入的表达式显示在历史记录文本框中

String label=e.getActionCommand();//获得事件源的标签

if(Objects.equals(label, "="))//

{

resultText.setText(this.b);

History.setText(History.getText()+resultText.getText());

if(label.equals("="))//调用计算方法,得出最终结果

{

String[] s = houzhui(this.b);

String result = Result(s);

this.b=result+"";

//更新文本框,当前结果在字符串b中,并未删除,下一次输入接着此结果以实现连续运算

resultText.setText(this.b);

History.setText(History.getText()+"="+resultText.getText()+"\n");

}

}

else if(Objects.equals(label, "AC"))//清空按钮,消除显示屏文本框前面所有的输入和结果

{

this.b="";

resultText.setText("0");//更新文本域的显示,显示初始值;

}

else if(Objects.equals(label, "sqrt"))

{

String n=kfys(this.b);

resultText.setText("sqrt"+"("+this.b+")");//使运算表达式显示在输入界面

History.setText(History.getText()+"sqrt"+"("+this.b+")"+"=");//获取输入界面的运算表达式并使其显示在历史记录文本框

this.b=n;

}

else if(Objects.equals(label, "x*x"))

{

String m=pfys(this.b);

resultText.setText(this.b+"^2");//使运算表达式显示在输入界面

History.setText(History.getText()+this.b+"^2"+"=");//获取输入界面的运算表达式并使其显示在历史记录文本框

this.b=m;

}

else if(Objects.equals(label, "e") || Objects.equals(label, "pi"))

{

if(label.equals("e"))

{

String m=String.valueOf(2.71828);//将e的值以字符串的形式传给m

this.b=this.b+m;//保留显示m之前输入的运算符或数字字符继续下一步运算

resultText.setText(this.b);

// History.setText(History.getText()+this.b);

}

if(label.equals("pi"))

{

String m=String.valueOf(3.14159265);

this.b=this.b+m;

resultText.setText(this.b);

// History.setText(History.getText()+this.b);

}

}

else

{

this.b=this.b+label;

resultText.setText(this.b);

// History.setText(History.getText()+this.b);

}}

  1. 将中缀表达式转换为后缀表达式

private String[] houzhui(String str) {

String s = "";// 用于承接多位数的字符串

char[] opStack = new char[100];// 静态栈,对用户输入的操作符进行处理,用于存储运算符

String[] postQueue = new String[100];// 后缀表达式字符串数组,为了将多位数存储为独立的字符串

int top = -1, j = 0;// 静态指针top,控制变量j

for (int i = 0; i < str.length(); i++)// 遍历中缀表达式

// indexof函数,返回字串首次出现的位置;charAt函数返回index位置处的字符;

{

if ("0123456789.".indexOf(str.charAt(i)) >= 0) // 遇到数字字符的情况直接入队

{

s = "";// 作为承接字符,每次开始时都要清空

for (; i < str.length() && "0123456789.".indexOf(str.charAt(i)) >= 0; i++) {

s = s + str.charAt(i);

//比如,中缀表达式:234+4*2,我们扫描这个字符串的时候,s的作用相当于用来存储长度为3个字符的操作数:234

}

i--;

postQueue[j] = s;// 数字字符直接加入后缀表达式

j++;

}

else if ("(".indexOf(str.charAt(i)) >= 0) {// 遇到左括号

top++;

opStack[top] = str.charAt(i);// 左括号入栈

}

else if (")".indexOf(str.charAt(i)) >= 0) {// 遇到右括号

for (;;)// 栈顶元素循环出栈,直到遇到左括号为止

{

if (opStack[top] != '(') {// 栈顶元素不是左括号

postQueue[j] = opStack[top] + "";// 栈顶元素出栈

j++;

top--;

} else { // 找到栈顶元素是左括号

top--;// 删除栈顶左括号

break;// 循环结束

}

}

}

else if ("*%/+-".indexOf(str.charAt(i)) >= 0)// 遇到运算符

{

if (top == -1)

{// 若栈为空则直接入栈

top++;

opStack[top] = str.charAt(i);

}

else if ("*%/".indexOf(opStack[top]) >= 0)

{// 当栈顶元素为高优先级运算符时,让栈顶元素出栈进入后缀表达式后,当前运算符再入栈

postQueue[j] = opStack[top] + "";

j++;

opStack[top] = str.charAt(i);

}

else

{

top++;

opStack[top] = str.charAt(i);// 当前元素入栈

}

}

}

while (top != -1) {// 遍历结束后将栈中剩余元素依次出栈进入后缀表达式

postQueue[j] = opStack[top] + "";

j++;

top--;

}

return postQueue;

}

  1. 计算后缀表达式,并返回最终结果

public String Result(String[] str) {

String[] Result = new String[100];// 顺序存储的栈,数据类型为字符串

int Top = -1;// 静态指针Top

for (int i = 0; str[i] != null; i++) {

if ("+-*%/".indexOf(str[i]) < 0) { //遇到数字,直接入栈

Top++;

Result[Top] = str[i];

}

if ("+-*%/".indexOf(str[i]) >= 0)// 遇到运算符字符,将栈顶两个元素出栈计算并将结果返回栈顶

{

double x, y, n;

x = Double.parseDouble(Result[Top]);// 顺序出栈两个数字字符串,并转换为double类型

Top--;

y = Double.parseDouble(Result[Top]);

Top--;

if ("*".indexOf(str[i]) >= 0) {

n = y * x;

Top++;

Result[Top] = String.valueOf(n);// 将运算结果重新入栈

}

if ("/".indexOf(str[i]) >= 0)

{

if (x == 0)// 被除数不允许为0

{

String s = "error!";

return s;

} else {

n = y / x;

Top++;

Result[Top] = String.valueOf(n);// 将运算结果重新入栈

}

}

if ("%".indexOf(str[i]) >= 0)

{

if (x == 0)// 被除数不允许为0

{

String s = "error!";

return s;

} else {

n = y % x;

Top++;

Result[Top] = String.valueOf(n);// 将运算结果重新入栈

}

}

if ("-".indexOf(str[i]) >= 0) {

n = y - x;

Top++;

Result[Top] = String.valueOf(n);// 将运算结果重新入栈

}

if ("+".indexOf(str[i]) >= 0) {

n = y + x;

Top++;

Result[Top] = String.valueOf(n);// 将运算结果重新入栈

}

}

}

return Result[Top];// 返回最终结果

}

2.3关键算法分析

2.3.1中缀表达式转后缀表达式

规则:从左向右遍历中缀表达式

①:遇到数字字符,直接加入后缀表达式

②:遇到高优先级运算符,若栈为空直接入栈,若栈不为空,则将当前运算符与栈顶元素比较

比较1(栈顶元素也为高优先级运算符):栈顶元素出栈加入后缀表达式,当前运算符入栈。这样的操作使得栈中不会出现连续的高优先级运算符

比较2(栈顶元素为'('左括号):将当前元素入栈

比较3(栈顶元素为低优先级运算符):将当前元素入栈

③:遇到'('左括号,将左括号入栈

④:遇到')'右括号,将栈顶元素顺序出栈,直到栈顶元素为左括号,此时删去栈顶的左括号

⑤:遇到低优先级运算符,若栈为空直接入栈,若栈不为空,则将当前运算符与栈顶元素比较

比较1(栈顶元素也为低优先级运算符):栈顶元素出栈加入后缀表达式,当前运算符入栈。这样的操作使得栈中不会出现连续的低优先级运算符

比较2(栈顶元素为'('左括号):将当前运算符入栈

比较 3(栈顶元素为高优先级运算符):栈顶元素出栈加入后缀表达式,当前运算符入栈

2.3.2后缀表达式求值

·规则:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。

·举例说明

1. 初始化一个空栈。此桟用来对要运算的数字进出使用。

2. 后缀表达式中前三个都是数字,所以9、3、1进栈。

3. 接下来是减号“-”,所以将栈中的1出栈作为减数,3出栈作为被减数,并运算3-1得到2,再将2进栈。

4. 接着是数字3进栈。

5. 后面是乘法“*”,也就意味着栈中3和2出栈,2与3相乘,得到6,并将6进栈。

6. 下面是加法“+”,所以找中6和9出找,9与6相加,得到15,将15进栈。

7. 接着是10与2两数字进栈。

8. 接下来是符号因此,栈顶的2与10出栈,10与2相除,得到5,将5进栈。

9. 最后一个是符号“+”,所以15与5出找并相加,得到20,将20进栈。

10. 结果是20出栈,栈变为空。

2.3.3用户界面输入的容错机制

1)开头不允许是"+×÷) . ";

2)"."不允许跟在运算符和"."之后;

3) "+×÷)"不能跟在"+×÷("之后;

4)"("不能跟在") ."之后;

  1. 项目实现及结果分析

1)计算器界面展示:

2)无法用图片展现的功能:

① 开头不能为小数点、运算符、右括号;

② 按下×÷+后若想切换为另一个运算符,直接再次按下便可直接切换;

③ 输入右括号后,下一个将无法输入小数点、左括号或数字;

④ 输入小数点后,下一个将无法输入小数点、运算符、括号;

⑤ 按下⬅按钮可以删除一个数字或一个运算符;

⑥ 按下C按钮可以将计算器清零,但历史记录不清空;

⑦ 按下History可以展现上一次的历史记录;

⑧ 按下等于号时,表达式也不能为空,最后一个字符不能是"+-×÷. ("。

⑨ 当刚计算完一个算式或正在查看历史记录时,无需清空计算器,直接按下任意数字便可开始下一轮运算。

  1. 实验总结

  1. 进行平方,开方运算时,结果文本框提前计算,历史记录文本框内容重复。

2)检测用户输入的容错机制。

3)为方便小数、多位数、负数的运算,写一个函数将原始中缀表达式中的数字用字母来对应,并存入字典中,转成后缀表达式开始求值时再取出对应数值进行计算。

源代码:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Objects;import javax.swing.*;//Calculator类,继承JFrame框架,实现事件监听器接口
public class Calculator extends JFrame implements ActionListener {private final String[] KEYS = { "7", "8", "9", "AC", "4", "5", "6", "-", "1", "2", "3", "+", "0", "e", "pi", "/", "sqrt","%", "x*x", "*", "(", ")", ".", "=" };private JButton keys[] = new JButton[KEYS.length];private JTextArea resultText = new JTextArea("0");// 文本域组件TextArea可容纳多行文本;文本框内容初始值设为0private JTextArea History = new JTextArea();// 历史记录文本框初始值设为空private JPanel jp2=new JPanel();private JScrollPane gdt1=new JScrollPane(resultText);//给输入显示屏文本域新建一个垂直滚动滑条private JScrollPane gdt2=new JScrollPane(History);//给历史记录文本域新建一个垂直滚动滑条//private JScrollPane gdt3=new JScrollPane(History);//给历史记录文本域新建一个水平滚动滑条private JLabel label = new JLabel("历史记录");private String b = "";// 构造方法public Calculator() {super("Caculator");//“超”关键字,表示调用父类的构造函数,resultText.setBounds(20, 18, 255, 115);// 设置文本框大小resultText.setAlignmentX(RIGHT_ALIGNMENT);// 文本框内容右对齐resultText.setEditable(false);// 文本框不允许修改结果History.setBounds(290, 40, 250,370);// 设置文本框大小History.setAlignmentX(LEFT_ALIGNMENT);// 文本框内容右对齐History.setEditable(false);// 文本框不允许修改结果label.setBounds(300, 15, 100, 20);//设置标签位置及大小jp2.setBounds(290,40,250,370);//设置面板窗口位置及大小jp2.setLayout(new GridLayout());JPanel jp1 = new JPanel();jp1.setBounds(20,18,255,115);//设置面板窗口位置及大小jp1.setLayout(new GridLayout());resultText.setLineWrap(true);// 激活自动换行功能resultText.setWrapStyleWord(true);// 激活断行不断字功能resultText.setSelectedTextColor(Color.RED);History.setLineWrap(true);//自动换行History.setWrapStyleWord(true);History.setSelectedTextColor(Color.blue);gdt1.setViewportView(resultText);//使滚动条显示出来gdt2.setViewportView(History);gdt1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//设置让垂直滚动条一直显示gdt2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//设置让垂直滚动条一直显示gdt2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);//设置让水平滚动条一直显示jp1.add(gdt1);//将滚动条添加入面板窗口中jp2.add(gdt2);this.add(jp1);//将面板添加到总窗体中this.add(jp2);//将面板添加到总窗体中this.setLayout(null);this.add(label);// 新建“历史记录”标签//this.add(resultText);// 新建文本框,该语句会添加进去一个新的JTextArea导致带有滚动条的文本无法显示或者发生覆盖//this.add(History);// 新建历史记录文本框,该语句会添加进去一个新的JTextArea导致带有滚动条的文本无法显示// 放置按钮int x = 20, y = 150;for (int i = 0; i < KEYS.length; i++){keys[i] = new JButton();keys[i].setText(KEYS[i]);keys[i].setBounds(x, y, 60, 40);if (x < 215) {x += 65;}else {x = 20;y += 45;}this.add(keys[i]);}for (int i = 0; i < KEYS.length; i++)// 每个按钮都注册事件监听器{keys[i].addActionListener(this);}this.setResizable(false);this.setBounds(500, 200, 567, 480);this.setDefaultCloseOperation(EXIT_ON_CLOSE);this.setVisible(true);}// 事件处理public void actionPerformed(ActionEvent e){//History.setText(b);//使输入的表达式显示在历史记录文本框中String label=e.getActionCommand();//获得事件源的标签if(Objects.equals(label, "="))//{resultText.setText(this.b);History.setText(History.getText()+resultText.getText());if(label.equals("="))//调用计算方法,得出最终结果{String[] s = houzhui(this.b);String result = Result(s);this.b=result+"";//更新文本框,当前结果在字符串b中,并未删除,下一次输入接着此结果以实现连续运算resultText.setText(this.b);History.setText(History.getText()+"="+resultText.getText()+"\n");}}else if(Objects.equals(label, "AC"))//清空按钮,消除显示屏文本框前面所有的输入和结果{this.b="";resultText.setText("0");//更新文本域的显示,显示初始值;}else if(Objects.equals(label, "sqrt")){String n=kfys(this.b);resultText.setText("sqrt"+"("+this.b+")");//使运算表达式显示在输入界面History.setText(History.getText()+"sqrt"+"("+this.b+")"+"=");//获取输入界面的运算表达式并使其显示在历史记录文本框this.b=n;}else if(Objects.equals(label, "x*x")){String m=pfys(this.b);resultText.setText(this.b+"^2");//使运算表达式显示在输入界面History.setText(History.getText()+this.b+"^2"+"=");//获取输入界面的运算表达式并使其显示在历史记录文本框this.b=m;}else if(Objects.equals(label, "e") || Objects.equals(label, "pi")){if(label.equals("e")){String m=String.valueOf(2.71828);//将e的值以字符串的形式传给mthis.b=this.b+m;//保留显示m之前输入的运算符或数字字符继续下一步运算resultText.setText(this.b);// History.setText(History.getText()+this.b);}if(label.equals("pi")){String m=String.valueOf(3.14159265);this.b=this.b+m;resultText.setText(this.b);// History.setText(History.getText()+this.b);}}else{this.b=this.b+label;resultText.setText(this.b);// History.setText(History.getText()+this.b);}//History.setText(History.getText()+this.b);//使输入的表达式显示在历史记录文本框中}//将中缀表达式转换为后缀表达式private String[] houzhui(String str) {String s = "";// 用于承接多位数的字符串char[] opStack = new char[100];// 静态栈,对用户输入的操作符进行处理,用于存储运算符String[] postQueue = new String[100];// 后缀表达式字符串数组,为了将多位数存储为独立的字符串int top = -1, j = 0;// 静态指针top,控制变量jfor (int i = 0; i < str.length(); i++)// 遍历中缀表达式// indexof函数,返回字串首次出现的位置;charAt函数返回index位置处的字符;{if ("0123456789.".indexOf(str.charAt(i)) >= 0) // 遇到数字字符的情况直接入队{s = "";// 作为承接字符,每次开始时都要清空for (; i < str.length() && "0123456789.".indexOf(str.charAt(i)) >= 0; i++) {s = s + str.charAt(i);//比如,中缀表达式:234+4*2,我们扫描这个字符串的时候,s的作用相当于用来存储长度为3个字符的操作数:234}i--;postQueue[j] = s;// 数字字符直接加入后缀表达式j++;}else if ("(".indexOf(str.charAt(i)) >= 0) {// 遇到左括号top++;opStack[top] = str.charAt(i);// 左括号入栈}else if (")".indexOf(str.charAt(i)) >= 0) {// 遇到右括号for (;;)// 栈顶元素循环出栈,直到遇到左括号为止{if (opStack[top] != '(') {// 栈顶元素不是左括号postQueue[j] = opStack[top] + "";// 栈顶元素出栈j++;top--;} else { // 找到栈顶元素是左括号top--;// 删除栈顶左括号break;// 循环结束}}}else if ("*%/+-".indexOf(str.charAt(i)) >= 0)// 遇到运算符{if (top == -1){// 若栈为空则直接入栈top++;opStack[top] = str.charAt(i);}else if ("*%/".indexOf(opStack[top]) >= 0){// 当栈顶元素为高优先级运算符时,让栈顶元素出栈进入后缀表达式后,当前运算符再入栈postQueue[j] = opStack[top] + "";j++;opStack[top] = str.charAt(i);}else{top++;opStack[top] = str.charAt(i);// 当前元素入栈}}}while (top != -1) {// 遍历结束后将栈中剩余元素依次出栈进入后缀表达式postQueue[j] = opStack[top] + "";j++;top--;}return postQueue;}//开方运算方法public String kfys(String str) {String result = "";double a = Double.parseDouble(str), b = 0;b = Math.sqrt(a);result = String.valueOf(b);//将运算结果转换为string类型并赋给string类型的变量resultreturn result;}//平方运算方法public String pfys(String str) {String result = "";double a = Double.parseDouble(str), b = 0;b = Math.pow(a, 2);result = String.valueOf(b);return result;}// 计算后缀表达式,并返回最终结果public String Result(String[] str) {String[] Result = new String[100];// 顺序存储的栈,数据类型为字符串int Top = -1;// 静态指针Topfor (int i = 0; str[i] != null; i++) {if ("+-*%/".indexOf(str[i]) < 0) {  //遇到数字,直接入栈Top++;Result[Top] = str[i];}if ("+-*%/".indexOf(str[i]) >= 0)// 遇到运算符字符,将栈顶两个元素出栈计算并将结果返回栈顶{double x, y, n;x = Double.parseDouble(Result[Top]);// 顺序出栈两个数字字符串,并转换为double类型Top--;y = Double.parseDouble(Result[Top]);Top--;if ("*".indexOf(str[i]) >= 0) {n = y * x;Top++;Result[Top] = String.valueOf(n);// 将运算结果重新入栈}if ("/".indexOf(str[i]) >= 0){if (x == 0)// 被除数不允许为0{String s = "error!";return s;} else {n = y / x;Top++;Result[Top] = String.valueOf(n);// 将运算结果重新入栈}}if ("%".indexOf(str[i]) >= 0){if (x == 0)// 被除数不允许为0{String s = "error!";return s;} else {n = y % x;Top++;Result[Top] = String.valueOf(n);// 将运算结果重新入栈}}if ("-".indexOf(str[i]) >= 0) {n = y - x;Top++;Result[Top] = String.valueOf(n);// 将运算结果重新入栈}if ("+".indexOf(str[i]) >= 0) {n = y + x;Top++;Result[Top] = String.valueOf(n);// 将运算结果重新入栈}}}return Result[Top];// 返回最终结果}// 主函数public static void main(String[] args) {Calculator a = new Calculator();}
}

http://chatgpt.dhexx.cn/article/ed5ay62i.shtml

相关文章

【C语言】实现简易计算器

目录 1.实现逻辑 2.运行过程 3.优化前代码分析 主函数 计算函数 4.优化后代码分析 主函数 计算方法函数 输入操作数的函数 5.完整代码展示 1.实现逻辑 实现一个简易的计算器&#xff0c;可以计算两个整数的加减乘除 2.运行过程 3.优化前代码分析 主函数 int main()…

java工作流引擎,roadflow(一个强大的工作流引擎)

JAVA工作流引擎(J-RoadFlow) J-RoadFlow工作流平台是知名的.NET工作流引擎RoadFlow的JAVA移植版。该工作流平台由从事多年OA和工作流实施及开发的团队研发&#xff0c; 采用最简单的SM架构实现大中小企业中日常复杂业务流程审批。JAVA版不仅仅是.NET版本的移植&#xff0c;从架…

Easy-Flows - Java的简单愚蠢的工作流引擎

The simple, stupid workflow engine for Java 源代码名称&#xff1a;easy-flows源代码网址&#xff1a;http://www.github.com/j-easy/easy-flowseasy-flows 源代码文档easy-flows 源代码下载 Git URL git://www.github.com/j-easy/easy-flows.git Git Clone 代码到本地 g…

Flowable工作流引擎

Flowable工作流引擎 Flowable-基础篇(根据BV1Pb4y1p7Ku整理) 一、简介 Flowable是BPMN的一个基于java的软件实现&#xff0c;不过Flowable不仅仅包括BPMN&#xff0c;还有DMN决策表和CMMN Case管理引擎&#xff0c;并且有自己的用户管理、微服务API等一系列功能&#xff0c;…

Java工作流引擎

Java工作流引擎有很多&#xff0c;有免费和商业的 主流免费&#xff1a;Activiti和Flowable Activiti和Flowable都是来自于一个叫JBPM的开源工作流。在早期Jboss发行JBPM4的时候&#xff0c;因为合作伙伴关系闹的不开心。于是其中一个核心人员离职。加入了Alfresco(Activiti所…

工作流引擎技术选型

一、主流开源框架介绍 1、工作流相关文档 1.Camunda 官方文档&#xff1a;https://camunda.com/ 中文文档&#xff1a;介绍 | docs.camunda.org 2.Activiti 官方文档&#xff1a;https://www.activiti.org/ 中文文档&#xff1a;[activiti6用户手册 3.Snaker 官方文档&…

Java开源工作流引擎 介绍

Java开源工作流引擎 http://www.open-open.com/08.htm 身为拿来主义者&#xff0c; 很好的吸取经验才是我们的目的&#xff01; Willow 由Huihoo Power开发详细可到其中文主页查看。 更多Willow信息 OpenWFE OpenWFE是一个开放源码的Java工作流引擎。它是一个完整的业务处理…

最近进行的一次技术选型(工作流引擎)及相关知识介绍

前言 最近有个新项目&#xff0c;需要实现类似工作流引擎的效果&#xff0c;如果不知道是啥&#xff0c;看完本文就懂了。 公司内其实也有些自研的&#xff0c;可能就是不像开源的这些那样&#xff0c;还支持这个那个规范&#xff0c;都是基于需求定制开发的&#xff0c;扩展…

java工作流引擎(j-roadflow)快速入门教程

使用j-roadflow java工作流引擎创建一个流程分为两个步骤&#xff0c;创建表单和创建流程。 一、创建表单。 在流程管理--表单管理下点新建表单即开始创建一个新的表单&#xff1a; 点击之后打开表单设计器并弹出表单属性设置&#xff1a; 表单名称&#xff1a;为您新建的表单…

为什么使用工作流引擎,什么是工作流引擎,工作流引擎选型以及如何使用

文章目录 为什么使用工作流引擎&#xff1f;不使用工作流存在以下问题工作流优缺点 什么是工作流引擎尝试自己构建工作流引擎有哪些选型方案呢基于bpmn标准进行流程定义国产自定义 如何使用SnakerFlow工作流以请假流程来看下数据库中数据流转情况初始状态员工发起请假申请 常见…

工作流引擎

1 绪论 【社会上的需求.】 1.1 课题的研究背景 工作流的概念起源于生产组织和办公自动化领域。它是针对日常工作中具有固定程序的活动而提出得一个概念。它的主要特点是使处理过程自动化&#xff0c;通过将工作分解成定义良好的任务、角色&#xff0c;按照一定的规则和过程来执…

LeaRun.Java工作流引擎 快速开发业务流程

工作流引擎是用来开发工作流转的框架。作为应用系统的一部分&#xff0c;能根据角色、分工和条件的不同决定信息传递路由、内容等级等核心解决方案&#xff0c;包含组织结构、流程、节点、转向规则等。 而低代码开发框架&#xff0c;是能够解决一个可以直接在后台配置就可以开…

IBPS java工作流引擎介绍

java工作流引擎是什么&#xff1f;看了这篇文章&#xff0c;相信80%的人都会明白的。IBPS低代码开发平台是近些年流辰信息的主打产品&#xff0c;实践证明&#xff0c;该产品推向市场后&#xff0c;得到了企业信息化部门、各高校、电力等企业的喜爱和支持。本文为大家着重介绍I…

Java开源工作流引擎有什么突出特点?

在高效办公需求日渐增长的当天&#xff0c;如何利用优质软件助力企业提升办公效率&#xff0c;是很多企业一直在寻觅的途径。Java开源工作流引擎可以借助其优势特点助力企业实现标准化发展&#xff0c;高效提高工作效率。那么&#xff0c;Java开源工作流引擎到底有什么用的突出…

后端web开发框架——Spring Boot

为什么使用Spring Boot 简化配置&#xff0c;无需编写太多的 xml 配置文件&#xff0c;效率很高&#xff1b;Spring 可以整合很多各式各样的框架&#xff0c;并能很好的集成&#xff1b;基于 Spring 构建&#xff0c;使开发者快速入门&#xff0c;门槛很低&#xff1b;Spring …

Web前端开发工具和框架

摘要&#xff1a;技术的快速发展让很多人学习起来无所适从&#xff0c;幸运的是&#xff0c;很多优秀的 Web 开发人员和设计人员在努力寻找各种有特色的解决方案。 因此&#xff0c;我们有了很多优秀的小工具和库&#xff0c;每一个都是用来解决特定的问题或维护一组特定的项目…

后端Web开发框架(Java)

本文节选自霍格沃兹测试学院内部教材 Spring Boot 是由 Pivotal 团队提供的全新框架&#xff0c;其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。讲的通俗一点就是 Spring …

Python中如何选择Web开发框架?

Python开发中Web框架可谓是百花齐放&#xff0c;各式各样的web框架层出不穷&#xff0c;那么对于需要进行Python开发的我们来说&#xff0c;如何选择web框架也就变成了一门学问了。本篇文章主要是介绍目前一些比较有特点受欢迎的Web框架&#xff0c;我们可以根据各个Web框架的特…

移动web开发框架研究

纯粹的总结一下移动web开发框架&#xff0c;移动web开发框架有jQuery Mobile 、Sencha Touch等等,他们都来源于web开发&#xff0c;是成熟的框架&#xff0c;jQuery Mobile出自于jQuery家族&#xff0c;Sencha Touch来自于ExtJS。jQuery Mobile 和Sencha Touch都是比较成熟老牌…

【Web开发】框架篇

前后端分离 为了适应技术和业务发展的需求&#xff0c;采用前后端分离的技术&#xff0c;前端应用和后端应用以JSON格式进行数据交互&#xff0c;采用的解决方案Spring Boot Vue。 单体——> 前端应用 后端应用 前端应用&#xff1a;负责数据展示和用户交互 后端应用&…