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(); // } // } // } }