计算器类实现两个数的加、减、乘、除运算,并可以进行undo和redo操作

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

public class Calculator {

    private BigDecimal preTotal; // 前面累计计算值
    private BigDecimal newNum; // 新计算值
    private List<BigDecimal> lastNumList = new ArrayList<>(); // 最近系列操作值
    private List<String> lastOptList = new ArrayList<>(); // 最近系列操作
    private List<BigDecimal> lastTotalList = new ArrayList<>(); // 最近系列总值
    private String curOperator; // 当前操作符
    private int lastOptIndex = -1; // undo/redo最近操作索引
    private int scale = 2; // 默认精度2位小数
    private int validIndexMax = -1; // undo/redo有效索引最大值

    public BigDecimal getPreTotal() {
        return preTotal;
    }

    public void setPreTotal(BigDecimal preTotal) {
        this.preTotal = preTotal;
    }

    public BigDecimal getNewNum() {
        return newNum;
    }

    public void setNewNum(BigDecimal newNum) {
        if(preTotal == null){ // 未计算过,累计总值为第一个输入值
            preTotal = newNum;
        }else{
            this.newNum = newNum;
        }
    }

    public List<BigDecimal> getLastNumList() {
        return lastNumList;
    }

    public void setLastNumList(List<BigDecimal> lastNumList) {
        this.lastNumList = lastNumList;
    }

    public List<String> getLastOptList() {
        return lastOptList;
    }

    public void setLastOptList(List<String> lastOptList) {
        this.lastOptList = lastOptList;
    }

    public String getCurOperator() {
        return curOperator;
    }

    public void setCurOperator(String curOperator) {
        this.curOperator = curOperator;
    }

    public int getScale() {
        return scale;
    }

    public void setScale(int scale) {
        this.scale = scale;
    }

    public List<BigDecimal> getLastTotalList() {
        return lastTotalList;
    }

    public void setLastTotalList(List<BigDecimal> lastTotalList) {
        this.lastTotalList = lastTotalList;
    }

    public int getLastOptIndex() {
        return lastOptIndex;
    }

    public void setLastOptIndex(int lastOptIndex) {
        this.lastOptIndex = lastOptIndex;
    }

    public int getValidIndexMax() {
        return validIndexMax;
    }

    public void setValidIndexMax(int validIndexMax) {
        this.validIndexMax = validIndexMax;
    }

    /**
     *  计算,相当于计算器的等于按钮
     */
    public void calc(){
        preTotal = preTotal == null ? BigDecimal.ZERO : preTotal;
        if(curOperator == null){
            System.out.println("请选择操作!");
        }
        if(newNum != null){ // 新输入值
            // 累加计算
            BigDecimal ret = calcTwoNum(preTotal, curOperator, newNum);
            if(this.lastOptIndex == -1){ // 未处于redo/undo中间过程
                lastTotalList.add(preTotal);
                lastNumList.add(newNum);
                lastOptList.add(curOperator);
            }else{ // 处于redo/undo中间过程,覆盖undo/redo操作记录,并记录有效索引最大值
                this.lastOptIndex++;
                this.validIndexMax = this.lastOptIndex;
                this.lastTotalList.set(this.lastOptIndex, ret);
                this.lastNumList.set(this.lastOptIndex-1, newNum);
                this.lastOptList.set(this.lastOptIndex-1, curOperator);
            }
            preTotal = ret;
            curOperator = null;
            newNum = null;
        }
    }

    /**
     * 回撤到上一步
     */
    public void undo(){
        if(preTotal != null && lastOptIndex == -1){ // 未进行undo/redo操作,存储最后计算结果
            lastTotalList.add(preTotal);
            curOperator = null;
            newNum = null;
        }

        if(lastTotalList.size() == 0){
            System.out.println("无操作!");
        }else if(lastTotalList.size() == 1){
            System.out.println("undo后值:0,"+"undo前值:"+preTotal);
            preTotal = BigDecimal.ZERO;
        } else {
            if(lastOptIndex == -1){
                lastOptIndex = lastOptList.size()-1;
            }else{
                if(lastOptIndex-1 < 0){
                    System.out.println("无法再undo!");
                    return;
                }
                lastOptIndex--;
            }
            cancelPreOperate(lastTotalList.get(lastOptIndex),lastOptList.get(lastOptIndex), lastNumList.get(lastOptIndex));
        }
    }

    /**
     *  根据回撤进行重做
     */
    public void redo(){
        try{
            if(lastOptIndex > -1){
                if(lastOptIndex + 1 == lastTotalList.size() || lastOptIndex+1 == this.validIndexMax+1){
                    System.out.println("无法再redo!");
                    return;
                }
                lastOptIndex++;

                redoOperate(lastTotalList.get(lastOptIndex),lastOptList.get(lastOptIndex-1), lastNumList.get(lastOptIndex-1));
            }
        }catch (Exception e){
            System.out.println("redo异常,lastOptIndex:"+lastOptIndex);
        }
    }

