首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >药房价格计算器(更新)

药房价格计算器(更新)
EN

Code Review用户
提问于 2022-07-21 20:44:38
回答 1查看 40关注 0票数 1

这是我一直在用的计算器的新代码。当我开始处理GUI时,我就放弃了多类文件的想法。只是想了解一下我是否做了什么奇怪或错误的事情。谢谢你的意见。该程序可以工作,但不确定它的效果或传统或任何东西。我计划把它变得更加可变,不同地点的税率也是可变的,所以我有更多的工作要做done...but,这就是我所得到的。

原始代码:这里

代码语言:javascript
复制
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;

public class Gui extends JFrame implements ActionListener {

static int pricePoint = 0;
static double desiredPrice = 0.0;
static double fivePerGram[] = { 5, 15, 25, 40, 80 };
static double eightPerGram[] = { 8, 25, 45, 85, 160 };
static double tenPerGram[] = { 10, 35, 65, 120, 225 };
static double weightFormat[] = { 1, 3.5, 7, 14, 28 };

static double maxWeight = 0;

static double gramPrice = 0;
static double eighthPrice = 0;
static double quarterPrice = 0;
static double halfPrice = 0;
static double ouncePrice = 0;

static double gramWeight = 0;
static double eighthWeight = 0;
static double quarterWeight = 0;
static double halfWeight = 0;
static double ounceWeight = 0;

static double breakpoint = 0;
static double neededGrams = 0;
static double newBreak = 0;
static double underDesired = 0;

JPanel topPanel = new JPanel();
JPanel leftPanel = new JPanel();
JPanel middlePanel = new JPanel();

static JTextField inputField = new JTextField();

JButton calculateButton = new JButton("Calculate");

JLabel inputLabel = new JLabel("Desired Price");
JLabel outputLabel = new JLabel("Grams Needed: ");
JLabel emptyLabel = new JLabel("");

static JLabel weightOutput = new JLabel("0");

static JRadioButton fiveButton = new JRadioButton("5 / g");
static JRadioButton eightButton = new JRadioButton("8 / g");
static JRadioButton tenButton = new JRadioButton("10 / g");

Gui() {
    this.setSize(420, 420);
    this.setVisible(true);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLayout(new BorderLayout());
    this.setResizable(false);

    ButtonGroup radioButtonGroup = new ButtonGroup();
    radioButtonGroup.add(fiveButton);
    radioButtonGroup.add(eightButton);
    radioButtonGroup.add(tenButton);

    fiveButton.setPreferredSize(new Dimension(90, 20));
    fiveButton.setBackground(Color.black);
    fiveButton.setForeground(Color.white);
    fiveButton.setFocusable(false);
    
    eightButton.setPreferredSize(new Dimension(90, 20));
    eightButton.setBackground(Color.black);
    eightButton.setForeground(Color.white);
    eightButton.setFocusable(false);
    
    tenButton.setPreferredSize(new Dimension(90, 20));
    tenButton.setBackground(Color.black);
    tenButton.setForeground(Color.white);
    tenButton.setFocusable(false);
    
    outputLabel.setBounds(125, 0, 200, 200);
    outputLabel.setFont(new Font("Comic Sams", Font.BOLD, 20));
    outputLabel.setForeground(Color.black);

    weightOutput.setHorizontalAlignment(JLabel.CENTER);
    weightOutput.setBounds(140, 130, 100, 100);
    weightOutput.setFont(new Font("Comic Sams", Font.BOLD, 40));
    weightOutput.setVisible(false);
    weightOutput.setForeground(Color.green);

    inputLabel.setPreferredSize(new Dimension(100, 30));
    inputLabel.setForeground(Color.white);
    inputLabel.setFont(new Font("Comic Sams", Font.BOLD, 11));
    inputLabel.setHorizontalAlignment(JLabel.CENTER);

    emptyLabel.setPreferredSize(new Dimension(50, 10));

    inputField.setPreferredSize(new Dimension(75, 20));
    inputField.setHorizontalAlignment(JTextField.CENTER);

    calculateButton.setFont(new Font("Comic Sams", Font.PLAIN, 10));
    calculateButton.setPreferredSize(new Dimension(75, 75));
    calculateButton.setFocusable(false);
    calculateButton.setMargin(new Insets(0, 0, 0, 0));
    calculateButton.addActionListener(this);

    topPanel.setBackground(Color.LIGHT_GRAY);
    topPanel.setPreferredSize(new Dimension(50, 50));

    leftPanel.setBackground(Color.black);
    leftPanel.setPreferredSize(new Dimension(100, 100));
    leftPanel.setLayout(new FlowLayout());
    leftPanel.add(calculateButton);
    leftPanel.add(inputLabel);
    leftPanel.add(inputField);
    leftPanel.add(emptyLabel);
    leftPanel.add(fiveButton);
    leftPanel.add(eightButton);
    leftPanel.add(tenButton);

    middlePanel.setBackground(Color.gray);
    middlePanel.setPreferredSize(new Dimension(370, 320));
    middlePanel.add(outputLabel);
    middlePanel.add(weightOutput);
    middlePanel.setLayout(null);

    this.add(topPanel, BorderLayout.NORTH);
    this.add(leftPanel, BorderLayout.WEST);
    this.add(middlePanel, BorderLayout.EAST);
    this.pack();
}

public static void main(String[] args) {

    Gui frame = new Gui();

}

public static double round(double value, int places) {
    if (places < 0)
        throw new IllegalArgumentException();

    BigDecimal bd = BigDecimal.valueOf(value);
    bd = bd.setScale(places, RoundingMode.HALF_UP);
    return bd.doubleValue();
}

public static double getDesired(int d) {
    double result = Double.valueOf(d);
    result /= 1.16;
    return result;
}

public static double getGramPrice(double input) {
    double result = 0;
    result = input / 1;
    result = round(result, 2);
    return result;
}

public static double getEighthPrice(double input) {
    double result = 0;
    result = input / 3.5;
    result = round(result, 2);
    return result;
}

public static double getQuarterPrice(double input) {
    double result = 0;
    result = input / 7;
    result = round(result, 2);
    return result;
}

public static double getHalfPrice(double input) {
    double result = 0;
    result = input / 14;
    result = round(result, 2);
    return result;
}

public static double getOuncePrice(double input) {
    double result = 0;
    result = input / 28;
    result = round(result, 2);
    return result;
}

public static double getBreakpoint(double input) {
    double result = 0;
    for (int i = 4; i >= 0; i--) {
        if (input < weightFormat[i]) {
            continue;
        } else if (input >= weightFormat[i]) {
            result = weightFormat[i];
            break;
        }
    }
    return result;
}

public static double getNeededGrams(double input) {
    double result = 0;
    for (int i = 0; i < 5; i++) {
        if (breakpoint == 1) {
            result = gramWeight;
            if (input > 1 && input <= 1.99) {
                underDesired = desiredPrice;
                underDesired *= 1.16;
                underDesired -= 1.28;
                result = underDesired / gramPrice;
            }
            break;
        }
        if (breakpoint == 3.5) {
            result = eighthWeight;
            break;
        }
        if (breakpoint == 7) {
            result = quarterWeight;
            break;
        }
        if (breakpoint == 14) {
            result = halfWeight;
            break;
        }
        if (breakpoint == 28) {
            result = ounceWeight;
            break;
        }
    }

    if (neededGrams < breakpoint) {
        for (int i = 4; i >= 0; i--) {
            if (result < weightFormat[i]) {
                continue;
            } else if (result >= weightFormat[i]) {
                newBreak = weightFormat[i];
                break;
            }
        }

        for (int i = 0; i < 5; i++) {
            if (newBreak == 1) {
                result = gramWeight;
                if (result > 1 && result <= 1.99) {
                    underDesired = desiredPrice;
                    underDesired *= 1.16;
                    underDesired -= 1.28;
                    result = underDesired / gramPrice;
                }
                break;
            }
            if (newBreak == 3.5) {
                result = eighthWeight;
                break;
            }
            if (newBreak == 7) {
                result = quarterWeight;
                break;
            }
            if (newBreak == 14) {
                result = halfWeight;
                break;
            }
            if (newBreak == 28) {
                result = ounceWeight;
                break;
            }
        }
    }
    return result;

}

public static double getWeight(int input) {
    double result = 0;
    if (input == 5) {

        gramWeight = (desiredPrice / getGramPrice(fivePerGram[0]));
        eighthWeight = (desiredPrice / getEighthPrice(fivePerGram[1]));
        quarterWeight = (desiredPrice / getQuarterPrice(fivePerGram[2]));
        halfWeight = (desiredPrice / getHalfPrice(fivePerGram[3]));
        ounceWeight = (desiredPrice / getOuncePrice(fivePerGram[4]));

        double weightList[] = { gramWeight, eighthWeight, quarterWeight, halfWeight, ounceWeight };

        maxWeight = Arrays.stream(weightList).max().getAsDouble();
        maxWeight = round(maxWeight, 2);

        breakpoint = getBreakpoint(maxWeight);

        neededGrams = getNeededGrams(breakpoint);

    }

    if (input == 8) {

        gramWeight = (desiredPrice / getGramPrice(eightPerGram[0]));
        eighthWeight = (desiredPrice / getEighthPrice(eightPerGram[1]));
        quarterWeight = (desiredPrice / getQuarterPrice(eightPerGram[2]));
        halfWeight = (desiredPrice / getHalfPrice(eightPerGram[3]));
        ounceWeight = (desiredPrice / getOuncePrice(eightPerGram[4]));

        double weightList[] = { gramWeight, eighthWeight, quarterWeight, halfWeight, ounceWeight };

        double maxWeight = Arrays.stream(weightList).max().getAsDouble();
        maxWeight = round(maxWeight, 2);

        breakpoint = getBreakpoint(maxWeight);

        neededGrams = getNeededGrams(breakpoint);

    }

    if (input == 10) {

        gramWeight = (desiredPrice / getGramPrice(tenPerGram[0]));
        eighthWeight = (desiredPrice / getEighthPrice(tenPerGram[1]));
        quarterWeight = (desiredPrice / getQuarterPrice(tenPerGram[2]));
        halfWeight = (desiredPrice / getHalfPrice(tenPerGram[3]));
        ounceWeight = (desiredPrice / getOuncePrice(tenPerGram[4]));

        double weightList[] = { gramWeight, eighthWeight, quarterWeight, halfWeight, ounceWeight };

        double maxWeight = Arrays.stream(weightList).max().getAsDouble();
        maxWeight = round(maxWeight, 2);

        breakpoint = getBreakpoint(maxWeight);

        neededGrams = getNeededGrams(breakpoint);

    }

    return result;
}

@Override
public void actionPerformed(ActionEvent e) {
    
    desiredPrice = getDesired(Integer.parseInt(inputField.getText()));
    if (fiveButton.isSelected()) {
        pricePoint = 5;
    }
    if (eightButton.isSelected()) {
        pricePoint = 8;
    }
    if (tenButton.isSelected()) {
        pricePoint = 10;
    }

    getWeight(pricePoint);

    weightOutput.setText(Double.toString(round(neededGrams, 2)));
    weightOutput.setVisible(true);

}

}
EN

