2014-02-14 7 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

Как кофе может быть экспрессом и двойным экспрессом одновременно? Вы должны использовать кнопки rzdio, поскольку выбор является взаимоисключающим. Не флажки. –

+0

@JBNizet OP упомянул, мне нужно добавить код обработки событий, чтобы позволить пользователю покупать «один или несколько элементов». – JNL

+0

Я пропустил это. Все еще странно, что можно купить экспресс и латте, но не 2 экспресса. –

ответ

2

Вашей первой проблема (которую вы можете или не можете быть замеченными) Ваш массив компоненты 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 
}; 

Тогда назначение предполагает использование массивов, потому что вы можете создать еще один параллельный массив цен (которые вы сделали). Но так как вам нужны эти цены параллельно, вы не можете использовать 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); 
    } 
} 
+0

Спасибо, это решило мою проблему, также спасибо за совет. – Johntk

1

Прежде всего, вы не обрабатывает все галочки одинаково. В течение первых двух вариантов, вы добавить цену на стоимость:

cost += 3.75; 

, тогда как в течение последних двух вариантов, вы заменяете стоимость:

cost = 4.50; 

Первый путь является правильным способом.

Во-вторых, нет причин иметь себестоимость как поле. Вы должны пересчитать стоимость, и она всегда должна начинаться с 0, каждый раз при изменении выбора флажка. Таким образом, стоимость должна быть локальной переменной метода actionPerformed().

В-третьих, нет причин менять стоимость этикетки, прежде чем вы узнаете окончательную стоимость. Таким образом, линии

String r = String.valueOf(cost); 
bMsg.setText(r); 

должны быть только там один раз, в конце методы actionPerformed(), когда конечная стоимость известна.

Наконец, вы хотите использовать его вместо массива вместо обработки каждого контрольного пакета отдельно. Это довольно просто, вам просто нужно перебрать флажки:

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

Хотя оба ответа, размещенные здесь очень полезны, я добавляю этот, потому что IMHO массивы менее объектно-ориентированное, что когда-либо. Вы можете достичь более надежного и ОО решения следующего за эти намеками:

  • Использование putClientProperty() метода наследуется от JComponent держать цены в флажках.
  • Внесите 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); 
+0

Спасибо за ваш вклад. – Johntk

+0

@Johntk, пожалуйста. Надеюсь, это будет полезно. – dic19

Смежные вопросы