我的程序包含一个带有“选择咖啡”标题的标签和四个复选框 - Americano,Espresso,Double Espresso和Latte。注意:建议使用JCheckBox数组)
我需要添加事件处理代码以允许用户购买一个或多个项目。在用户进行选择后,账单金额显示在标签中。 价格为Americano€3.75,Espresso€4.00,Double Espresso€4.50和Latte€3.50。阵列也适用于此。 当用户做出选择时,会显示一个显示账单的标签。
我无法弄清楚如何在选中复选框时添加成本,并在使用数组取消选择时删除成本。 任何帮助表示赞赏。
到目前为止,这是我的代码:
package Lab4EventHandling;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Frame3 extends JFrame implements ActionListener {
private Container cPane;
private JLabel tMsg, bMsg;
private JCheckBox americano, espresso, doubleEspresso, latte;
JCheckBox[] boxes = new JCheckBox[]{americano, espresso, doubleEspresso, latte};
private JPanel checkPanel = new JPanel(new GridLayout(0,1));
private Color cl;
private double cost = 0;
private final int WINDOW_WIDTH = 200;
private final int WINDOW_HEIGHT = 200;
private final int x = 550;
private final int y = 400;
public Frame3()
{
cPane = getContentPane();
cl = new Color(150, 150, 250);
cPane.setBackground(cl);
this.setLayout(new BorderLayout(0,1));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocation(x,y);
this.add(checkPanel, BorderLayout.CENTER);
tMsg = new JLabel("Choose a coffee:" ,SwingConstants.CENTER);
tMsg.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));
this.add(tMsg, BorderLayout.PAGE_START);
americano = new JCheckBox("Americano", false);
checkPanel.add(americano);
americano.addActionListener(this);
espresso = new JCheckBox("Espresso", false);
checkPanel.add(espresso);
espresso.addActionListener(this);
doubleEspresso = new JCheckBox("Double Espresso", false);
checkPanel.add(doubleEspresso);
doubleEspresso.addActionListener(this);
latte = new JCheckBox("Latte", false);
checkPanel.add(latte);
latte.addActionListener(this);
bMsg = new JLabel("Bill is ");
bMsg.setHorizontalAlignment(SwingConstants.CENTER);
bMsg.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));
this.add(bMsg, BorderLayout.SOUTH);
this.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
Double[] array = {3.75, 4.00, 4.50, 3.50};
for (JCheckBox box : boxes) {
if(americano.isSelected())
{
cost += 3.75;
String r = String.valueOf(cost);
bMsg.setText(r);
}
if(espresso.isSelected())
{
cost += 4.00;
String r = String.valueOf(cost);
bMsg.setText(r);
}
else if(doubleEspresso.isSelected())
{
cost = 4.50;
String r = String.valueOf(cost);
bMsg.setText(r);
}
else if(latte.isSelected())
{
cost = 3.50;
String r = String.valueOf(cost);
bMsg.setText(r);
}
}
}
public class Frame3Test{
public static void main(String [] args)
{
Frame3 f = new Frame3();
f.setVisible(true);
}
}
答案 0 :(得分:3)
你的第一个问题(你可能已经注意到或未注意到)是你的JCheckBoxes数组只包含null元素:
// check boxes are null here
private JCheckBox americano, espresso, doubleEspresso, latte;
// array created with only null elements
JCheckBox[] boxes = new JCheckBox[]{americano, espresso, doubleEspresso, latte};
因此,您需要在实例化实际复选框后创建数组。
...
americano = new JCheckBox("Americano", false);
checkPanel.add(americano);
americano.addActionListener(this);
espresso = new JCheckBox("Espresso", false);
checkPanel.add(espresso);
espresso.addActionListener(this);
doubleEspresso = new JCheckBox("Double Espresso", false);
checkPanel.add(doubleEspresso);
doubleEspresso.addActionListener(this);
latte = new JCheckBox("Latte", false);
checkPanel.add(latte);
boxes = new JCheckBox[] {
americano, espresso, doubleEspresso, latte
};
然后分配建议使用数组,因为你可以创建另一个并行的价格数组(你做过)。但由于您需要并行使用这些价格,因此无法为每个循环使用a。你需要索引。然后,每次选择或取消选择任何内容时,您都需要重新计算整个成本。
final double[] prices = {
3.75, 4.00, 4.50, 3.50
};
...
double total = 0.0;
for(int i = 0; i < boxes.length; i++) {
if(boxes[i].isSelected()) {
total += prices[i];
}
}
其他两个注释似乎不在作业范围内:
double
来赚钱。使用BigDecimal
或类似的东西。使用类使逻辑更简单而不使用double
使得计算不会导致此十进制加法的错误。
class PricePair {
JCheckBox jCheckBox;
BigDecimal price;
}
BigDecimal total = new BigDecimal("0.00");
for(PricePair option : options) {
if(option.jCheckBox.isSelected()) {
total = total.add(option.price);
}
}
答案 1 :(得分:1)
首先,您没有以相同的方式处理所有复选框。对于前两个选项,您可以将价格添加到成本中:
cost += 3.75;
而对于最后两个选择,您将替换成本:
cost = 4.50;
第一种方式是正确的方法。
其次,没有理由将成本作为一个领域。您应该重新计算成本,每次复选框选择更改时,它应始终以0开头。因此,成本应该是actionPerformed()
方法的局部变量。
第三,在您知道最终成本之前,没有理由更改标签值。所以行
String r = String.valueOf(cost);
bMsg.setText(r);
只应该在actionPerformed()方法结束时有一次,当最终成本已知时。
最后,您希望将它用于数组,而不是单独处理每个checkbos。这很简单,你只需要遍历复选框:
double prices = {3.75, 4.00, 4.50, 3.50};
double cost = 0.0;
for (int i = 0; i < boxes.length; i++) {
if (boxes[i].isSelected()) {
double price = prices[i];
cost += price;
}
}
// now display the cost in the label
答案 2 :(得分:1)
虽然这里发布的两个答案都非常有用,但我添加了这个,因为IMHO数组是面向对象的东西。根据这些提示,您可以实现更强大的OO解决方案:
请参阅以下示例:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigDecimal;
import java.math.BigInteger;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Demo {
BigDecimal total = new BigDecimal(BigInteger.ZERO);
private void createAndShowGUI() {
final JLabel totalLabel = new JLabel("Total: ");
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JCheckBox checkBox = (JCheckBox)e.getSource();
BigDecimal value = (BigDecimal)checkBox.getClientProperty("price");
total = checkBox.isSelected() ? total.add(value) : total.subtract(value);
StringBuilder sb = new StringBuilder("Total: ").append(total);
totalLabel.setText(sb.toString());
}
};
JCheckBox americano = new JCheckBox("Americano");
americano.addActionListener(actionListener);
americano.putClientProperty("price", new BigDecimal("3.75"));
JCheckBox espresso = new JCheckBox("Espresso");
espresso.addActionListener(actionListener);
espresso.putClientProperty("price", new BigDecimal("4.00"));
JCheckBox doubleEspresso = new JCheckBox("Double Espresso");
doubleEspresso.addActionListener(actionListener);
doubleEspresso.putClientProperty("price", new BigDecimal("4.50"));
JCheckBox latte = new JCheckBox("Latte");
latte.addActionListener(actionListener);
latte.putClientProperty("price", new BigDecimal("3.50"));
JPanel content = new JPanel();
content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS));
content.add(americano);
content.add(espresso);
content.add(doubleEspresso);
content.add(latte);
content.add(totalLabel);
JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(content);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Demo().createAndShowGUI();
}
});
}
}
这样您就可以忘记使用数组或映射将每个复选框映射为值。如果你需要添加一种新的咖啡,你应该简单地添加4行:
JCheckBox newCoffee = new JCheckBox("New Coffee");
newCoffee.addActionListener(actionListener);
newCoffee.putClientProperty("price", new BigDecimal("4.00"));
content.add(newCoffee);