Thinking from the summary of the small calculator example

1. Design and thinking

1. If you don’t know, just ask.

I don’t know how you will deal with problems when you encounter them. I am used to figuring things out on my own first, and then looking up information to find answers based on the results. I often waste most of my time in this process, and often Taking a wrong path or taking a repetitive path that others have already walked.

That's why we have this subtitle - just ask if you don't know. There are really many "giants" around us. Ask the giants around you humbly, and don't dare to ask because of face or fear that your questions are too low-level. This is what the so-called "standing on the shoulders of giants" means. Our predecessors have laid a lot of foundations for us and explored many dark roads for us, so that we do not need to reinvent the wheel again. When you don’t understand, don’t understand, or your ideas are stuck, it’s better to humbly ask the “giants” around you for advice.

2. If the logic doesn’t make sense, draw a picture.

When I was young, my mother always taught me that "a good memory is worse than a bad writing", which meant that I should take more notes, put more things in my mind on paper, and clear my mind on time. The same thing happened today. After the teacher told me this small example, I kept thinking about how to implement it. I always looked at one thing and lost sight of the other. My consideration was not comprehensive enough, and the implementation plan was contradictory.

Until I implemented the ideas in my mind on the picture, I drew the first version of the flow chart based on my own thinking :
Insert image description here
Although the flow chart was output, there were still many places in it that could not be implemented in the code. So after discussing with the teacher, I came up with a second version of the flow chart :
Insert image description here
The second version of the flow chart here pays more attention to decoupling and code implementation. It divides the change of operation and the calculation result into two processes to sort out. Connections are made through objects.

Realization effect:
Please add image description

2. Code implementation

1. Specific code implementation

UI page:

package com.zwb.awtui;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;

/**
 * @program: zwbStudy
 * @description:
 * @author: 翟文彪
 * @create: 2022-06-02 10:07
 **/
public class UI {
    
    
    public static Operation opera;
    public static JLabel labelOperation;

    public static void main(String[] args) {
    
    
        // 创建窗口
        JFrame jf = new JFrame("运算器");
        jf.setLayout(new FlowLayout());
        jf.setBounds(400,300,400,500);

        // 运算符按钮集合
        List<JButton> jButtonList = new ArrayList<>();

        // 按钮(通过读取配置文件默认加载)
        // 读取配置文件
        Properties properties = new Properties();
        String pat = "D:\\JAVA\\zwbStudy\\src\\main\\resources\\application.properties";
        File file = new File(pat);
        try {
    
    
            FileInputStream fileOutputStream = null;
            if (file.getParentFile().exists()) {
    
    
                fileOutputStream = new FileInputStream(file);
            }
            properties.load(fileOutputStream);
            String config = properties.getProperty("button");

            List<String> buttonList = new ArrayList<>();
            // 使用字符串分词器将";"作为分隔符分隔各个按钮
            StringTokenizer subString = new StringTokenizer(config,";");
            // 循环存储到buttonList中
            while (subString.hasMoreTokens()){
    
    
                buttonList.add(subString.nextToken());
            }
            for (String button : buttonList) {
    
    
                // 根据配置文件中的全路径实例化对象,创建页面上的按钮
                Class<?> newButton = null;
                newButton = Class.forName(button);
                ButtonObject jButton = (ButtonObject)newButton.newInstance();
                jButtonList.add(jButton.creatButton());
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }

        JButton equalsButton = new JButton("=");
        equalsButton.setEnabled(true);

        // 输入框
        JTextField textA = new JTextField(5);
        JTextField textB = new JTextField(5);

        // 标签
        labelOperation = new JLabel();
        JLabel labelResult = new JLabel();

        // 运算器执行区域
        jf.add(textA);
        jf.add(labelOperation);
        jf.add(textB);
        jf.add(equalsButton);
        jf.add(labelResult);

        // 运算符库
        for (JButton jButton : jButtonList) {
    
    
            jf.add(jButton);
            // 各个运算符加载上运算符监听事件
            OperationClickAction cli = new OperationClickAction();
            jButton.addMouseListener(cli);
        }

        // 给等于按钮加载上等于按钮监听事件
        equalsButton.addActionListener(new ActionListener() {
    
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
    
                opera.setNumberA(Double.valueOf(textA.getText()));
                opera.setNumberB(Double.valueOf(textB.getText()));
                labelResult.setText(String.valueOf(opera.getResult()));
            }
        });

        jf.setVisible(true);
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}

Operator button abstract class and subclass:

package com.zwb.awtui;

import javax.swing.*;

/**
 * @program: zwbStudy
 * @description: 按钮
 * @author: 翟文彪
 * @create: 2022-06-10 15:09
 **/
public abstract class ButtonObject {
    
    
    protected abstract iFactory creatFactory();
    protected abstract JButton creatButton();
}

class ButtonAdd extends ButtonObject{
    
    
    @Override
    protected iFactory creatFactory() {
    
    
        return new Factory1();
    }
    @Override
    protected JButton creatButton() {
    
    
        JButton jButton = new JButton("+");
        jButton.setEnabled(true);
        return jButton;
    }
}

class ButtonSub extends ButtonObject{
    
    
    @Override
    protected iFactory creatFactory() {
    
    
        return new Factory2();
    }

    @Override
    protected JButton creatButton() {
    
    
        JButton jButton =  new JButton("-");
        jButton.setEnabled(true);
        return jButton;
    }
}

class ButtonMul extends ButtonObject{
    
    
    @Override
    protected iFactory creatFactory() {
    
    
        return new Factory3();
    }

    @Override
    protected JButton creatButton() {
    
    
        JButton jButton =  new JButton("*");
        jButton.setEnabled(true);
        return jButton;
    }
}
class ButtonDiv extends ButtonObject{
    
    
    @Override
    protected iFactory creatFactory() {
    
    
        return new Factory4();
    }