    private void redoOperate(BigDecimal redoTotal, String redoOpt, BigDecimal redoNum) {
        System.out.println("redo后值:"+redoTotal+",redo前值:"+preTotal+",redo的操作:"+redoOpt+",redo操作的值:"+redoNum);
        preTotal = redoTotal;
        curOperator = null;
        newNum = null;
    }

    private void cancelPreOperate(BigDecimal lastTotal, String lastOpt, BigDecimal lastNum) {
        System.out.println("undo后值:"+lastTotal+",undo前值:"+preTotal+",undo的操作:"+lastOpt+",undo操作的值:"+lastNum);
        preTotal = lastTotal;
        curOperator = null;
        newNum = null;
    }

    /**
     * 进行累计计算
     * @param preTotal 前面已累计值
     * @param curOperator 当前操作
     * @param newNum 新输入值
     * @return 计算结果
     */
    private BigDecimal calcTwoNum(BigDecimal preTotal, String curOperator, BigDecimal newNum) {
        BigDecimal ret = BigDecimal.ZERO;
        curOperator = curOperator == null ? "+" : curOperator;
        switch (curOperator){
            case "+":
                ret = preTotal.add(newNum);
                break;
            case "-":
                ret = preTotal.subtract(newNum).setScale(scale, RoundingMode.HALF_UP);
                break;
            case "*":
                ret = preTotal.multiply(newNum).setScale(scale, RoundingMode.HALF_UP);
                break;
            case "/":
                ret = preTotal.divide(newNum, RoundingMode.HALF_UP);
                break;
        }
        return ret;
    }

    /**
     * 显示操作结果
     */
    public String display(){
        StringBuilder sb = new StringBuilder();
        if(preTotal != null){
            sb.append(preTotal.setScale(scale, BigDecimal.ROUND_HALF_DOWN).toString());
        }
        if(curOperator != null){
            sb.append(curOperator);
        }
        if(newNum != null){
            sb.append(newNum);
        }
        System.out.println(sb.toString());
        return sb.toString();
    }

    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        calculator.setNewNum(new BigDecimal(3));
        calculator.setCurOperator("+");
        calculator.setNewNum(new BigDecimal(5));
        calculator.display();
        calculator.calc();
        calculator.display();
        calculator.setCurOperator("*");
        calculator.setNewNum(new BigDecimal(2));
        calculator.display();
        calculator.calc();
        calculator.display();
        calculator.undo();
        calculator.display();

        System.out.println("开始打断undo并附加额外计算:+2");
        calculator.setCurOperator("+");
        calculator.setNewNum(new BigDecimal(2));
        calculator.display();
        calculator.calc();
        calculator.display();
        System.out.println("打断计算结束,重新进行undo/redo操作!");

        calculator.undo();
        calculator.display();
        calculator.undo();
        calculator.display();
        calculator.redo();
        calculator.display();
        calculator.redo();
        calculator.display();
        calculator.redo();
        calculator.display();
        calculator.redo();
        calculator.display();
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在Eclipse中,可以使用JFace的org.eclipse.jface.text包的undo/redo框架来实现对SWT组件的撤销/重做操作。以下是一个简单的示例代码,演示如何在Eclipse中对SWT Text组件进行撤销/重做操作: ```java import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextOperationTarget; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.TextViewerUndoManager; import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; public class SWTUndoRedoExample { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setLayout(new FillLayout()); // 创建SWT Text组件 Text text = new Text(shell, SWT.BORDER | SWT.MULTI); // 创建SourceViewer控件 SourceViewer viewer = new SourceViewer(shell, null, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); IDocument document = new Document(); viewer.setDocument(document); // 将SWT Text组件设置为Viewer的文本输入目标 ITextOperationTarget target = (ITextOperationTarget) viewer; target.setTargetEditor(text); // 创建撤销/重做管理器并将其设置为Viewer的撤销/重做管理器 TextViewerUndoManager undoManager = new TextViewerUndoManager(20); viewer.setUndoManager(undoManager); // 显示窗口 shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } } ``` 在上面的示例代码中,创建了一个SWT Text组件和一个SourceViewer控件,然后将SWT Text组件设置为Viewer的文本输入目标。接着创建了一个TextViewerUndoManager对象,并将其设置为Viewer的撤销/重做管理器。现在,当用户输入文本并按下Ctrl+Z或Ctrl+Y键时,就可以执行撤销/重做操作。 需要注意的是,撤销/重做操作只对文本输入产生影响。如果要在SWT组件中实现其他类型的撤销/重做操作,需要自己编写相应的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kenick

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值