0

I am trying to calculate sub-total in a separate textField from an event which involves user selecting number of rooms and number of days (based on check in and check out dates).

This textField (sub-total) will effectively multiply (no of days * no of rooms * room price) and will be updated when the user changes duration or number of rooms.

Please note my GUI is based on drag and drop.

private void checkDoubleActionPerformed(java.awt.event.ActionEvent evt) {                                            
 // User clicks "Check Availability" button after selecting number of Double Rooms required and duration of stay

   String value2 = spinner2.getValue().toString(); //Getting number of room using spinner2

    //.set a default current date to Check in. Can be changed by customer
    cid_chooser2.getJCalendar().setMinSelectableDate(new Date());
    cid_chooser2.setMinSelectableDate(new Date());

    Date d1 = null; //initial value of check in date
    Date d2 = null; // initial value of check out date

    try {
        d1 = cid_chooser2.getDate();
        d2 = cod_chooser2.getDate();

        long duration = d2.getTime() - d1.getTime(); //calculationg duration in days
        long days = TimeUnit.MILLISECONDS.toDays(duration);

        if (days > 0) {

            JOptionPane pane = new JOptionPane("You selected " + value2 + " Double Rooms for: " + days,JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION);
            JDialog dialog = pane.createDialog(null, "Customer Notification");
            dialog.setSize(new Dimension(400, 200));
            dialog.show();
        }
        else {JOptionPane.showMessageDialog(null, "Check out Date needs to be after Check in Date ");
        }
    }
    catch (NullPointerException ex1) {

        if (d1 == null && d2 == null) {

            JOptionPane.showMessageDialog(null, "Please enter missing check in AND check out dates.");
        }

        else if (d2 == null) {
            JOptionPane.showMessageDialog(null, "Please enter missing check out date."
                + "\nyour check out date should be at least a day after your check in date");
        }
        else if (d1 == null) {

            JOptionPane.showMessageDialog(null, "Please enter missing check in date."
                + "\nyour check in date should be at least today");
        }
    }                                          

}                         

   ////////////// separate JTextField to calculate sub-total////////////

  private void subTotal2ActionPerformed(java.awt.event.ActionEvent evt) {                                          
// sub-Total based on number of Double Rooms selected * duration (days) * unit price

}  
Emanuel
  • 37
  • 8
  • I would then calculate the total (Separate TextField) of the prices for Single, Double and Conference Room bookings. – Emanuel Jan 16 '19 at 01:42
  • What are the types of `cid_chooser2`, `cod_chooser2` and `spinner2`? `com.toedter.calendar.JDateChooser` and `javax.swing.JSpinner`? So, I guess you want the sub total to be calculated and set in the text field whenever `cid_chooser2`, `cod_chooser2` or `spinner2` values are changed? – Prasad Karunagoda Jan 16 '19 at 02:01
  • Hi Prasad. cid_chooser2 is the (Check In Date) DatePicker, cod_chooser2 is the (Check Out Date) Date Picker, Spinner2 (for choosing the number of Double rooms). When user clicks Check Availability (checkDoubleActionPerformed), I want the textField (subTotal2ActionPerformed) to calculate the sub-Total. You are right that I would like this textfield to display revised sub-total if duration or number of rooms is changed by the user. Thanks – Emanuel Jan 16 '19 at 03:20
  • The question is not quite clear for me. You want the sub total field to be updated when user clicks Check Availability button OR you want the sub total field to be updated as soon as user change one of checkin date, checkout date or number of rooms? – Prasad Karunagoda Jan 16 '19 at 05:48
  • Another thing, are you using `javafx.scene.control.DatePicker` class as your date components? If so, are you building the UI using JavaFX? Not Swing? – Prasad Karunagoda Jan 16 '19 at 05:52
  • Hi Prasad, the sub-total can be defaulted at 0. However, when the user (1) selects check in date (2) check out date (3)the number of double rooms to be booked (4) Clicks the Event button (Check Availability)... the sub-total should change to the price * number of double rooms * number of days.... I wish I could send you the GUI for exact illustration (if you want a screenshot emailed).... It is Swing GUI, I am sure. – Emanuel Jan 16 '19 at 14:06
  • @Emanuel, tell me the names of classes (fully qualified names including packages) you are using for date components and spinner component. Without knowing the exact classes, we cannot tell you the available APIs for binding event listeners. (Or add the whole code to the question.) – Prasad Karunagoda Jan 16 '19 at 15:28
  • Hi Prasad. I did mention from the onset, that this is all on a Swing GUI and I am coding under GUI's action events. I am not using domain classes as I intend to work with Arraylist not DB. You have all the information in the code I copied earlier. Hope that is helpful. – Emanuel Jan 16 '19 at 15:58

1 Answers1

1

I hope this sample program will show you how to do this. Here I'm using JDateChooser class which can be downloaded from: https://toedter.com/jcalendar/