回答 1

Code Review用户

发布于 2022-07-22 02:41:47

我放弃了多类文件的概念

这和你应该去的方向正好相反。例如,您的动作侦听器类、GUI类和业务逻辑应该互不相关。

总的来说,你在这里所做的会计操作是相当复杂的,而且实现起来比需要的要复杂得多。它是如此难以理解,以至于我无法与其中的大多数人交谈,不得不逐字翻译。

您不应该将fivePereightPer等数组分开。这可以是一个单一的二维数组(三乘五)。

几乎所有的GUI元素变量都不应该是类成员,而应该是本地的。

不要依赖空标签来修改布局。

也许你想知道为什么你的字体不能工作。这是连环画桑斯,不是连环画。(我正在考虑把这个留给自己,以免你的用户有眼珠子;唉。)

您的weightOutput宽度是有问题的--当有足够的空间时,您不必要地使用较长的字符串。

代码中有大量的重复和冗余;例如,请参见getHalfPrice和系列代码,它们基本上都是做相同的事情。相反,您应该依赖于weightFormat中的索引来改变除数。

我不认为在你的财务状况中期进行round()是明智的,你只应该在最后才表现出来。

你的许多变量和函数名都需要爱。例如,getDesired实际上是否计入了税收?因为它看起来就是这样的。

