Java 单击JCheckBox时添加值

Java 单击JCheckBox时添加值,java,swing,jframe,jcheckbox,Java,Swing,Jframe,Jcheckbox,我的程序包含一个标题为“选择咖啡”的标签和四个复选框——美式咖啡、浓缩咖啡、双份浓缩咖啡和拿铁咖啡。注意:此处建议使用JCheckBox阵列) 我需要添加事件处理代码,以允许用户购买一个或多个项目。用户做出选择后,票据金额将显示在标签中。 价格分别为美式咖啡3.75欧元、浓缩咖啡4.00欧元、双份浓缩咖啡4.50欧元和拿铁3.50欧元。这里也适合使用数组。 当用户做出选择时,将显示一个显示账单的标签 我不知道如何在选中复选框时添加成本,在使用数组取消选中时删除成本。 谢谢你的帮助 这是我目前的代

我的程序包含一个标题为“选择咖啡”的标签和四个复选框——美式咖啡、浓缩咖啡、双份浓缩咖啡和拿铁咖啡。注意:此处建议使用JCheckBox阵列)

我需要添加事件处理代码,以允许用户购买一个或多个项目。用户做出选择后,票据金额将显示在标签中。 价格分别为美式咖啡3.75欧元、浓缩咖啡4.00欧元、双份浓缩咖啡4.50欧元和拿铁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);

    }
}

首先,您并不是以相同的方式处理所有复选框。对于前两种选择,将价格添加到成本中:

cost += 3.75;
cost = 4.50;
而对于最后两种选择,您将替换成本:

cost += 3.75;
cost = 4.50;
第一种方法是正确的方法

其次,没有理由将成本作为一个领域。您应该重新计算成本,并且每次复选框选择更改时,它都应该以0开头。所以成本应该是
actionPerformed()
方法的局部变量

第三,在知道最终成本之前,没有理由更改标签值。那么台词呢

String r = String.valueOf(cost);
bMsg.setText(r);
在actionPerformed()方法的末尾,当最终成本已知时,应该只存在一次

最后,您希望将其用作一个数组,而不是单独处理每个checkbo。这很简单,您只需在复选框上循环:

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
双倍价格={3.75,4.00,4.50,3.50};
双倍成本=0.0;
对于(int i=0;i
首先,您没有以相同的方式处理所有复选框。对于前两种选择,将价格添加到成本中:

cost += 3.75;
cost = 4.50;
而对于最后两种选择,您将替换成本:

cost += 3.75;
cost = 4.50;
第一种方法是正确的方法

其次,没有理由将成本作为一个领域。您应该重新计算成本,并且每次复选框选择更改时,它都应该以0开头。所以成本应该是
actionPerformed()
方法的局部变量

第三,在知道最终成本之前,没有理由更改标签值。那么台词呢

String r = String.valueOf(cost);
bMsg.setText(r);
在actionPerformed()方法的末尾,当最终成本已知时,应该只存在一次

最后,您希望将其用作一个数组,而不是单独处理每个checkbo。这很简单,您只需在复选框上循环:

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
双倍价格={3.75,4.00,4.50,3.50};
双倍成本=0.0;
对于(int i=0;i
您的第一个问题(您可能注意到,也可能没有注意到)是您的JCheckbox数组只包含空元素:

// 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];
    }
}
您的第一个问题(您可能注意到,也可能没有注意到)是您的JCheckbox数组只包含空元素:

// 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];
    }
}

虽然这里发布的两个答案都非常有用,但我添加了这个答案,因为IMHO数组从来都不是面向对象的。根据以下提示,您可以实现更健壮、更面向对象的解决方案:

  • 使用 方法继承自 在复选框中保留价格
  • 根据复选框状态,实现将复选框价格添加/减去到总额中。使用方法检索存储在复选框中的值
请参见下面的示例:

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

虽然这里发布的两个答案都非常有用,但我添加了这个答案,因为IMHO数组从来都不是面向对象的。根据以下提示,您可以实现更健壮、更面向对象的解决方案:

  • 使用 方法继承自 在复选框中保留价格
  • 根据复选框状态,实现将复选框价格添加/减去到总额中。使用方法检索存储在复选框中的值
请参见下面的示例:

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

一杯咖啡怎么能同时是速递咖啡和双份速递咖啡呢?您应该使用rzdio按钮,因为这些选项是互斥的。不是复选框。@jbnitet OP提到,我需要添加事件处理代码,以允许用户购买
一个或多个项目。
我错过了。能买一杯expresso和一杯拿铁咖啡,却买不到两杯expresso咖啡,这还是很奇怪的。为什么你的咖啡这么贵?选择不是相互排斥的,这是一项任务,我知道这毫无意义,但这正是我需要它做的。一杯咖啡怎么能同时是一杯expresso和一杯双倍expresso咖啡?您应该使用rzdio按钮,因为