单击JCheckBox时添加值

我的程序包含一个带有“选择咖啡”标题的标签和四个复选框 – Americano,Espresso,Double Espresso和Latte。 注意:这里建议使用JCheckBox数组)

我需要添加事件处理代码以允许用户购买一个或多个项目。 在用户进行选择后,账单金额显示在标签中。 价格为Americano€3.75,Espresso€4.00,Double Espresso€4.50和Latte€3.50。 arrays也适用于此。 当用户做出选择时,显示标签显示账单。

我无法弄清楚如何在选中复选框时添加成本,并在使用数组取消选择时删除成本。 任何帮助赞赏。

到目前为止这是我的代码:

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); } } 

您的第一个问题(您可能已经注意到或未注意到)是您的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); } } 

首先,您没有以相同的方式处理所有复选框。 对于前两个选项,您可以将价格添加到成本中:

 cost += 3.75; 

而对于最后两个选择,您将替换成本:

 cost = 4.50; 

第一种方式是正确的方法。

其次,没有理由将成本作为一个领域。 您应该重新计算成本,每次复选框选择更改时,它应始终以0开头。 因此,cost应该是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 

虽然这里发布的两个答案都非常有用,但我正在添加这个,因为IMHO数组是面向对象的东西。 您可以按照以下提示获得更强大的OO解决方案:

  • 使用从JComponentinheritance的putClientProperty()方法来保存复选框中的价格。
  • 实现ActionListener以根据复选框状态将复选框价格添加/减去总数。 使用getClientProperty()方法检索复选框中存储的值。

请参阅以下示例:

 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);