getNeededGrams特别麻烦:input总是等于breakpoint,所以这里的内部条件是:

代码语言:javascript
复制
    if (breakpoint == 1) {
        result = gramWeight;
        if (input > 1 && input <= 1.99) {

据我所知,永远不会是真的。这将整个函数简化为一个数组查找。

考虑重新处理您的UI,这样就没有计算按钮,并且每当控件更改时,输出都会被刷新。

建议

这是不全面的,只是第一步。结果与您的基本相同,但中间舍入误差较小。

Gui.java

代码语言:javascript
复制
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;

public class Gui extends JFrame {
    private final JTextField inputField = new JTextField();

    private final JLabel weightOutput = new JLabel("0");

    private final ButtonGroup radioButtonGroup = new ButtonGroup();


    public Gui() {
        this.setSize(420, 420);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout(new BorderLayout());
        this.setResizable(false);

        JPanel
            topPanel = new JPanel(),
            leftPanel = new JPanel(),
            middlePanel = new JPanel();

        JLabel inputLabel = new JLabel("Desired Price"),
            outputLabel = new JLabel("Grams Needed: ");

        JRadioButton
            fiveButton = new JRadioButton("5 / g"),
            eightButton = new JRadioButton("8 / g"),
            tenButton = new JRadioButton("10 / g");

        radioButtonGroup.add(fiveButton);
        radioButtonGroup.add(eightButton);
        radioButtonGroup.add(tenButton);

        ChangeListener radioChanges = new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent changeEvent) {
                onChange();
            }
        };

        fiveButton.setPreferredSize(new Dimension(90, 20));
        fiveButton.setBackground(Color.black);
        fiveButton.setForeground(Color.white);
        fiveButton.setFocusable(false);
        fiveButton.setActionCommand("5");
        fiveButton.setSelected(true);
        fiveButton.addChangeListener(radioChanges);

        eightButton.setPreferredSize(new Dimension(90, 20));
        eightButton.setBackground(Color.black);
        eightButton.setForeground(Color.white);
        eightButton.setFocusable(false);
        eightButton.setActionCommand("8");
        eightButton.addChangeListener(radioChanges);

        tenButton.setPreferredSize(new Dimension(90, 20));
        tenButton.setBackground(Color.black);
        tenButton.setForeground(Color.white);
        tenButton.setFocusable(false);
        tenButton.setActionCommand("10");
        tenButton.addChangeListener(radioChanges);

        outputLabel.setBounds(125, 0, 200, 200);
        outputLabel.setFont(new Font("Comic Sans", Font.BOLD, 20));
        outputLabel.setForeground(Color.black);

        weightOutput.setHorizontalAlignment(JLabel.CENTER);
        weightOutput.setBounds(140, 130, 200, 100);
        weightOutput.setFont(new Font("Comic Sans", Font.BOLD, 40));
        weightOutput.setVisible(false);
        weightOutput.setForeground(Color.green);

        inputLabel.setPreferredSize(new Dimension(100, 30));
        inputLabel.setForeground(Color.white);
        inputLabel.setFont(new Font("Comic Sans", Font.BOLD, 11));
        inputLabel.setHorizontalAlignment(JLabel.CENTER);

        DocumentListener listener = new DocumentListener() {
            @Override public void insertUpdate(DocumentEvent e) { onChange(); }
            @Override public void removeUpdate(DocumentEvent e) { onChange(); }
            @Override public void changedUpdate(DocumentEvent e) { onChange(); }
        };

        inputField.setPreferredSize(new Dimension(75, 20));
        inputField.setHorizontalAlignment(JTextField.CENTER);
        inputField.getDocument().addDocumentListener(listener);

        topPanel.setBackground(Color.LIGHT_GRAY);
        topPanel.setPreferredSize(new Dimension(50, 50));

        leftPanel.setBackground(Color.black);
        leftPanel.setPreferredSize(new Dimension(100, 100));
        leftPanel.setLayout(new FlowLayout());
        leftPanel.add(inputLabel);
        leftPanel.add(inputField);
        leftPanel.add(fiveButton);
        leftPanel.add(eightButton);
        leftPanel.add(tenButton);

        middlePanel.setBackground(Color.gray);
        middlePanel.setPreferredSize(new Dimension(370, 320));
        middlePanel.add(outputLabel);
        middlePanel.add(weightOutput);
        middlePanel.setLayout(null);

        this.add(topPanel, BorderLayout.NORTH);
        this.add(leftPanel, BorderLayout.WEST);
        this.add(middlePanel, BorderLayout.EAST);
        this.pack();
    }

    public static void main(String[] args) {
        new Gui();
    }

    public static double round(double value, int places) {
        if (places < 0)
            throw new IllegalArgumentException();

        BigDecimal bd = BigDecimal.valueOf(value);
        bd = bd.setScale(places, RoundingMode.HALF_UP);
        return bd.doubleValue();
    }

    public void onChange() {
        try {
            double price = Double.parseDouble(inputField.getText());

            int pricePoint = Integer.parseInt(
                radioButtonGroup.getSelection().getActionCommand()
            );

            Order order = new Order(price, pricePoint);

            weightOutput.setText(Double.toString(round(order.neededWeight, 2)));
            weightOutput.setVisible(true);
        }
        catch (Exception e) {
            weightOutput.setVisible(false);
        }
    }
}

