单击JCheckBox时添加值

时间:2014-02-14 21:42:25

标签: java swing jframe jcheckbox

我的程序包含一个带有“选择咖啡”标题的标签和四个复选框 - 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);

    }
}

3 个答案:

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