If you are using some other date component, I'm sure that class would also have a similar API like addPropertyChangeListener() which you can use.

import com.toedter.calendar.JDateChooser;

import javax.swing.*;
import javax.swing.event.*;
import java.awt.GridLayout;
import java.awt.event.*;
import java.beans.*;
import java.util.Date;

public class CalculateSubTotal {

  private static JDateChooser checkin = new JDateChooser();
  private static JDateChooser checkout = new JDateChooser();
  private static JSpinner rooms = new JSpinner(new SpinnerNumberModel(1, 0, 10, 1));
  private static JTextField subTotal = new JTextField(20);
  private static JButton button = new JButton("Check availability");

  public static void main(String[] args) {

    checkin.getDateEditor().addPropertyChangeListener("date", new PropertyChangeListener() {
      @Override
      public void propertyChange(PropertyChangeEvent evt) {
        calculateSubTotal(checkin.getDate(), checkout.getDate(), (Integer) rooms.getValue(), 50);
      }
    });

    checkout.getDateEditor().addPropertyChangeListener("date", new PropertyChangeListener() {
      @Override
      public void propertyChange(PropertyChangeEvent evt) {
        calculateSubTotal(checkin.getDate(), checkout.getDate(), (Integer) rooms.getValue(), 50);
      }
    });

    rooms.addChangeListener(new ChangeListener() {
      @Override
      public void stateChanged(ChangeEvent e) {
        calculateSubTotal(checkin.getDate(), checkout.getDate(), (Integer) rooms.getValue(), 50);
      }
    });

    button.addActionListener(new ActionListener()
    {
      @Override
      public void actionPerformed(ActionEvent e) {
        calculateSubTotal(checkin.getDate(), checkout.getDate(), (Integer) rooms.getValue(), 50);
      }
    });

    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.getContentPane().setLayout(new GridLayout(6, 2));
    f.getContentPane().add(new JLabel("Price"));
    f.getContentPane().add(new JLabel("50"));
    f.getContentPane().add(new JLabel("Check in"));
    f.getContentPane().add(checkin);
    f.getContentPane().add(new JLabel("Check out"));
    f.getContentPane().add(checkout);
    f.getContentPane().add(new JLabel("Number of rooms"));
    f.getContentPane().add(rooms);
    f.getContentPane().add(new JLabel("Sub total"));
    f.getContentPane().add(subTotal);
    f.getContentPane().add(button);
    f.setBounds(300, 200, 400, 300);
    f.setVisible(true);
  }

  private static void calculateSubTotal(Date checkin, Date checkout, int rooms, int price) {
    if (checkin == null || checkout == null) {
      return;
    }
    int sub = getDays(checkin, checkout) * rooms * price;
    subTotal.setText(String.valueOf(sub));
  }

  private static int getDays(Date checkin, Date checkout) {
    return (int) ((checkout.getTime() - checkin.getTime()) / (1000 * 60 * 60 * 24));
  }
}
Prasad Karunagoda
  • 2,048
  • 2
  • 12
  • 16
  • Thanks a lot Prasad ! It all makes sense now. Thank you so much :) – Emanuel Jan 19 '19 at 13:52
  • @Emanuel, you are welcome. Please accept/vote the answer if it was helpful :) – Prasad Karunagoda Jan 19 '19 at 14:33
  • Just done it. Sorry, I am kinda getting used to the StackOverFlow ways. God bless. – Emanuel Jan 19 '19 at 14:45
  • @Emanuel, but I don't see my answer accepted nor voted :) (This may help you: https://stackoverflow.com/help/someone-answers) – Prasad Karunagoda Jan 19 '19 at 14:57
  • I have voted up again and the same message appeared as last time. "Thanks for the feedback! Votes cast by those with less than 15 reputation are recorded, but do not change the publicly displayed post score.". I am guessing I need to earn some reputation for my vote to be publicly displayed. I hope that you are not disappointed by this Prasad. – Emanuel Jan 19 '19 at 15:44
  • @Emanuel, but you should be able to accept the answer (by clicking "√" below the voting buttons). For that you don't need reputation points. Anyway it's ok, I'm not disappointed. I'm glad I could help :) – Prasad Karunagoda Jan 19 '19 at 15:51
  • Just saw that ("√" below the voting buttons) and clicked it . It's now showing Green. I hope it is reflecting correctly now for you. Thanks ever so much and do let me know if otherwise. – Emanuel Jan 19 '19 at 16:39
  • @Emanuel, yes, now I see my answer is accepted. Thank you very much :) – Prasad Karunagoda Jan 19 '19 at 17:06
  • Thanks to you Prasad ! I have been stuck on this for days until you helped. I don't know why my question has been voted down by somebody. It is a very valid question! – Emanuel Jan 19 '19 at 17:52