    @Override
    protected JButton creatButton() {
    
    
        JButton jButton =  new JButton("/");
        jButton.setEnabled(true);
        return jButton;
    }
}

Computational factory:

package com.zwb.awtui;

/**
 * @program: zwbStudy
 * @description: 运算工厂
 * @author: 翟文彪
 * @create: 2022-06-05 10:52
 **/
public interface iFactory {
    
    
    Operation createOperation();
}

class Factory1 implements iFactory{
    
    
    @Override
    public Operation createOperation() {
    
    
        return new OperationAdd();
    }
}

class Factory2 implements iFactory{
    
    
    @Override
    public Operation createOperation() {
    
    
        return new OperationSub();
    }
}

class Factory3 implements iFactory{
    
    
    @Override
    public Operation createOperation() {
    
    
        return new OperationMul();
    }
}

class Factory4 implements iFactory{
    
    
    @Override
    public Operation createOperation() {
    
    
        return new OperationDiv();
    }
}

Operator abstract classes and subclasses

package com.zwb.awtui;

/**
 * @program: zwbStudy
 * @description: 运算符抽象类与子类
 * @author: 翟文彪
 * @create: 2022-06-05 10:14
 **/
public abstract class Operation {
    
    
    private double numberA = 0;
    private double numberB = 0;

    public double getNumberA() {
    
    
        return numberA;
    }

    public void setNumberA(double numberA) {
    
    
        this.numberA = numberA;
    }

    public double getNumberB() {
    
    
        return numberB;
    }

    public void setNumberB(double numberB) {
    
    
        this.numberB = numberB;
    }

    public abstract double getResult();
}

class OperationAdd extends Operation {
    
    

    @Override
    public double getResult() {
    
    
        double result = 0;
        result = getNumberA() + getNumberB();
        return result;
    }
}

class OperationSub extends Operation {
    
    
    @Override
    public double getResult() {
    
    
        double result = 0;
        result = getNumberA() - getNumberB();
        return result;
    }
}

class OperationMul extends Operation {
    
    
    @Override
    public double getResult() {
    
    
        double result = 0;
        result = getNumberA() * getNumberB();
        return result;
    }
}

class OperationDiv extends Operation {
    
    
    @Override
    public double getResult() {
    
    
        double result = 0;
        try {
    
    
            if (getNumberB() == 0) {
    
    
                throw new Exception("除数不能为0");
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        result = getNumberA() / getNumberB();
        return result;
    }
}

Button event listening class

package com.zwb.awtui;

import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;

/**
 * @program: zwbStudy
 * @description: 按钮事件监听类
 * @author: 翟文彪
 * @create: 2022-06-10 14:40
 **/
public class OperationClickAction implements MouseListener {
    
    
    public static String operationText;

    @Override
    public void mouseClicked(MouseEvent mouseEvent) {
    
    
        //System.out.println("你点击的按钮名称为"+((JButton) (e.getSource())).getText());

        // 读取配置文件
        Properties properties = new Properties();
        String pat = "D:\\JAVA\\zwbStudy\\src\\main\\resources\\application.properties";
        File file = new File(pat);
        try {
    
    
            FileInputStream fileOutputStream = null;
            if (file.getParentFile().exists()) {
    
    
                fileOutputStream = new FileInputStream(file);
            }
            properties.load(fileOutputStream);
            String config = properties.getProperty(((JButton) (mouseEvent.getSource())).getText());
            // 根据配置文件中的全路径实例化对象,创建页面上的按钮
            Class<?> newButton = null;
            newButton = Class.forName(config);
            ButtonObject button = (ButtonObject) newButton.newInstance();
            // 创建对应的工厂对象
            iFactory factory = button.creatFactory();
            UI.opera = factory.createOperation();

            // 赋值给运算符文本
            UI.labelOperation.setText(((JButton) (mouseEvent.getSource())).getText());
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
    
    

    }

    @Override
    public void mouseReleased(MouseEvent e) {
    
    

    }

    @Override
    public void mouseEntered(MouseEvent e) {
    
    

    }

    @Override
    public void mouseExited(MouseEvent e) {
    
    

    }
}

2. Although your reflexes are good, don’t be greedy.

In the code I gave above, the initial operator button of the UI class (client class) is loaded onto the Frame by reading the full path of the class in the configuration file and reflection. Later, during the discussion with the teacher, I also It is understood that you can load buttons without using reflection, because we all know how many buttons need to be loaded. We only need to instantiate all subclass buttons included in the button class.

The biggest problem here is the abuse of reflection. Although we all know that reflection is very convenient and flexible, it has a gap in execution efficiency compared to direct instantiation operations, because reflection needs to read the contents of the configuration file and then Perform instantiation operations.

Therefore, although reflection is very convenient, you still need to pay attention to the scene and timing of use.

3. Summary and improvement

1. Technology improvement

(1) Learned and understood GUI programming in Java from the perspective of use, and also broadened knowledge in this area
(2) Flexible use of reflection, factory methods, and the relationship between classes can combine various objects. The coupling between

2. Improvement of thoughts

(1) When you encounter difficulties, you must ask for advice in time and learn to stand on the shoulders of giants.
(2) You must have an awareness of the overall situation and sort out the overall business and structure by drawing pictures. You will not get the correct answer if you look at the problem in isolation and locally. (3) What you think is not necessarily what you think, for
example In this small example, I couldn’t think of a suitable solution to meet the teacher’s needs at the beginning, but this does not mean that there is no such solution. Don't limit your thoughts. As long as you dare to think and do, you will definitely get results.

Guess you like

Origin blog.csdn.net/zwb568/article/details/125227942