//Loading file also loads open/closed status- should reset? //Set restrictvaters based on whether or not field is empty! //Change vater vated status when input is received //Restrict vaters //What if I deselect an item from the choice list and do stuff? //when loading a file with an empty list of choices, barfs //Change vaters to a treemap (sorted)? import java.awt.*; import java.awt.event.*; import java.applet.*; import javax.swing.*; import java.io.*; import java.util.*; import java.net.*; import java.text.*; //import java.beans.*; /* This server creates a GUI for a user to set up "vating"- polls, election voting, preference ranking, etc- and administer them * to client applets. * Chad Schultz */ public class Server extends Applet { int port = 7000; // Port number int loginNumber = 0; // For counting logins ArrayList threads; // For storing thread references VatingSet data; //This is where we store all the data the user creates Map vatings; //List of vatings (questions) Map choices; //List of options in each vating Vating currentVating; Choice currentChoice; java.awt.List currentChoiceList; //Copy of listbox in GUI; this stores the data int maxTitle = 42; //Maximum number of characters allowable in Title Combo Box (based on wide chars like M and W) to avoid breaking GUI int maxChoice = 20; //Maximum number of characters allowable in Choice List Box (based on wide chars like M and W) to avoid breaking GUI int maxWidth = 630; //Dimensions for applet window int maxHeight = 650; String newChoice = " "; //User clicks this in listbox to create a new choice String openPublicVating = new String("Open Public Vating "); //Add a space to make the button large enough for the alternate caption String closePublicVating = new String ("Close Public Vating"); //Toggle message: allow users to vote/rate/sort, or no? String showResultsYes = new String(" Make Results Available "); //Toggle message: allow users to see results or no? String showResultsNo = new String("Make Results Unavailable"); JPanel headerPanel; //Program title and credits JLabel headerLabel; //"Vating Booth by Chad Schultz - Voting / Rating System" JTextArea help; //Context-sensitive help information String helpMessage = "Welcome to the vating (voting/sorting/rating) booth! Please set up your vating as you wish. Click on\n" +"any object for more instructions.\n"; //Initial message displayed to user JLabel vatingLabel; //"Select vating:" JComboBox vatingCombo; //List of "vatings," each poll/vote/etc JPanel titlePanel; JLabel titleLabel; //"Description of vating:" JTextArea titleText; //displays information about poll/etc JPanel typePanel; ButtonGroup type; //Radio buttons to select whether this is a sorting, rating, or voting vating JRadioButton sortButton; JRadioButton rateButton; JRadioButton voteButton; JPanel choicesPanel; JLabel choiceLabel; //"Choices:" java.awt.List choiceListBox; //Displays listbox of candidates for votes, good/fair/poor ratings, etc. JPanel movePanel; JButton moveUp; //Only for sorting vatings: move items up in the list JButton moveDown; //Only for sorting vatings: move items down in the list JPanel detailPanel; JLabel choiceNameLabel; //"Choice name:" JTextField choiceNameField; //Shows name of the choice, the same as what appears in choiceListBox JTextArea choiceDescription; //Detailed information on individual choice JPanel vaterPanel; JLabel vaterLabel; //"Valid vaters:" JTextArea validVaters; //Type in names of those who can vate JPanel buttonPanel; JButton save; //Write data on vating to file JButton load; //Load vating data from file MyPublicVating publicVating; //Start or stop allowing users to vate MyResults results; //Start or stop allowing users to see results MyReset reset; JFrame frame; JPanel mainPanel; public static void main(String[] args) { Server me = new Server(); me.go(); } public void go() { frame = new JFrame("Vating Booth 1.0 Server"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(maxWidth, maxHeight); mainPanel = new JPanel(); frame.getContentPane().add(mainPanel); //Set up GUI //resize(maxWidth, maxHeight); //We need lots of room! //headPanel contains the title, help information, and the combo box to select a vating headerPanel = new JPanel(); headerPanel.setPreferredSize(new Dimension(maxWidth,165)); mainPanel.add(headerPanel); headerLabel = new JLabel("Vating Booth 1.0 - Server"); //Yay titles! headerLabel.setFont(new Font("SansSerif", Font.BOLD, 18)); headerPanel.add(headerLabel); // help = new JTextArea(helpMessage,5,80); //We'll use this to display context-sensitive messages to user help = new JTextArea(helpMessage,5,55); //We'll use this to display context-sensitive messages to user help.setEditable(false); //Hands off! JScrollPane helpScroll = new JScrollPane(help); headerPanel.add(helpScroll); //headerPanel.add(help); vatingLabel = new JLabel("Select vating:"); headerPanel.add(vatingLabel); //The long vatingcombo entry forces the combobox to the maximum width it can be without breaking the GUI vatingCombo = new JComboBox(new String[] {" "}); headerPanel.add(vatingCombo); vatingCombo.addActionListener(new VatingComboListener()); //typePanel holds the radio buttons to show the type of the vating, which affects how the user gives input and how it is scored typePanel = new JPanel(); typePanel.setPreferredSize(new Dimension(maxWidth,25)); mainPanel.add(typePanel); type = new ButtonGroup(); //Logical grouping of radio buttons String sortString = new String("Sort"); sortButton = new JRadioButton(sortString); //Code for "sort" type of vating sortButton.setActionCommand(sortString); sortButton.addActionListener(new SortButtonListener()); sortButton.setSelected(true); type.add(sortButton); typePanel.add(sortButton); String rateString = new String("Rate"); rateButton = new JRadioButton(rateString); //Code for "rate" type of vating rateButton.setActionCommand(rateString); rateButton.addActionListener(new RateButtonListener()); type.add(rateButton); typePanel.add(rateButton); String voteString = new String("Vote"); voteButton = new JRadioButton(voteString); //Code for "vote" type of vating voteButton.setActionCommand(voteString); voteButton.addActionListener(new VoteButtonListener()); type.add(voteButton); typePanel.add(voteButton); //Just holds title/description of vating titlePanel = new JPanel(); titlePanel.setPreferredSize(new Dimension(maxWidth, 60)); mainPanel.add(titlePanel); titleLabel = new JLabel("Description of vating:"); titlePanel.add(titleLabel); titleText = new JTextArea("",2,55); titleText.addFocusListener(new TitleTextFocusListener()); JScrollPane titleTextScroll = new JScrollPane(titleText); titlePanel.add(titleTextScroll); //titlePanel.add(titleText); //Holds listbox showing choices for a vating: the options for the vater to vote, rate, or sort choicesPanel = new JPanel(); choicesPanel.setPreferredSize(new Dimension(200,200)); mainPanel.add(choicesPanel); choiceLabel = new JLabel("Choices: "); //Make it nice and wide, so it doesn't "flow" beside the listbox- put it on its own row! choicesPanel.add(choiceLabel); choiceListBox = new java.awt.List(8); //8 rows display at a time choiceListBox.add(newChoice); //Always display , for the user to select when adding a new entry choiceListBox.select(0); choiceListBox.addItemListener(new ChoiceListBoxListener()); choicesPanel.add(choiceListBox); //movePanel shows move up/move down buttons to reorder items in listbox movePanel = new JPanel(); choicesPanel.add(movePanel); moveUp = new JButton("Move Up"); movePanel.add(moveUp); moveUp.addActionListener(new MoveUpListener()); moveDown = new JButton("Move Down"); movePanel.add(moveDown); moveDown.addActionListener(new MoveDownListener()); //detailPanel shows name and description of an individually selected choice detailPanel = new JPanel(); detailPanel.setPreferredSize(new Dimension(390,200)); mainPanel.add(detailPanel); choiceNameLabel = new JLabel("Choice name:"); detailPanel.add(choiceNameLabel); choiceNameField = new JTextField(30); choiceNameField.addFocusListener(new ChoiceNameFieldFocusListener()); detailPanel.add(choiceNameField); choiceDescription = new JTextArea("",9,35); choiceDescription.setLineWrap(true); // JScrollPane choiceDescriptionScroll = new JScrollPane(choiceDescription,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); JScrollPane choiceDescriptionScroll = new JScrollPane(choiceDescription); detailPanel.add(choiceDescriptionScroll); //detailPanel.add(choiceDescription); choiceDescription.addFocusListener(new ChoiceDescriptionFocusListener()); //vaterPanel shows names of those who are allowed to vate vaterPanel = new JPanel(); vaterPanel.setPreferredSize(new Dimension(maxWidth,90)); mainPanel.add(vaterPanel); vaterLabel = new JLabel("Valid vaters (separated by commas or line breaks):"); vaterPanel.add(vaterLabel); validVaters = new JTextArea(3,55); validVaters.setLineWrap(true); JScrollPane validVatersScroll = new JScrollPane(validVaters); vaterPanel.add(validVatersScroll); validVaters.addFocusListener(new ValidVatersFocusListener()); // vaterPanel.add(validVaters); //buttonPanel holds the command buttons for the main functionality of program buttonPanel = new JPanel(); buttonPanel.setPreferredSize(new Dimension(maxWidth,40)); mainPanel.add(buttonPanel); save = new JButton("Save"); buttonPanel.add(save); save.addActionListener(new SaveListener()); load = new JButton("Load"); buttonPanel.add(load); load.addActionListener(new LoadListener()); publicVating = new MyPublicVating(openPublicVating); buttonPanel.add(publicVating); publicVating.addActionListener(new PublicVatingListener()); results = new MyResults(showResultsYes); buttonPanel.add(results); results.addActionListener(new ResultsListener()); reset = new MyReset("Reset"); buttonPanel.add(reset); reset.addActionListener(new ResetListener()); //Let's get connected! SocketAccepter t = new SocketAccepter(); t.start(); data = new VatingSet(); //This is where we put all our data vatings = data.getVatings(); currentVating = new Vating(); choices = currentVating.getChoices(); currentChoice = new Choice(); currentChoiceList = currentVating.getChoiceList(); frame.setVisible(true); } //End of init() /* Extension of JButton to allow for special functionality in loading all the data * into its proper places when an item is selected from the vatingCombo. Also called * when loading data from a file. * Chad Schultz */ class MyReset extends JButton { public MyReset(String s) { super(s); } public void loadData() { //Load data into GUI if (vatingCombo.getSelectedIndex() != vatingCombo.getItemCount() - 1) { //If is not selected currentVating = (Vating) vatings.get(vatingCombo.getSelectedItem()); } else { currentVating = new Vating(); } //Load vating title titleText.setText(currentVating.getDescription()); //Load radio button if (currentVating.getType() == Vating.SORT) { sortButton.setSelected(true); } else if (currentVating.getType() == Vating.RATE) { rateButton.setSelected(true); } else if (currentVating.getType() == Vating.VOTE) { voteButton.setSelected(true); } //Load choice list choices = currentVating.getChoices(); currentChoiceList = currentVating.getChoiceList(); choiceListBox.removeAll(); for (int j=0; j < currentChoiceList.getItemCount(); j++) { choiceListBox.add(currentChoiceList.getItem(j)); } choiceListBox.select(0); //Load choice name and description if (choiceListBox.getSelectedIndex() == choiceListBox.getItemCount() - 1) { //If is selected choiceNameField.setText(""); choiceDescription.setText(""); } else { if (choiceListBox.getItemCount()>1) { currentChoice = (Choice) choices.get(choiceListBox.getSelectedItem()); choiceNameField.setText(currentChoice.getName()); choiceDescription.setText(currentChoice.getDescription()); } } } } /* An extension of JButton to allow for specialized functionality * for the publicVating button. * Chad Schultz */ class MyPublicVating extends JButton { public MyPublicVating(String s) { super(s); //Pass information up to JButton constructor } public void update() { //Called when loading or resetting to ensure buttons are set properly if (data.getVatingOpen()) //If vating is open... publicVating.setText(closePublicVating); //"Close Public Vating" else publicVating.setText(openPublicVating); //"Open Public Vating" } public void toggle() { if(data.getVatingOpen()) { //If vating is OPEN, button will say "Close Public Vating" publicVating.setText(openPublicVating); //Change it to say "Open Public Vating" data.setVatingOpen(false); //Vating now closed! help.setText("Users now may no longer add to the results."); } else { //If vating is CLOSED, so button says "Open Public Vating" publicVating.setText(closePublicVating); //Flip it to "Close Public Vating" data.setVatingOpen(true); //Flip it; NOW vating is open help.setText("Users now may sort, rate, and vote."); } } } /* An extension of JButton to allow for specialized functionality * for the results button. * Chad Schultz */ class MyResults extends JButton { public MyResults(String s) { super(s); //Pass information to JButton constructor } public void update() { //Called when loading or resetting to ensure buttons are set properly if (data.getResultsOpen()) results.setText(showResultsNo); else results.setText(showResultsYes); } public void toggle() { if(data.getResultsOpen()) { //If we ARE showing results, flip it results.setText(showResultsYes); //Stop showing results. Button will now say "Make Results Available" data.setResultsOpen(false); } else { //If we ARE NOT showing results, flip it results.setText(showResultsNo); //Start showing results. Button will now say "Make Results Unavailable" data.setResultsOpen(true); } System.out.println("Set resultsOpen to: "+data.getResultsOpen()); } } /* Class to create a thread for each connected client. * Chad Schultz */ class ServerThread extends Thread { // Variables boolean alive; // For continuing thread processing int threadNum; // For holding assigned thread number Socket s; // Reference for the thread's Socket ObjectOutputStream toClient; // For writing objects to the client ObjectInputStream fromClient; // For reading objects from the client //XMLEncoder toClient; //XMLDecoder fromClient; // This constructor initializes the ServerThread object, creates // object streams for communicating with the client, and sends the // client its Integer thread number. public ServerThread(Socket mySocket, int myThreadNum) { s = mySocket; threadNum = myThreadNum; try { toClient = new ObjectOutputStream(s.getOutputStream()); fromClient = new ObjectInputStream(s.getInputStream()); // toClient = new XMLEncoder(new BufferedOutputStream(new ObjectOutputStream(s.getOutputStream()))); // fromClient = new XMLDecoder(new BufferedInputStream(new ObjectInputStream(s.getInputStream()))); toClient.writeObject(new Integer(threadNum)); // toClient.writeObject(new VatingSet()); toClient.flush(); help.append("Thread " + threadNum + ": Connected" + "\n"); } catch(IOException err) { help.append("Thread " + threadNum + ": " + err.getMessage() + "\n"); } } // This method defines thread processing with the client. The thread is // marked as being alive, then it loops to handle client requests until // it is killed. public void run() { alive = true; VatingSet input; while (alive) { try { /* toClient.writeObject(data); VatingSet input = (VatingSet)fromClient.readObject(); toClient.writeObject(data);*/ Boolean vatable; String request = (String)fromClient.readObject(); // Processing for request to access the vating. if (request.equals("DATA")) { System.out.println("DATA request"); vatable = data.getVatingOpen(); toClient.writeObject(vatable); toClient.flush(); if (vatable) { toClient.writeObject(data); toClient.flush(); } } // Processing for request to view vating results. else if (request.equals("RESULTS")) { Boolean resultable = data.getResultsOpen(); System.out.println("Can we let them see results? "+resultable); toClient.writeObject(resultable); toClient.flush(); if (resultable) { toClient.writeObject(data); toClient.flush(); } } else if (request.equals("VATE")) { vatable = data.getVatingOpen(); toClient.writeObject(vatable); toClient.flush(); if (vatable) { // VatingSet input = new VatingSet(); input = new VatingSet(); input = (VatingSet)fromClient.readObject(); // data = (VatingSet)fromClient.readObject(); data.addVate(); //Increment the counter for number of people who have vated Map vs = input.getVatings(); Vating userV = new Vating(); Vating dataV = new Vating(); Iterator p = vs.keySet().iterator(); Map cs = new HashMap(); Map ds = new HashMap(); while (p.hasNext()) { userV = (Vating) vs.get(p.next()); dataV = (Vating) vatings.get(userV.getName()); cs = userV.getChoices(); ds = dataV.getChoices(); Iterator q = cs.keySet().iterator(); Choice userC = new Choice(); Choice dataC = new Choice(); int score; while (q.hasNext()) { userC = (Choice) cs.get(q.next()); dataC = (Choice) ds.get(userC.getName()); score = dataC.getScore(); score += userC.getScore(); dataC.setScore(score); // userC.setScore(0); // ds.remove(userC.getName()); // ds.put(userC.getName(),userC); dataC = (Choice) ds.get(userC.getName()); System.out.println("Score for: "+dataC.getName()+" is now: "+dataC.getScore()); } } } } // Processing for a "DISCONNECT" request. else if (request.equals("DISCONNECT")) { alive = false; help.append("Thread " + threadNum + ": DISCONNECTING" + "\n"); } // Processing for an invalid request. The thread is killed due to // the difficulty of re-synchronizing client communications. else { alive = false; help.append("Thread " + threadNum + ": INVALID: " + request + "\n"); } } catch (Exception err) { alive = false; help.append("Thread " + threadNum + ": " + err.getMessage() + "\n"); } } // Close the object streams as thread processing ends. try { fromClient.close(); toClient.close(); help.append("Thread " + threadNum + ": DISCONNECTED" + "\n"); } catch (Exception err) { help.append("Thread " + threadNum + ": " + err.getMessage() + "\n"); } } // This method can be called to kill the thread's processing loop. public void kill() { alive = false; } // This method can be called to safely update the collection in a // multithreaded environment. /* public synchronized boolean safeUpdate() { if (employees.containsKey(new Integer(emp.getNumber()))) { return false; } else { employees.put(new Integer(emp.getNumber()), emp); return true; } } }*/ } //do same thing when enter is pressed public class TitleTextFocusListener implements FocusListener { public void focusLost(FocusEvent e) { int insertAt; String title = new String(titleText.getText()); title = title.trim(); if (title.length() > maxTitle) { title = title.substring(0,maxTitle); } if (!vatings.containsKey(title)) { if (vatingCombo.getSelectedIndex() == vatingCombo.getItemCount() - 1) { //If is selected insertAt = vatingCombo.getItemCount() - 1; //Add a new item at end, before } else { insertAt = vatingCombo.getSelectedIndex(); //We'll take out the "old" item and put the modified one in the same place vatings.remove(vatingCombo.getSelectedItem()); vatingCombo.removeItemAt(vatingCombo.getSelectedIndex()); } if (title.length() > 0) { vatingCombo.insertItemAt(title,insertAt); currentVating.setName(title); currentVating.setDescription(titleText.getText()); // currentVating = new Vating(title,titleText.getText()); vatings.put(title,currentVating); vatingCombo.setSelectedIndex(insertAt); } data.setVatingCombo(vatingCombo); System.out.println("Number of vatings:"); System.out.println(data.getVatingCombo().getItemCount()); } else help.setText("Vating with this name already exists! Not entered."); } public void focusGained (FocusEvent e) { help.setText("Enter a description for the vating, such as \"Question 1\" or \"Who do you want for president?\" \nSelect" +" from the vating drop-down list and type in a description to add a new item. You may select an" +"existing item in the list and change it, or select it and clear the description field to remove it." +"\nClick anywhere else to update the list."); } } /* Implements actions for the vatingCombo when clicked. * Chad Schultz */ public class VatingComboListener implements ActionListener { public void actionPerformed(ActionEvent e) { reset.loadData(); //Load type, choice name and description help.setText("A vating (for example, a poll question) is one coherent list of choices for the user to give input on.\n" + "Click on and type a description into the box to create a new one and create the choice list."); } } public class SortButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { currentVating.setType(Vating.SORT); help.setText("A sorting vating allows the user to rank the choices in order of preference.\n"); } } public class RateButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { currentVating.setType(Vating.RATE); help.setText("A rating vating gives a list of choices, such as numbers or \"fair, good, great\"\n" + "and allows the user to select one. The results average the scores to decide which option\n" + "is closest to majority opinion."); } } public class VoteButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { currentVating.setType(Vating.VOTE); help.setText("A voting vating is simple and straightforward, useful for polls and elections:\n" + "you have several choices and you pick one. The one that the most people pick ends up on top."); } } //When you enter a choice name and click on the list, it changes what you click on, not what was selected- if is selected, it creates a new item. Is that a bug or a feature? LOL public class ChoiceNameFieldFocusListener implements FocusListener { public void focusLost(FocusEvent e) { int insertAt; String choice = new String(choiceNameField.getText()); choice = choice.trim(); if (choice.length() > maxChoice) { choice = choice.substring(0,maxChoice); } if (!choices.containsKey(choice)) { if ((choiceListBox.getSelectedIndex() == choiceListBox.getItemCount() - 1) || (choiceListBox.getSelectedIndex() < 0)){ //If is selected insertAt = choiceListBox.getItemCount() - 1; //Add a new item at end, before } else { insertAt = choiceListBox.getSelectedIndex(); //We'll take out the "old" item and put the modified one in the same place /* if (insertAt < 0) { insertAt = 1; choiceListBox.select(insertAt); }*/ choices.remove(choiceListBox.getSelectedItem()); choiceListBox.remove(insertAt); currentChoiceList.remove(insertAt); } if (choiceNameField.getText().length() > 0) { choiceListBox.add(choice,insertAt); currentChoiceList.add(choice,insertAt); currentChoice = new Choice(choice,choiceDescription.getText()); choices.put(choice,currentChoice); choiceListBox.select(insertAt); } // currentVating.setChoiceList(choiceListBox); } else help.setText("Choice with this name already exists! Not entered."); } public void focusGained (FocusEvent e) { help.setText("Enter a name for the option, such as \"Fair\" or \"Garfield\" \nSelect" +" from the choice list box and type in a name to add a new item. You may select an" +"\nexisting item in the list and change it, or select it and clear the description field to remove it." +"\nClick anywhere else to update the list. Click \"\" to immediately add the item," +"\nor click the name of a choice in the list to rename that choice."); } } public class ChoiceDescriptionFocusListener implements FocusListener { public void focusLost(FocusEvent e) { String key = choiceNameField.getText(); if (choices.containsKey(key)) { choices.remove(key); currentChoice = new Choice(key,choiceDescription.getText()); choices.put(key,currentChoice); } } public void focusGained (FocusEvent e) { help.setText("Enter a detailed description about the choice here."); } } /* Loads choice name and description when user clicks a choice from the list * Chad Schultz */ public class ChoiceListBoxListener implements ItemListener { public void itemStateChanged(ItemEvent e) { if (choiceListBox.getSelectedIndex() == choiceListBox.getItemCount() - 1) { //If is selected choiceNameField.setText(""); choiceDescription.setText(""); } else { if (choiceListBox.getItemCount()>1) { //Only fetch data if we even have any valid choices in list currentChoice = (Choice) choices.get(choiceListBox.getSelectedItem()); choiceNameField.setText(currentChoice.getName()); choiceDescription.setText(currentChoice.getDescription()); } } //Context-sensitive help help.setText("Create a list of choices for your vating: for example, the candidates for an election.\n" + "Click on and enter the name and description for each one in turn."); } } /* Functionality for button that moves a choice up in the list * Chad Schultz */ public class MoveUpListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (choiceListBox.getSelectedIndex() != choiceListBox.getItemCount() - 1) { //Only move if is not selected int i = choiceListBox.getSelectedIndex(); if (i > 0) { //Don't move it up if it's at the top! String item = choiceListBox.getSelectedItem(); choiceListBox.remove(i); //Take the item out of the list and put it back one one row higher currentChoiceList.remove(i); //Duplicate all actions in our stored data i--; choiceListBox.add(item,i); currentChoiceList.add(item,i); choiceListBox.select(i); //Select the item we moved; the listbox should always have an item selected } } } } /* Functionality for button that moves a choice down in the list * Chad Schultz */ public class MoveDownListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (choiceListBox.getSelectedIndex() != choiceListBox.getItemCount() - 1) { //If is not selected int i = choiceListBox.getSelectedIndex(); //if there are three items, the last one () is index 2, and the next //to last is index 1. Therefore, only move the item down when it's less then 2 less //then the number of items if (i < choiceListBox.getItemCount()-2) { String item = choiceListBox.getSelectedItem(); choiceListBox.remove(i); //take it out and put it back at the right spot currentChoiceList.remove(i); i++; choiceListBox.add(item,i); currentChoiceList.add(item,i); choiceListBox.select(i); } } } } public class ValidVatersFocusListener implements FocusListener { public void focusLost(FocusEvent e) { StringTokenizer parser = new StringTokenizer(validVaters.getText(), ",\t\n\r\f"); Map names = new HashMap(); Vater currentName; String s; while (parser.hasMoreTokens()) { s = parser.nextToken(); s.toUpperCase(); currentName = new Vater(s); names.put(currentName.getName(),currentName); } data.setVaters(names); if (names.isEmpty()) //If there are no names for vaters... data.setRestrictVaters(false); //Then anyone can vate else data.setRestrictVaters(true); //Otherwise, people must enter a matching name to vate } public void focusGained (FocusEvent e) { help.setText("Enter the names (or passwords, id numbers, etc) of people who are allowed to vate.\n" +"When vating, the user must enter the name exactly as it is shown, except\n" +"that it is not case-sensitive. This means that if you have a space after\n" +"a line break or comma, the user will also have to type in the space."); } } /* Saves the data for the current vating to a disk file * Chad Schultz */ public class SaveListener implements ActionListener { public void actionPerformed(ActionEvent e) { try { JFileChooser fc = new JFileChooser(); fc.showSaveDialog(choicesPanel); //"Save File" dialog box File f = fc.getSelectedFile(); FileOutputStream fos = new FileOutputStream(f); //Allows writing of bytes to file ObjectOutputStream os = new ObjectOutputStream(fos); //Buffers fileoutputstream so objects can be converted to bytes os.writeObject(data); //Send all vating data to file os.close(); fos.close(); //added recently help.setText("File successfully saved to: "+f.getPath()); //Displays confirmation message } catch (Exception err) { help.setText("*** ERROR ***\n An I/O error has occurred\n"); help.append(err.getMessage()); } } } /* Loads data for the current vating from a disk file * Chad Schultz */ public class LoadListener implements ActionListener { public void actionPerformed(ActionEvent e) { try { JFileChooser fc = new JFileChooser(); fc.showOpenDialog(choicesPanel); //"Load File" dialog box File f = fc.getSelectedFile(); FileInputStream fis = new FileInputStream(f); //Allows reading of bytes from file ObjectInputStream is = new ObjectInputStream(fis); //Buffers fileinputstream so bytes can be converted to object data = (VatingSet) is.readObject(); //Get all vating data from file is.close(); vatings = data.getVatings(); //Poll questions, etc. //Load data into GUI //Load combo box JComboBox loadedCombo = data.getVatingCombo(); //So we can access stored data vatingCombo.removeAllItems(); //Clear the combobox on the GUI before filling it for (int i=0; i < loadedCombo.getItemCount(); i++) { vatingCombo.addItem(loadedCombo.getItemAt(i)); //Copy items from the stored data to the GUI } reset.loadData(); //Loads choice information //Load vaters Map names = new HashMap(); //Names of people allowed to vote/rate/sort Vater currentName; names = data.getVaters(); Iterator p = names.keySet().iterator(); //Load vater names into textbox, separated by commas. //First we load the first one, then we repeatedly load commas and names. This is to avoid starting or //Ending the textbox with a comma, which would confuse the program. if (p.hasNext()) { currentName = (Vater) names.get(p.next()); validVaters.setText(currentName.getName()); } while (p.hasNext()) { currentName = (Vater) names.get(p.next()); validVaters.append(","+currentName.getName()); } publicVating.update(); //Make sure "open/close public vating" is correctly toggled results.update(); //Make sure "make results available/unavailable" is correctly toggled help.setText("File successfully loaded from: "+f.getPath()); } catch (Exception err) { help.setText("*** ERROR ***\n An I/O error has occurred\n"); //Sadly, it has happened oft in development help.append(err.getMessage()); } } } public class PublicVatingListener implements ActionListener { public void actionPerformed(ActionEvent e) { publicVating.toggle(); } } public class ResultsListener implements ActionListener { public void actionPerformed(ActionEvent e) { results.toggle(); } } /* Clear data when reset button is pressed. Create a new data object * to overwrite the old one, then reset all the other data objects and * GUI elements to their initial state * Chad Schultz*/ public class ResetListener implements ActionListener { public void actionPerformed(ActionEvent e) { data = new VatingSet(); vatings = data.getVatings(); currentVating = new Vating(); choices = currentVating.getChoices(); currentChoice = new Choice(); currentChoiceList = currentVating.getChoiceList(); vatingCombo.removeAllItems(); vatingCombo.addItem(" "); sortButton.setSelected(true); titleText.setText(""); choiceListBox.removeAll(); choiceListBox.add(newChoice); choiceListBox.select(0); choiceNameField.setText(""); choiceDescription.setText(""); validVaters.setText(""); publicVating.update(); //Ensure toggle buttons show the right value results.update(); help.setText("Data cleared."); } } class SocketAccepter extends Thread { public void run() { try { ServerSocket ss = new ServerSocket(port); help.append("Server active" + "\n"); help.append("Address: " + InetAddress.getLocalHost() + "\n"); help.append("Port: " + port + "\n"); threads = new ArrayList(); while (true) { Socket s = ss.accept(); // Create a thread to process requests from the client, add it // to the list of threads, and start its processing. ServerThread thread = new ServerThread(s, loginNumber); threads.add(thread); thread.start(); loginNumber++; } } catch(IOException err) { help.append(err.getMessage() + "\n"); } } } } //End of server class /* VatingSet holds allll the data that the user creates: the set * of polling questions, etc, as well as other settings * Chad Schultz */ class VatingSet implements Serializable { //Serializable, so we can save it do disk private int vates; //Number of times people have vated private boolean vatingOpen; //Can users save vates right now? private boolean resultsOpen; //Can users view results right now? private boolean restrictVaters; //Require valid vater name Map vaters; //Map of Vater objects: who is allowed to vate Map vatings; //Map of vating objects: what people can vote/rate/sort JComboBox vCombo; public VatingSet () { vates = 0; vatingOpen = false; resultsOpen = false; restrictVaters = false; vaters = new HashMap(); vatings = new HashMap(); vCombo = new JComboBox(); } public int getVates() { return vates; } public synchronized void addVate() { //The number of votes/etc. Increment whenever a client sends us data vates = vates + 1; } public Boolean getVatingOpen() { //Can people vote/rate/sort? return vatingOpen; } public void setVatingOpen(Boolean b) { vatingOpen = b; } public Boolean getResultsOpen() { //Can people view the results? Note that people may be able to view results even after vating is closed, or may be able to vate without seeing results return resultsOpen; } public void setResultsOpen(Boolean b) { resultsOpen = b; } public Boolean getRestrictVaters() { return restrictVaters; } public void setRestrictVaters(Boolean b) { restrictVaters = b; } public Map getVaters() { return vaters; } public void setVaters(Map m) { vaters = m; } public Map getVatings() { return vatings; } public void setVatings(Map m) { vatings = m; } public JComboBox getVatingCombo() { return vCombo; } public void setVatingCombo(JComboBox c) { vCombo = c; } } /* Data for the name of a single person who is allowed to vate * Chad Schultz */ class Vater implements Serializable { private String name; private Boolean vated; public Vater(String n) { name = n; vated = false; //Have they already vated? } public String getName() { return name; } public void setName(String n) { name = n; } public Boolean getVated() { return vated; } public void setVated(Boolean b) { vated = b; } } /* Data for one poll question/etc. * Chad Schultz */ class Vating implements Serializable { private String name; private String description; public static int SORT = 0; //Codes for option button values in type public static int RATE = 1; public static int VOTE = 2; private int type; //Sort, rate, vote? private Map choices; //List of choices (such as candidates in an election) in a single vating private java.awt.List choiceList; //Storing the list object preserves much data- for example, the order of the choices. public Vating () { name = ""; description = ""; type = SORT; choices = new HashMap(); choiceList = new java.awt.List(); choiceList.add(" "); } public Vating (String n, String d) { name = n; description = d; type = SORT; choices = new HashMap(); choiceList = new java.awt.List(); choiceList.add(" "); } public String getName() { return name; } public void setName(String n) { name = n; } public String getDescription() { return description; } public void setDescription(String d) { description = d; } public int getType() { return type; } public void setType(int t) { type = t; } public Map getChoices() { return choices; } public void setChoices(Map m) { choices = m; } public java.awt.List getChoiceList() { return choiceList; } public void setChoiceList(java.awt.List l) { choiceList = l; } } /* The data for one single possible answer in one question * Chad Schultz */ class Choice implements Serializable { private String name; private String description; private int place; //Order in list private int score; public Choice () {} public Choice(String n, String d) { name = n; description = d; place = 0; score = 0; } public String getName() { return name; } public void setName(String n) { name = n; } public String getDescription() { return description; } public void setDescription(String d) { description = d; } public int getPlace() { return place; } public void setPlace(int p) { place = p; } public int getScore() { return score; } public void setScore(int s) { score = s; } }