Order.java

代码语言:javascript
复制
import java.util.Arrays;
import java.util.List;


/*
Selected example output

      4     20       100     200     999

5    .69    4.02     30.17   60.34   301.42

8     -     2.16     14.2    30.17   150.71

10    -     1.72
* */

public class Order {
    private static final List<Integer> pricePoints = List.of(5, 8, 10);

    private static final int[][] pricePerWeight = new int[][] {
        {  5, 15, 25,  40,  80 },
        {  8, 25, 45,  85, 160 },
        { 10, 35, 65, 120, 225 }
    };

    private static final double[] weightFormat = new double[] {
        1, 3.5, 7, 14, 28
    };


    public final double price, desiredPrice, maxWeight, breakpoint, neededWeight;
    public final int pricePoint, pricePointIndex, breakpointIndex;

    public Order(double price, int pricePoint) {
        this.price = price;
        this.pricePoint = pricePoint;

        desiredPrice = price / 1.16;
        pricePointIndex = pricePoints.indexOf(pricePoint);

        double[] weights = getWeights();
        maxWeight = Arrays.stream(weights).max().getAsDouble();

        breakpointIndex = getBreakpointIndex();

        if (breakpointIndex >= 0) {
            breakpoint = weightFormat[breakpointIndex];
            neededWeight = weights[breakpointIndex];
        }
        else {
            breakpoint = 0;
            neededWeight = 0;
        }
    }

    private double[] getWeights() {
        double[] weights = new double[5];
        for (int i = 0; i < 5; i++) {
            weights[i] = desiredPrice / (
                pricePerWeight[pricePointIndex][i]
                / weightFormat[i]
            );
        }

        return weights;
    }

    private int getBreakpointIndex() {
        for (int i = 4; i >= 0; i--) {
            if (maxWeight >= weightFormat[i])
                return i;
        }
        return -1;
    }
}
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/278251

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档