我刚开始用Java开始我的第一个真正的项目,所以我仍然理解基础知识,为此道歉。
我正在计算价格*数量然后给每个产品的总金额,然后必须在订单处理过程中对我的所有产品重复这一过程。所以我想找到最好的方式让我重复一遍。
这是我的工作代码:
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
double priceA = 20.00;/*fixed price*/
String strA = txtbxCaseA.getText();/*gets amount from textbox*/
int numA = Integer.parseInt(strA);/*parse to int */
double casetotalA = (priceA * numA);/*sum*/
String caseAtotal = String.valueOf(casetotalA);/*to string */
double priceB = 25.00;
String strB = txtbxCaseB.getText();
int numB= Integer.parseInt(strB);
double casetotalB = (priceB * numB);
String caseBtotal = String.valueOf(casetotalB);
double priceC = 30.00;
String strC = txtbxCaseC.getText();
int numC = Integer.parseInt(strC);
double casetotalC = (priceC * numC);
String caseCtotal = String.valueOf(casetotalC);
ArrayList caselist = new ArrayList();
caselist.add("Case A Total - £" + caseAtotal);
caselist.add("Case B Total - £" + caseBtotal);
caselist.add("Case C Total - £" + caseCtotal);
DefaultListModel myModel = new DefaultListModel ();
for(int i = 0; i < caselist.size(); i++){
jTextArea3.append((String)caselist.get(i) + ('\n'));
myModel.addElement(caselist.get(i) + ",");
/*
- save arraylist to a gobal varible for cart processing
- move to next panel (page) along
*/
}
}
我的问题是,这种方法是不错的做法,也是他们更好的方法(可能更短),我可以为我的50种产品中的每一种重复,因为这似乎有点低效但是有效。
非常感谢任何建议或意见。
答案 0 :(得分:2)
是他们更好的方法(可能更短),我可以重复每一个 我的50个产品
为什么不将您的产品存储在一个集合(List)中,以便您可以随时遍历每个产品和总计?如果你有一个Product
对象,那么你可以为每个成员分配一个价格,并在你去的时候迭代总计。
for (Product p : listOfProducts) {
sum = sum + p.price * quantity;
}
请注意,我会将上述内容放入价格计算器或类似计算器中,以便您可以与GUI Swing代码分开运行和测试(通过单元测试框架,如JUnit)。
答案 1 :(得分:1)
可以做的一件事是你可以使用TextBox数组并创建一个计算值并在Arraylist中插入的函数,并在按钮事件处理程序方法内的循环中调用此函数。另请尝试使用ArrayList<String>
代替ArrayList
。这确保了更强的类型检查。
答案 2 :(得分:0)
自您提及以来最佳做法的一些提示:
double priceA = 20.00;
首先double
并不完全准确,您应该注意是否计划使用浮点变量进行必须100%准确的任何计算(例如资金计算),使用{{ 1}}类而不是。
其次,您应该将所有常量(固定)值存储在您定义变量的类的顶部,这样您就不会漫游任何“幻数”。
示例:java.math.BigDecimal
这样,每次访问该方法时都不必重新定义变量。
第三,你应该始终怀疑用户输入并处理它。
如果我将其中一个文本框留空,那么private static final double priceA = 20.00
会发生什么?
或者更糟糕的是,如果我在那里写一些文字而不是数字呢?
您应该始终注意,用户不会总是按预期使用您的程序,甚至会尝试破解它。
最后,您可以在此方法之外定义一种计算方法,以简化您当前的方法。
从您的示例中可能看起来像这样:
Integer.parseInt(strA)
这会将原始方法缩减为:
private String calculcateTotal(double price, String amount) {
int actualAmount = Integer.parseInt(amount);
double totalAmount = (price * actualAmount);
return String.valueOf(totalAmount);
}
看看它现在看起来怎么样?
你甚至可以省略
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
double priceA = 20.00;
double priceB = 25.00;
double priceC = 30.00;
ArrayList caselist = new ArrayList();
caselist.add("Case A Total - £" + calculateTotal(priceA, txtbxCaseA.getText()));
caselist.add("Case B Total - £" + calculateTotal(priceB, txtbxCaseB.getText()));
caselist.add("Case C Total - £" + calculateTotal(priceC, txtbxCaseC.getText()));
DefaultListModel myModel = new DefaultListModel ();
for(int i = 0; i < caselist.size(); i++){
jTextArea3.append((String)caselist.get(i) + ('\n'));
myModel.addElement(caselist.get(i) + ",");
/*
- save arraylist to a gobal varible for cart processing
- move to next panel (page) along
*/
}
}
如果你像我之前提到的那样在你的班级顶层定义了它们。
答案 3 :(得分:0)
我的建议是将业务逻辑与表示逻辑分开,你最终会得到这样的结果:
/**
* Represents the concept of getting a `Integer` quantity from some source.
*/
public inteface Quantity
{
public Integer getValue();
}
/**
* Represents the combination of a price and quantity to produce a total.
*/
public class Total
{
private double price;
private Quantity quantity;
public Total(double price, Quantity quantity)
{
this.price = price;
this.quantity = quantity;
}
public Double getValue()
{
Integer quantity = quantity.getValue();
return quantity != null ? quantity * price : null;
}
}
然后你可以在你的Swing代码中使用这个inteface和class(这只是为了显示与Swing的交互,而不是如何布局控件):
public class MyFrame extends JFrame
{
private static final List<Double> PRICES = Arrays.asList(20.0, 25.0, 30.0);
public MyFrame()
{
List<Total> totals = new ArrayList<Total>();
JList totalsList = new JList(new TotalListModel(totals));
addComponent(totalsList);
for (Double price : PRICES)
{
JTextField quantityTextField = new JTextField();
quantityTextField.addActionListener(new RepaintComponentActionListener(totalsList));
addComponent(quantityTextField);
totals.add(new Total(price, new TextFieldQuantity(quantityTextField)));
}
}
private class TotalListModel extends AbstractListModel
{
private List<Total> totals;
public TotalListModel(List<Total> totals)
{
this.totals = totals;
}
public Object getElementAt(int index)
{
Double value = totals.get(index).getValue();
return value != null ? value.toString() : "NO VALUE";
}
public int getSize()
{
return totals.size();
}
}
private class TextFieldQuantity implements Quantity
{
private JTextField textField;
public TextFieldQuantitySource(JTextField textField)
{
this.textField = textField;
}
public Integer getQuantity()
{
try
{
return Integer.parseInt(textField.getText());
}
catch (NumberFormatException e)
{
return null;
}
}
}
private class RepaintComponentActionListener implements ActionListener
{
private Component component;
public RefreshControlActionListener(Component component)
{
this.component = component;
}
public void actionPerformed(ActionEvent actionEvent)
{
component.repaint();
}
}
}
如果不能立即清楚此代码是如何工作的,则使用:
ListModel
以包裹totals
,意味着JList
只需要重新绘制,并且将显示当前总计。PRICES
上方循环以动态创建JTextField
控件(我会让它为您设计布局)。ActionListener
,当任何JList
更改时,会重新显示JTextField
。Quantity
,用于读取JTextField
。答案 4 :(得分:0)
改善整体项目的一些提示,让您更轻松。其中一些提示已经在其他答案中公布。
基本原则是(就像Ceiling Gecko评论的那样):如果你看到自己重复代码,那就用一种通用的方式对代码进行一次编码,并为每次重复重用代码。
public class Product {
private String name;
private double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
}
您将在程序一开始就填写所有产品,并将其存储在array
或List
List<Product> productList = new ArrayList<Product>();
productList.add(new Product("Milk", 10.00));
productList.add(new Product("Bread", 20.00));
此处的产品是硬编码的,但您可能希望从文件或数据库中读取它。稍后会详细介绍。
Collections
如果为了输入金额而为JPanel
编码50 JTextField
s,那么当您添加其他产品时会发生什么?
然后您必须更改代码。
如果您使用之前提到的List
Product
,则可以动态生成JTextField
个
如果您从文件或数据库中填充列表,则在更新产品列表和/或价格时,您将永远不必更改代码。然后,您只需更新您的文件或数据库,更改将反映在您的代码中。
List<JTextField> textFields = new ArrayList<JTextField>();
for (Product p : productList) {
textFields.add(new JTextField());
}
然后将该列表与产品列表一起使用,将Component
放在JPanel
JPanel panel = new JPanel();
for (int i = 0; i < textFields.size(); i++) {
panel.add(new JLabel(productList.get(i).getName()));
panel.add(textFields.get(i));
}
private double calculateTotal(String amount, double cost) {
int amnt = Integer.parseInt(amount);
return cost * amnt;
}
Integer.parseInt
private void jButton2ActionPerformed(ActionEvent evt) {
caselist = new ArrayList<String>();
for (int i = 0; i < textFields.size(); i++) {
try {
double total = calculateTotal(textFields.get(i).getText(), productList.get(i).getPrice());
caselist.add(productList.get(i).getName() +" Total - £" + total);
} catch (NumberFormatException e) {
caselist.add(productList.get(i).getName() +" invalid amount");
}
}
}
所以你可以复制并运行它以查看它们是如何组合在一起的 它被快速组合在一起,因此它不是构建程序的最佳方式
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ProductCalc extends JFrame {
public static void main(String[] args) {
new ProductCalc();
}
private List<Product> productList;
private List<JTextField> textFields;
private List<String> caselist;
public ProductCalc() {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
productList = new ArrayList<Product>();
productList.add(new Product("Milk", 10.00));
productList.add(new Product("Bread", 20.00));
productList.add(new Product("Eggs", 5.00));
textFields = new ArrayList<JTextField>();
for (Product p : productList) {
textFields.add(new JTextField(10));
}
JPanel panel = new JPanel();
for (int i = 0; i < textFields.size(); i++) {
panel.add(new JLabel(productList.get(i).getName()));
panel.add(textFields.get(i));
}
JButton button = new JButton("click");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});
panel.add(button);
this.setSize(500, 500);
this.add(panel);
this.setVisible(true);
}
private void jButton2ActionPerformed(ActionEvent evt) {
caselist = new ArrayList<String>();
for (int i = 0; i < textFields.size(); i++) {
try {
double total = calculateTotal(textFields.get(i).getText(), productList.get(i).getPrice());
caselist.add(productList.get(i).getName() + " Total - £" + total);
} catch (NumberFormatException e) {
caselist.add(productList.get(i).getName() + " invalid amount");
}
}
for (String s : caselist) {
System.out.println(s);
}
}
private double calculateTotal(String amount, double cost) {
int amnt = Integer.parseInt(amount);
return cost * amnt;
}
}
class Product {
private String name;
private double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
}