//Author: ^-^ Veerle ^-^ import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.Vector; import javax.swing.JOptionPane; import java.text.DecimalFormat; public class currencyConverter2E extends JFrame implements ActionListener //Setup frame, allowing you to edit the currencies { private final int maxCurrenciesSupported = 50; private final String storedPassword = "pcfy"; //Password for saving changes private currencyConverter2R readObject; //Read the txt file private currencyConverter2W writeObject; //Write to the txt file private currencyConverter2T conversionTable; //Display the conversion table private Vector vecCurrencies; private String[] backupCurrencies = new String[maxCurrenciesSupported]; //Stores a string array of all the currencies since the last save private int backupCurrenciesAmount; //Amount of currencies since last time saved private DecimalFormat decFormat = new DecimalFormat("#.00"); private JButton cmdSave, cmdClose, cmdAddCurrency, cmdRemoveCurrency, cmdRenameCurrency; private JScrollPane scrollTable; private JLabel lblInstructions, lblDummy; private JPanel panRoot, panButtonArea, panButtonRow1, panButtonRow2, panNorthArea; private Color clrBackgrounds = new Color(75,141,221); //Light white private Color clrForegrounds = new Color(0,0,0); //Black private boolean changesMade = false; //Flag for if the combo box models need updating or not private boolean isPasswordCorrect = false; //Flag for if a correct password has been entered private boolean currenciesAlreadyRead = false; //Flag for if the currencies have already been read private float[][] conversionMatrix; //2D grid of all the conversions public currencyConverter2E (String title) //Sets up the frame { this.setTitle(title); this.setResizable(false); this.setLayout(new BorderLayout()); this.setSize(new Dimension(550, 250)); writeObject = new currencyConverter2W(); readObject = new currencyConverter2R(); conversionTable = new currencyConverter2T(); cmdSave = new JButton("Save"); cmdClose = new JButton("Close"); cmdAddCurrency = new JButton("Add Currency"); cmdRemoveCurrency = new JButton("Remove Currency"); cmdRenameCurrency = new JButton("Rename Currency"); cmdSave.addActionListener(this); cmdClose.addActionListener(this); cmdAddCurrency.addActionListener(this); cmdRemoveCurrency.addActionListener(this); cmdRenameCurrency.addActionListener(this); lblDummy = new JLabel(""); lblInstructions = new JLabel("Change the conversion rates in the table and click save to apply changes", JLabel.CENTER); panRoot = new JPanel(new BorderLayout()); panButtonArea = new JPanel(new BorderLayout()); panNorthArea = new JPanel(new BorderLayout()); panButtonRow1 = new JPanel(); panButtonRow2 = new JPanel(); //Sets up the scroll pane with the V and Hz scroll bars always showing, with the conversion table inside the pane scrollTable = new JScrollPane(conversionTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); this.add(panRoot, BorderLayout.CENTER); panRoot.add(panNorthArea, BorderLayout.NORTH); panNorthArea.add(lblInstructions, BorderLayout.NORTH); panNorthArea.add(scrollTable, BorderLayout.SOUTH); panRoot.add(panButtonArea, BorderLayout.SOUTH); panButtonArea.add(panButtonRow1, BorderLayout.NORTH); panButtonRow1.add(cmdSave); panButtonRow1.add(cmdClose); panButtonArea.add(panButtonRow2, BorderLayout.SOUTH); panButtonRow2.add(cmdAddCurrency); panButtonRow2.add(cmdRenameCurrency); panButtonRow2.add(cmdRemoveCurrency); panRoot.setBackground(clrBackgrounds); panButtonArea.setBackground(clrBackgrounds); panButtonRow1.setBackground(clrBackgrounds); panButtonRow2.setBackground(clrBackgrounds); panNorthArea.setBackground(clrBackgrounds); scrollTable.setBackground(clrBackgrounds); lblInstructions.setForeground(clrForegrounds); lblInstructions.setBorder(BorderFactory.createEmptyBorder(3,1,3,1)); panButtonRow2.setBorder(BorderFactory.createEmptyBorder(1,1,3,1)); scrollTable.setBorder(BorderFactory.createEmptyBorder(3,5,3,5)); } public void checkPassword () //Requires a correct password to make changes { if (!isPasswordCorrect) //If the correct password hasn't been entered yet { //Show the dialogue box and get the password they type in String enteredPassword = "default value"; enteredPassword = JOptionPane.showInputDialog(null, "Enter Password (password is pcfy)", "Password", JOptionPane.QUESTION_MESSAGE); if (enteredPassword != null) { if (enteredPassword.equalsIgnoreCase(storedPassword)) //If password is correct { JOptionPane.showMessageDialog(null, "Password is correct, you may save changes", "Correct Password", JOptionPane.INFORMATION_MESSAGE); isPasswordCorrect = true; } else { JOptionPane.showMessageDialog(null, "Password is incorrect, enter the correct password to save changes", "Incorrect Password", JOptionPane.WARNING_MESSAGE); } } } } public void resetCurrencies () //Tells the read object to read the currencies and conversions { if (!currenciesAlreadyRead) //If they have not already been read { readObject.read(); //Tells the read object to read if (readObject.isError()) //If an error occured { if (readObject.noFile()) //If no file exist { writeObject.createDefault(); //Create the default file readObject.read(); //Read again } else { System.out.print(readObject.getErrorMsg()); } } conversionMatrix = readObject.getConversionMatrix(); //Gets the conversion matrix vecCurrencies = readObject.getCurrencies(); //Gets the currencies backupCurrenciesAmount = vecCurrencies.size(); //Sets the backup amount of how many currencies exist for (int i = 0; i < backupCurrenciesAmount; i++) { backupCurrencies[i] = vecCurrencies.elementAt(i).toString(); //Sets the backup currencies list } conversionTable.updateTable(vecCurrencies, conversionMatrix, false); //Show the table of conversion rates (but don't require a save) currenciesAlreadyRead = true; //Stops the programme unnessarrily reading the file again } changesMade = false; //Turn of the flag saying combo boxes should be updated } private void saveChanges () //Tells the write object to write the currencies and conversions { checkPassword(); if (isPasswordCorrect) { conversionMatrix = conversionTable.getConversionMatrix(); //Gets the running conversion table writeObject.write(vecCurrencies, conversionMatrix); //Writes the file if (writeObject.isError()) //If error occured { JOptionPane.showMessageDialog(null, "Error saving file", "Error saving file", JOptionPane.ERROR_MESSAGE); } else { JOptionPane.showMessageDialog(null, "Save was sucessfull", "Saved", JOptionPane.INFORMATION_MESSAGE); changesMade = true; //Turn on the flag to reset combo boxes conversionTable.saved(); //Tell converion table to turn of the flag requiring a save if (vecCurrencies.size() != backupCurrenciesAmount) //If the size has changed (add/remove currency) { backupCurrenciesAmount = vecCurrencies.size(); //Change backup size for (int i = 0; i < maxCurrenciesSupported; i++) //Remove all the backup currencies { backupCurrencies[i] = ""; } for (int i = 0; i < backupCurrenciesAmount; i++) //Add the new currencies { backupCurrencies[i] = vecCurrencies.elementAt(i).toString(); } } } } } private void addCurrency () //Method for adding a currency { String currencyName = "default Value"; currencyName = JOptionPane.showInputDialog(null, "Enter Currency Name", "Add Currency", JOptionPane.QUESTION_MESSAGE); if (currencyName != null) { int currencyExists = checkCurrencyExists(currencyName); //Check if the currency name already exists if (currencyExists != -1) //-1 is used if the currency name doesn't exist { JOptionPane.showMessageDialog(null, "Error, currency name is already used","Error", JOptionPane.ERROR_MESSAGE); } else { //Creates a new conversion matrix one row/column size bigger float[][] newConversionMatrix = new float[vecCurrencies.size() + 1][vecCurrencies.size() + 1]; vecCurrencies.addElement(currencyName); //Add the new currency for (int row = 0; row < vecCurrencies.size(); row++) { for (int column = 0; column < vecCurrencies.size(); column++) { if ((vecCurrencies.size() - 1) == row) //If last row { newConversionMatrix[row][column] = 1.00f; //Default value which the user can change } else { if ((vecCurrencies.size() - 1) == column) //If last column { newConversionMatrix[row][column] = 1.00f; } else { newConversionMatrix[row][column] = conversionMatrix[row][column]; } } } } conversionMatrix = newConversionMatrix; conversionTable.updateTable (vecCurrencies, conversionMatrix, true); //Update the conversion table the user sees, and turn on the flag requiring a save } } } private int checkCurrencyExists (String name) //Checks if a currency name already exists { for (int i = 0; i < vecCurrencies.size(); i++) { if (name.equalsIgnoreCase(vecCurrencies.elementAt(i).toString())) { return i; //Returns the index number where it was found (useful for removing and renaming the currency) } } return -1; //Returns -1 if the currency name was not found } private void removeCurrency () //Method for removing a currency { String currencyName = "default value"; currencyName = JOptionPane.showInputDialog(null, "Enter Currency Name", "Remove Currency", JOptionPane.QUESTION_MESSAGE); if (currencyName != null) { int currencyIndex = checkCurrencyExists(currencyName); if (currencyIndex != -1) //If the currency name exists { int selectedValue = JOptionPane.showConfirmDialog(null, "Are you sure you want to remove " + currencyName + "?", "Remove Currency?", JOptionPane.YES_NO_OPTION); if (selectedValue == JOptionPane.YES_OPTION) //If user confirms the delete { //makes a new conversion matrix with a row/column size reduced float[][] newConversionMatrix = new float[vecCurrencies.size() - 1][vecCurrencies.size() - 1]; int newRow = 0, newColumn = 0; //These are the new column/rows for (int row = 0; row < vecCurrencies.size(); row++) { if (row != currencyIndex) //If the row number doesn't eq the index at which the currency name was found { for (int column = 0; column < vecCurrencies.size(); column++) { if (column != currencyIndex) //If the column number doesn't eq the index at which the currency name was found { //Insert the currency into the new conversion matrix with the new row/column addresses newConversionMatrix[newRow][newColumn] = conversionMatrix[row][column]; newColumn++; } } newRow++; //Only increases if the index didn't match } newColumn = 0; } vecCurrencies.removeElementAt(currencyIndex); //Removes the currency from the vector conversionMatrix = newConversionMatrix; conversionTable.updateTable(vecCurrencies, conversionMatrix, true); //Updates the table for the user to see, and turns on the flag requiring a save } } else { JOptionPane.showMessageDialog(null, "Unreconised Currency " + currencyName, "Error", JOptionPane.ERROR_MESSAGE); } } } private void renameCurrency () //Method for renaming a currency { String currencyName = ""; currencyName = JOptionPane.showInputDialog(null, "Enter Existing Currency Name", "Rename Currency", JOptionPane.QUESTION_MESSAGE); if (currencyName != null) { int currencyIndex = checkCurrencyExists(currencyName); if (currencyIndex != -1) //If currency exists { String newName = JOptionPane.showInputDialog(null, "Enter the new Currency Name", "Rename Currency", JOptionPane.QUESTION_MESSAGE); int newCurrencyIndex = checkCurrencyExists(currencyName); if (newCurrencyIndex == -1) //If new currency name doesn't exist { vecCurrencies.setElementAt(newName, currencyIndex); //Make the change conversionTable.updateTable(vecCurrencies, conversionMatrix, true); //Updates the table for the user to see, and turns on the flag requring a save } else { JOptionPane.showMessageDialog(null, "Currency Name already exists " + currencyName, "Error", JOptionPane.ERROR_MESSAGE); } } else { JOptionPane.showMessageDialog(null, "Unreconised Currency " + currencyName, "Error", JOptionPane.ERROR_MESSAGE); } } } public boolean hasChangesBeenMade () //Method for finding if changes have been made { return changesMade; } public float getRate (int source, int des) //Gets an indvidual conversion { return conversionMatrix[source][des]; } public DefaultComboBoxModel getModel () //Gets a model to be used with a combo box { DefaultComboBoxModel cmenu = new DefaultComboBoxModel(vecCurrencies); return cmenu; } public boolean isError () { return readObject.isError(); } public String getErrorMsg () { return readObject.getErrorMsg(); } public void actionPerformed (ActionEvent e) { if (e.getSource() == cmdSave) { saveChanges(); } else if (e.getSource() == cmdClose) { if (conversionTable.changesMade()) //If changes have been made { int selectedValue = JOptionPane.showConfirmDialog(null, "Do you wish to Save changes?", "Save changes?", JOptionPane.YES_NO_OPTION); //Ask the user if they want to save changes if (selectedValue == JOptionPane.YES_OPTION) //If they answer yes { saveChanges(); //Save changes (asks for a password first if not already entered) if (isPasswordCorrect) //If the password is correct { this.setVisible(false); } //If the password is not correct, don't close the frame since the user might have entered the wrong password by mistake } else //If not changing { conversionMatrix = conversionTable.getDefault(); //Resets the default if (vecCurrencies.size() != backupCurrenciesAmount) //If the size has changed { vecCurrencies.clear(); //Clear everything for (int i = 0; i < backupCurrenciesAmount; i++) //Reset the vector list { vecCurrencies.addElement(backupCurrencies[i]); } } conversionTable.updateTable(vecCurrencies, conversionMatrix, false); //Update the conversion table for the user to see, but don't require a save this.setVisible(false); } } else { this.setVisible(false); } } else if (e.getSource() == cmdAddCurrency) { if (vecCurrencies.size() < maxCurrenciesSupported) //If cap has not been reached { checkPassword(); if (isPasswordCorrect) { addCurrency(); } } else { JOptionPane.showMessageDialog(null, "To many currencies, max " + maxCurrenciesSupported + " allowed", "Overflow", JOptionPane.ERROR_MESSAGE); } } else if (e.getSource() == cmdRemoveCurrency) { checkPassword(); if (isPasswordCorrect) { removeCurrency(); } } else if (e.getSource() == cmdRenameCurrency) { checkPassword(); if (isPasswordCorrect) { renameCurrency(); } } } }