Newer
Older
democall3 / src / gui / processors / RequestProcessor.java
package gui.processors;

import discovery.server.KnownClients;
import gui.QueuePanel;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;

/**
 *
 * @author Mark
 */
public abstract class RequestProcessor {

	private final Color helpCol = Color.GREEN;
	private final Color markingCol = Color.YELLOW;
	private final Color regularCol = new JLabel().getBackground();

	private final Map<Integer, Student> students = new ConcurrentHashMap<Integer, Student>();
	private final Set<JLabel> labels = new HashSet<JLabel>();

	protected final QueuePanel helpQueue;
	protected final QueuePanel markingQueue;

	public abstract MouseAdapter getMouseAdapter();
//	{
//		return new MouseAdapter() {
//
//			@Override
//			public void mousePressed(final MouseEvent e) {
//				super.mousePressed(e);
//				final JLabel label = (JLabel) e.getSource();
//				final Integer machine = new Integer(label.getText());
//
//				Status status = getStatus(machine);
//
//				if (status == Status.BOTH) {
//
//					final JPopupMenu menu = new JPopupMenu();
//
//					final JMenuItem cancelHelp = new JMenuItem("Cancel Help");
//					cancelHelp.addActionListener(new ActionListener() {
//
//						@Override
//						public void actionPerformed(final ActionEvent e) {
//							cancelHelp(machine);
//						}
//					});
//
//					final JMenuItem cancelMarking = new JMenuItem("Cancel Marking");
//					cancelMarking.addActionListener(new ActionListener() {
//
//						@Override
//						public void actionPerformed(final ActionEvent e) {
//							cancelMarking(machine);
//						}
//					});
//
//					menu.add(cancelHelp);
//					menu.add(cancelMarking);
//
//					menu.show((Component) e.getSource(), e.getX(), e.getY());
//
//				} else if (status == Status.HELP) {
//					cancelHelp(machine);
//				} else if (status == Status.MARKING) {
//					cancelMarking(machine);
//				}
//
//			}
//		};
//	}

	public RequestProcessor(QueuePanel helpPanel, QueuePanel markingPanel) {
		this.helpQueue = helpPanel;
		this.markingQueue = markingPanel;
	}

	public final void processLabels(final JPanel panel) {
		processPanel(panel);
	}

	private void processPanel(final JPanel panel) {
		for (Component component : panel.getComponents()) {

			if (component instanceof JLabel) {
				final JLabel label = (JLabel) component;
				try {
					// component must be opaque so the background color can be set
					label.setOpaque(true);
					final Integer id = Integer.valueOf(label.getText());
					students.put(id, new Student(id, label));
					labels.add(label);

					label.addMouseListener(this.getMouseAdapter());

				} catch (NumberFormatException ignored) {
					continue;
				}
			} else if (component instanceof JPanel) {
				// found a panel that might contain labels so recurse
				processPanel((JPanel) component);
			}
		}
	}

	public void resizeFonts(float newFontSize) {
		// there should always labels in this map so hopefully this next line doesn't cause issues
		Font newFont = labels.iterator().next().getFont().deriveFont(newFontSize);

		for (JLabel label : labels) {
			label.setFont(newFont);
		}

		helpQueue.setQueueFont(newFont);
		markingQueue.setQueueFont(newFont);
	}

	public final void requestHelp(final int id) {
		synchronized (helpQueue) {
			helpQueue.addRequest(id);
			students.get(id).addStatus(Status.HELP);
		}
		KnownClients.requestHelp(id);
	}

	public final void requestMarking(final int id) {
		synchronized (markingQueue) {
			markingQueue.addRequest(id);
			students.get(id).addStatus(Status.MARKING);
		}
		KnownClients.requestMarking(id);
	}

	public synchronized void cancelHelp(final int id) {
		synchronized (helpQueue) {
			helpQueue.removeRequest(id);
			students.get(id).removeStatus(Status.HELP);
		}
		KnownClients.cancelHelp(id);
	}

	public synchronized void cancelMarking(final int id) {
		synchronized (helpQueue) {
			markingQueue.removeRequest(id);
			students.get(id).removeStatus(Status.MARKING);
		}
		KnownClients.cancelMarking(id);
	}

	public final Collection<Integer> getHelpQueue() {
		synchronized (helpQueue) {
			// Creating a copy of helpQueue to prevent ConcurrentModification errors.
			// This only works because helpQueue is locked by the sync block
			return new ArrayList<Integer>(helpQueue.getQueue());
		}
	}
	
	public final Collection<Integer> getMarkingQueue() {
		synchronized (markingQueue) {
			// Creating a copy of helpQueue to prevent ConcurrentModification errors.
			// This only works because helpQueue is locked by the sync block
			return new ArrayList<Integer>(markingQueue.getQueue());
		}
	}
	
	public Status getStatus(Integer id) {
		return students.get(id).getStatus();
	}
	
//	private void updateTutorClients(Collection<Integer> queue1) {
//		Iterator<ObjectOutputStream> it = Constants.PERSISTENT_SOCKETS.iterator();
//		while (it.hasNext()) {
//			try {
//				ObjectOutputStream oos = it.next();
//				oos.reset(); // necessary since if you send the same object twice some "optimisations" happen causing the client to see cached versions of the object
//				oos.writeObject(helpQueue);
//				oos.flush();
//				System.out.println(helpQueue);
//			} catch (IOException ex) {
//				it.remove();
//			}
//		}
//	}
}