2014-02-14 23 views
1

我的程序包含一个标签,标题为“选择咖啡”和四个复选框 - Americano,Espresso,Double Espresso和Latte。注意:这里推荐一个JCheckBox数组)当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); 

    } 
} 
+1

咖啡怎么可以是一个expresso和一个双expresso在同一时间?您应该使用rzdio按钮,因为选项是互斥的。不是复选框。 –

+0

@JBNizet OP提到,我需要添加事件处理代码,以允许用户购买'一件或多件商品.' – JNL

+0

我错过了。能够购买expresso和latte,但不是2 expresses,仍然很奇怪。 –

回答

2

你的第一个问题(您可能会或可能没有注意到)是你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 
}; 

然后分配建议使用数组,因为您可以创建另一个并行数组(价格)。但由于您需要并行使用这些价格,因此您无法在每个循环中使用一个。你需要索引。然后,每次选择或取消选择任何内容时,都需要重新计算整个成本。

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

谢谢,这解决了我的问题,也谢谢你的建议。 – Johntk

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 
+0

感谢您的帮助,非常感谢。 – Johntk

1

尽管在这里发布的两个答案都非常有帮助,但我添加了这一个,因为恕我直言的阵列是面向对象的东西。你可以实现一个更强大和面向对象的解决方案如下这样的提示:从 JComponent 继承来保持价格复选框

请参见下面的例子:

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

感谢您的输入。 – Johntk

+0

@Johntk不客气。希望它有帮助。 – dic19