Question: //java public class GardenGUI extends JFrame{ JPanel mainPanel ; JPanel dataEntryPanel ; JPanel invoicePreviewPanel ; JTextArea invoicePreviewTextArea ; JButton saveInvoiceButton ; JTextField customerNameTextField ; JTextField

//java public class GardenGUI extends JFrame{ JPanel mainPanel; JPanel dataEntryPanel; JPanel invoicePreviewPanel; JTextArea invoicePreviewTextArea; JButton saveInvoiceButton; JTextField customerNameTextField; JTextField customerAddressTextField; JButton generateInvoicePreviewButton; JSpinner serviceDateSpinner; JCheckBox mowingServiceCheckBox; JLabel mowingServiceCost; GardenGUI() { setContentPane(mainPanel); setPreferredSize(new Dimension(1000, 600)); pack(); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setVisible(true); configureDateSpinner(); // TODO add event handlers here   /* Checkboxes and JComboBox should cause their associated JLabels and the total to update.  Example: user clicks the mowingServiceCheckBox and has 'small' selected for the garden size JComboBox.  The mowingServiceCost JLabel should show $14. The total JLabel should show $14.  Then, if the user changes the JComboBox to 'large'. This should cause the JLabel to change to $42. The total JLabel should update to $42.  Then, if the user selects another service, that service's JLabel should update, and so should the total.   Clicking the generateInvoicePreviewButton should validate that a name and address have been entered, and at least one garden service.  Use InvoiceGenerator's method to create the report text. You'll need to create a HashMap with the keys specified in InvoiceGenerator.  Show the text of the report in invoicePreviewTextArea.   Clicking the saveInvoiceButton will generate a filename for the invoice, using the methods in InvoiceWriter.  Save the contents of the invoicePreviewTextArea to this file. The user may have edited it, so save whatever is in this JTextArea.  Check if the file already exists before writing. If the file does exist, prompt user for a new file name, or  the option to cancel so they may remove the existing file if desired. You can use a JOptionDialog for this.   Don't write all of your code in this constructor. You should create methods for different tasks.   */   } // TODO use this method to show an alert dialog  // type can be JOptionPane.ERROR_MESSAGE, or JOptionPane.INFORMATION_MESSAGE  void showMessageDialog(String message, String title, int type) { JOptionPane.showMessageDialog(this, message, title, type); } // TODO use this method to show a 'enter new String' dialog. The text will be initialized to initialValue  String getStringWithDialog(String message, String initialValue) { return JOptionPane.showInputDialog(this, message, initialValue); } private void configureDateSpinner() { // Dates between Jan 1, 1970 and some time in 2920. I don't suppose this program will be around this long though...  SpinnerDateModel spinnerDateModel = new SpinnerDateModel(new Date(), new Date(0), new Date(30000000000000L), Calendar.DAY_OF_YEAR); serviceDateSpinner.setModel(spinnerDateModel); // Create a DateEditor to configure the way dates are displayed and edited  // Define format the dates will have  JSpinner.DateEditor editor = new JSpinner.DateEditor(serviceDateSpinner, "MM-dd-yyyy"); DateFormatter formatter = (DateFormatter) editor.getTextField().getFormatter(); // Attempt to prevent invalid input  formatter.setAllowsInvalid(false); // Allow user to type as well as use up/down buttons  formatter.setOverwriteMode(true); // And tell the serviceDataSpinner to use this Editor  serviceDateSpinner.setEditor(editor); } } 

======================================================================================================-===================================

 //A future program would read these from a data store, and/or permit modification  public class GardenServiceData { static String[] gardenSizes = {"Small", "Medium", "Large"}; // Prices of services   static final double MOWING = 15; static final double LEAF_RAKING = 12; static final double MEDIUM_PRICE_MULTIPLY = 2; static final double LARGE_PRICE_MULTIPLY = 3; // Example gardener contact String, used when generating invoices   static final String gardenerContactString = "Rose the Gardener, 000 ccc Street, Minneapolis. Telephone 00-000-000"; } 

======================================================================================================================================================================

 // but you will need to call the methods here.  public class InvoiceGenerator { static final String GARDENER_CONTACT = "GARDENER_CONTACT"; static final String NAME = "NAME"; static final String ADDRESS = "ADDRESS"; static final String DATE = "DATE"; static final String GARDEN_SIZE = "GARDEN_SIZE"; static final String MOWING = "MOWING"; static final String LEAVES = "LEAVES"; static final String TOTAL = "TOTAL"; static String invoiceTemplate; /* Provide a HashMap with the following keys, and String values.   NAME  ADDRESS  DATE  GARDEN_SIZE  MOWING  LEAVES  TOTAL   Notice these Strings are provided as constants in this class.   For a price, the value should be a String number with 2 decimal places,  and no & or other currency symbol, e.g. "28.00" or "14.00"    */    public static String generate(HashMap data) { // Add in the gardener info String  data.put(GARDENER_CONTACT, GardenServiceData.gardenerContactString); // Create a String Substitutor with the HashMap  StrSubstitutor sub = new StrSubstitutor(data); //Use our own template prefix  sub.setVariablePrefix("&{"); String invoice = sub.replace(invoiceTemplate); return invoice; } static int width = 80; static String lines[] = { StringUtils.center("************ Garden Services Invoice ************", width), "", "&{GARDENER_CONTACT}", "", "Customer Name: &{NAME}", "Address of garden: &{ADDRESS}", "", "Date of service: &{DATE}", "Size of garden: &{GARDEN_SIZE}", "", "Lawn mowing service charge: $ &{MOWING}", "Leaf raking service charge: $ &{LEAVES}", "", "Total: $ &{TOTAL}", "", "Please send payment to the address above.", "Thank you for your business."  } ; static { // Center the lines and concatenate together  StringBuilder builder = new StringBuilder(); for (String line: lines) { builder.append(line); builder.append(" "); } invoiceTemplate = builder.toString(); } } 

===========================================================================================================================================================================================================

 // You should not need to modify this file, but you will need to call methods.  public class InvoiceWriter { static final String INVOICE_DIRECTORY = "GardeningInvoices"; private static String dateFormatString = "MMM_dd_yyyy"; // e.g. "sep_09_2017"  private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormatString); static { File invoiceDir = new File(INVOICE_DIRECTORY); try { invoiceDir.mkdir(); } catch (SecurityException e) { if (!invoiceDir.exists()) { System.out.println("ERROR - could not create Invoice Directory. " + INVOICE_DIRECTORY); } // Otherwise, if it exists, presumably it has already been created, so no problem.  } } /*  Create a valid filename from a date, and the customer's name.  Names may have characters that are not permitted in filenames, these must be removed or replaced.  This is a very basic solution: remove all characters from customer name that are not A-Z or a-z.  This could definitely be improved. There are many names that would be distorted by this method.  This would perform poorly on names with characters outside A-Z and a-z. What if a customer has several characters removed from their name?  Many characters outside A-Z and a-z range are valid filename characters.   A more exhaustive solution to preserve names and create valid filenames would be more work, and more testing.  Looking into a 3rd party library to handle this would be recommended in a real program; it's a fairly common problem.  You are not required to improve this method; but you are welcome to contribute an improved version if you like :)  */   public static String createFileName(String customer, Date date) { String name = removeBannedCharacters(customer); if (name.length() == 0) { name = "Customer"; // Something, if there are no valid filename characters. Can you think of a better solution? Ask the user for a name?  } // Format the date into a String  String dateString = simpleDateFormat.format(date); String filename = String.format("%s_%s_invoice.txt", name, dateString); return filename; } protected static String removeBannedCharacters(String st) { return st.replaceAll("[^A-Za-z]", ""); } /* Warning! This method overwrites an existing file. A real program  * should warn the user that a file with the proposed name exists, and offer them  * the choice to overwrite or give a new name. */   public static boolean writeToFile(String filename, String text) { try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(INVOICE_DIRECTORY, filename)))) { writer.write(text); writer.close(); return true; } catch (IOException e) { System.out.println("Unable to write to file " + filename + ". Error message: " + e.getMessage()); return false; } } } 

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!