package event.editor; import java.awt.BorderLayout; import java.awt.Color; import java.awt.FlowLayout; import javax.swing.*; import java.util.*; import java.awt.event.*; import scriptbuilder.structures.events.*; enum UpdateType { Add, Remove, TitleChange } class PropertyUpdate { private UpdateType type; private PropertyPanel panel; private int position = -1; public PropertyUpdate(UpdateType theType, PropertyPanel thePanel) { type = theType; panel = thePanel; } public PropertyUpdate(UpdateType theType, PropertyPanel thePanel, int thePosition) { this(theType, thePanel); position = thePosition; } public int getPosition() { if (position == -1) { throw new RuntimeException("position unknown"); } return position; } public UpdateType getType() { return type; } public PropertyPanel getPanel() { return panel; } } enum PropertyTypes { Optional, Multiple; } class PropertyPanel { private final JPanel panel; private final Properties property; public PropertyPanel(JPanel thePanel, Properties theProperty) { panel = thePanel; property = theProperty; } public JPanel getPanel() { return panel; } public Properties getProperty() { return property; } public String title() { return property.getTitle(); } } class MultPropertyPanel extends PropertyPanel { private int index; public MultPropertyPanel(JPanel thePanel, Properties theProperty, int theIndex) { super(thePanel, theProperty); index = theIndex; } public int getIndex() { return index; } public void setIndex(int newIndex) { index = newIndex; } @Override public String title() { return super.title() + " " + index; } } class PropertyPanels extends Observable { private Vector properties = new Vector(); private EnumMap propertyCounter = new EnumMap(Properties.class); public PropertyPanels() { for (Properties property : Properties.values()) { propertyCounter.put(property, 0); } } private int nextIndex(Properties property) { propertyCounter.put(property, propertyCounter.get(property) + 1); return propertyCounter.get(property); } /** * public Vector getProperties() { return * (Vector) properties.clone(); } */ private int add(PropertyPanel panel) { int position = 0; for (int i = 0; i < properties.size(); i++) { if (properties.get(i).title().compareTo(panel.title()) < 0) { position = i + 1; } } properties.add(position, panel); return position; } public PropertyPanel addPropertyPanel(Properties property, JPanel panel) { PropertyPanel propertyPanel = null; if (property.getType() == PropertyTypes.Multiple) { propertyPanel = new MultPropertyPanel(panel, property, nextIndex(property)); //propertyPanel.addObserver(this); int position = add(propertyPanel); setChanged(); notifyObservers(new PropertyUpdate(UpdateType.Add, propertyPanel, position)); } else if (property.getType() == PropertyTypes.Optional) { if (containsProperty(property)) { throw new RuntimeException("Property \"" + property + "\" is already added"); } else { propertyPanel = new PropertyPanel(panel, property); int position = add(propertyPanel); //propertyPanel.addObserver(this); setChanged(); notifyObservers(new PropertyUpdate(UpdateType.Add, propertyPanel, position)); } } else { throw new RuntimeException("Property \"" + property + "\" not accounted for"); } return propertyPanel; } private boolean remove(PropertyPanel panel) { boolean result = false; if ((result = properties.remove(panel))) { setChanged(); notifyObservers(new PropertyUpdate(UpdateType.Remove, panel)); } else { throw new RuntimeException("Attempted to remove panel that did not exist"); } if (panel.getProperty().getType() == PropertyTypes.Multiple) { Vector panelsOfSameType = new Vector(); Vector panelsOfGreaterIndex = new Vector(); propertyCounter.put(panel.getProperty(), propertyCounter.get(panel.getProperty()) - 1); // extract panels of the same property type for (PropertyPanel pan : properties) { if (pan.getProperty() == panel.getProperty()) { panelsOfSameType.add((MultPropertyPanel) pan); } } // extract panels whose index is greater than the index of the panel // being removed for (MultPropertyPanel pan : panelsOfSameType) { if (pan.getIndex() > ((MultPropertyPanel) panel).getIndex()) { panelsOfGreaterIndex.add(pan); } } // decrement the index of each of the remaining panels by one for (MultPropertyPanel pan : panelsOfGreaterIndex) { pan.setIndex(pan.getIndex() - 1); setChanged(); notifyObservers(new PropertyUpdate(UpdateType.TitleChange, pan)); } } else if (panel.getProperty().getType() == PropertyTypes.Optional) { // do nothing } else { throw new RuntimeException("PropertyTypes not accounted for"); } return result; } public PropertyPanel removeProperty(Properties property) { if (property.getType() == PropertyTypes.Multiple) { throw new RuntimeException("Attemping to remove a property of multiple type"); } PropertyPanel removed = null; for (PropertyPanel panel : properties) { if (panel.getProperty() == property) { removed = panel; } } if (removed == null) { throw new RuntimeException("Could not find panel with property \"" + property + "\""); } remove(removed); return removed; } public PropertyPanel removeProperty(JPanel jPanel) { PropertyPanel removed = null; for (PropertyPanel panel : properties) { if (panel.getPanel() == jPanel) { removed = panel; } } if (removed == null) { throw new RuntimeException("Could not find jPanel"); } remove(removed); return removed; } public PropertyPanel removeProperty(String title) { PropertyPanel removed = null; for (PropertyPanel panel : properties) { if (panel.title().equals(title)) { if (removed == null) { removed = panel; } else { throw new RuntimeException("Attempted to remove a property by title but the title was not unique"); } } } if (removed == null) { throw new RuntimeException("Did not find titel \"" + title + "\""); } remove(removed); return removed; } public boolean removeProperty(PropertyPanel panel) { return remove(panel); } public boolean containsProperty(Properties property) { boolean contains = false; for (PropertyPanel panel : properties) { if (panel.getProperty() == property) { contains = true; } } return contains; } } class PropertyModel extends Observable implements Observer { PropertyPanels properties = new PropertyPanels(); private EnumMap classMap = new EnumMap(Properties.class); public PropertyModel() { classMap.put(Properties.ATMS, GenericEvaluationPanel.class); classMap.put(Properties.ActivityLog, GenericEvaluationPanel.class); classMap.put(Properties.CAD, GenericEvaluationPanel.class); classMap.put(Properties.Facilitator, GenericEvaluationPanel.class); classMap.put(Properties.Radio, GenericEvaluationPanel.class); classMap.put(Properties.MaintenanceRadio, MaintenanceRadioPanel.class); classMap.put(Properties.TMTRadio, TMTRadioPanel.class); classMap.put(Properties.CHPRadio, CHPRadioPanel.class); classMap.put(Properties.Telephone, TelephonePanel.class); classMap.put(Properties.Audio, AudioPanel.class); classMap.put(Properties.CADLog, CADLogPanel.class); classMap.put(Properties.CCTV, CCTVPanel.class); classMap.put(Properties.CMS, CMSEvaluationPanel.class); classMap.put(Properties.Paramics, ParamicsPanel.class); classMap.put(Properties.Tow, TowPanel.class); classMap.put(Properties.Unit, UnitPanel.class); classMap.put(Properties.Witness, WitnessPanel.class); properties.addObserver(this); } public void addProperty(Properties property, I_ScriptEvent se) { try { JPanel panel = (JPanel) classMap.get(property).newInstance(); final PropertyPanel propertyPanel = properties.addPropertyPanel(property, panel); if (panel instanceof ScriptEventEditorPanel) { ((ScriptEventEditorPanel) panel).getEventObject(se); } if (property.getType() == PropertyTypes.Multiple) { if (panel instanceof RemoveablePanel) { ((RemoveablePanel) panel).setRemoveListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { properties.removeProperty(propertyPanel); } }); } else { throw new RuntimeException("Property was multiple but panel was not removeable"); } } } catch (Exception e) { System.err.println("Could not create panel of type \"" + property + "\""); } } public void removeProperty(Properties property) { properties.removeProperty(property); } public void update(Observable o, Object arg) { setChanged(); notifyObservers(arg); } /* public Vector getPropertyPanels() { return properties.getProperties(); } */ } public class Editor extends javax.swing.JFrame implements Observer { private PropertyModel model = new PropertyModel(); public PropertyModel getPropertyModel() { return model; } public void addProperty(Properties property, I_ScriptEvent se) { model.addProperty(property, se); } private ActionListener optionalChangeListener = new ActionListener() { public void actionPerformed(ActionEvent evt) { JCheckBoxMenuItem src = (JCheckBoxMenuItem) evt.getSource(); Properties property = Properties.valueOf(src.getText().replaceAll(" ", "")); if (src.isSelected()) { model.addProperty(property, new CCTVEvent()); } else { model.removeProperty(property); } } }; private ActionListener multipleChangeListener = new ActionListener() { public void actionPerformed(ActionEvent evt) { JMenuItem src = (JMenuItem) evt.getSource(); model.addProperty(Properties.valueOf(src.getText().replaceAll(" ", "")), new CCTVEvent()); } }; public Editor() { initComponents(); model.addObserver(this); // For each menu for (int menuCtr = 0; menuCtr < jMenuBar1.getMenuCount(); menuCtr++) { // for each menu item for (java.awt.Component comp : jMenuBar1.getMenu(menuCtr).getMenuComponents()) { JMenuItem item = (JMenuItem) comp; String itemName = item.getText().replaceAll(" ", ""); Properties property = Properties.valueOf(itemName); if (property.getType() == PropertyTypes.Multiple) { item.addActionListener(multipleChangeListener); } else if (property.getType() == PropertyTypes.Optional) { item.addActionListener(optionalChangeListener); } else { throw new RuntimeException("Property type not accounted for"); } } } } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { jTabbedPane1 = new javax.swing.JTabbedPane(); jMenuBar1 = new javax.swing.JMenuBar(); jMenu1 = new javax.swing.JMenu(); ATMS = new javax.swing.JCheckBoxMenuItem(); ActivityLog = new javax.swing.JCheckBoxMenuItem(); CAD = new javax.swing.JCheckBoxMenuItem(); CMS = new javax.swing.JMenuItem(); Facilitator = new javax.swing.JCheckBoxMenuItem(); Radio = new javax.swing.JCheckBoxMenuItem(); JMenu2 = new javax.swing.JMenu(); MaintenanceRadio = new javax.swing.JCheckBoxMenuItem(); TMTRadio = new javax.swing.JCheckBoxMenuItem(); Telephone = new javax.swing.JCheckBoxMenuItem(); jMenu3 = new javax.swing.JMenu(); Audio = new javax.swing.JMenuItem(); CADLog = new javax.swing.JMenuItem(); CCTV = new javax.swing.JMenuItem(); CHPRadio = new javax.swing.JCheckBoxMenuItem(); Paramics = new javax.swing.JMenuItem(); Tow = new javax.swing.JMenuItem(); Unit = new javax.swing.JMenuItem(); Witness = new javax.swing.JMenuItem(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setTitle("Event Editor"); jMenu1.setText("Evaluations"); ATMS.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.event.InputEvent.CTRL_MASK)); ATMS.setText("ATMS"); ATMS.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/ATMSEval.png"))); // NOI18N ATMS.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { multipleChange(evt); } }); jMenu1.add(ATMS); ActivityLog.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.event.InputEvent.ALT_MASK)); ActivityLog.setText("Activity Log"); ActivityLog.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/ActivityLogEval.png"))); // NOI18N ActivityLog.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { multipleChange(evt); } }); jMenu1.add(ActivityLog); CAD.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.ALT_MASK)); CAD.setText("CAD"); CAD.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/CADEval.png"))); // NOI18N CAD.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { multipleChange(evt); } }); jMenu1.add(CAD); CMS.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.ALT_MASK | java.awt.event.InputEvent.CTRL_MASK)); CMS.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/CMSEval.png"))); // NOI18N CMS.setText("CMS"); CMS.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { multipleChangeListener(evt); } }); CMS.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { multipleChange(evt); } }); jMenu1.add(CMS); Facilitator.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F, java.awt.event.InputEvent.CTRL_MASK)); Facilitator.setText("Facilitator"); Facilitator.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/FacilitatorEval.png"))); // NOI18N Facilitator.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { optionalChange(evt); } }); jMenu1.add(Facilitator); Radio.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R, java.awt.event.InputEvent.CTRL_MASK)); Radio.setText("Radio"); Radio.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/RadioEval.png"))); // NOI18N Radio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { optionalChange(evt); } }); jMenu1.add(Radio); jMenuBar1.add(jMenu1); JMenu2.setText("Instructor Actions"); MaintenanceRadio.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_M, java.awt.event.InputEvent.CTRL_MASK)); MaintenanceRadio.setText("Maintenance Radio"); MaintenanceRadio.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/MaintenanceRadio.png"))); // NOI18N MaintenanceRadio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { optionalChange(evt); } }); JMenu2.add(MaintenanceRadio); TMTRadio.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_T, java.awt.event.InputEvent.ALT_MASK | java.awt.event.InputEvent.CTRL_MASK)); TMTRadio.setText("TMT Radio"); TMTRadio.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/TMTRadio.png"))); // NOI18N TMTRadio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { optionalChange(evt); } }); JMenu2.add(TMTRadio); Telephone.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_T, java.awt.event.InputEvent.SHIFT_MASK | java.awt.event.InputEvent.CTRL_MASK)); Telephone.setText("Telephone"); Telephone.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/Telephone.png"))); // NOI18N Telephone.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { optionalChange(evt); } }); JMenu2.add(Telephone); jMenuBar1.add(JMenu2); jMenu3.setText("Automated Data"); Audio.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.event.InputEvent.CTRL_MASK)); Audio.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/Audio.png"))); // NOI18N Audio.setText("Audio"); jMenu3.add(Audio); CADLog.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.CTRL_MASK)); CADLog.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/CAD.png"))); // NOI18N CADLog.setText("CAD Log"); jMenu3.add(CADLog); CCTV.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_V, java.awt.event.InputEvent.CTRL_MASK)); CCTV.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/CCTV.png"))); // NOI18N CCTV.setText("CCTV"); jMenu3.add(CCTV); CHPRadio.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.ALT_MASK)); CHPRadio.setText("CHP Radio"); CHPRadio.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/CHPRadio.png"))); // NOI18N CHPRadio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { optionalChange(evt); } }); jMenu3.add(CHPRadio); Paramics.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_P, java.awt.event.InputEvent.CTRL_MASK)); Paramics.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/Paramics.png"))); // NOI18N Paramics.setText("Paramics"); jMenu3.add(Paramics); Tow.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_T, java.awt.event.InputEvent.CTRL_MASK)); Tow.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/Tow.png"))); // NOI18N Tow.setText("Tow"); jMenu3.add(Tow); Unit.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_U, java.awt.event.InputEvent.CTRL_MASK)); Unit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/Unit.png"))); // NOI18N Unit.setText("Unit"); jMenu3.add(Unit); Witness.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_W, java.awt.event.InputEvent.CTRL_MASK)); Witness.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/Witness.png"))); // NOI18N Witness.setText("Witness"); jMenu3.add(Witness); jMenuBar1.add(jMenu3); setJMenuBar(jMenuBar1); org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .addContainerGap() .add(jTabbedPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 921, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .addContainerGap() .add(jTabbedPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 580, Short.MAX_VALUE) .addContainerGap()) ); pack(); }// //GEN-END:initComponents private void multipleChangeListener(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_multipleChangeListener }//GEN-LAST:event_multipleChangeListener private void multipleChange(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_multipleChange }//GEN-LAST:event_multipleChange private void optionalChange(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optionalChange }//GEN-LAST:event_optionalChange /** * @param args the command line arguments */ public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new Editor().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JCheckBoxMenuItem ATMS; private javax.swing.JCheckBoxMenuItem ActivityLog; private javax.swing.JMenuItem Audio; private javax.swing.JCheckBoxMenuItem CAD; private javax.swing.JMenuItem CADLog; private javax.swing.JMenuItem CCTV; private javax.swing.JCheckBoxMenuItem CHPRadio; private javax.swing.JMenuItem CMS; private javax.swing.JCheckBoxMenuItem Facilitator; private javax.swing.JMenu JMenu2; private javax.swing.JCheckBoxMenuItem MaintenanceRadio; private javax.swing.JMenuItem Paramics; private javax.swing.JCheckBoxMenuItem Radio; private javax.swing.JCheckBoxMenuItem TMTRadio; private javax.swing.JCheckBoxMenuItem Telephone; private javax.swing.JMenuItem Tow; private javax.swing.JMenuItem Unit; private javax.swing.JMenuItem Witness; private javax.swing.JMenu jMenu1; private javax.swing.JMenu jMenu3; private javax.swing.JMenuBar jMenuBar1; private javax.swing.JTabbedPane jTabbedPane1; // End of variables declaration//GEN-END:variables public void update(Observable o, Object arg) { final PropertyUpdate update = (PropertyUpdate) arg; final ImageIcon image = update.getPanel().getProperty().getImage(); final String caption = update.getPanel().title(); final JLabel title = new JLabel(caption, image, JLabel.CENTER); /* final BorderLayout layout = new BorderLayout(); final JPanel title = new JPanel(layout); title.setOpaque(false); title.add(new JLabel(image), BorderLayout.WEST); title.add(new JLabel(caption), BorderLayout.EAST); */ if (update.getType() == UpdateType.Add) { jTabbedPane1.insertTab(null, null, update.getPanel().getPanel(), null, update.getPosition()); jTabbedPane1.setTabComponentAt(update.getPosition(), title); jTabbedPane1.setSelectedIndex(update.getPosition()); } else if (update.getType() == UpdateType.Remove) { jTabbedPane1.remove(update.getPanel().getPanel()); } else if (update.getType() == UpdateType.TitleChange) { final int index = jTabbedPane1.indexOfComponent( update.getPanel().getPanel()); new Thread(new Runnable() { public void run() { Color c = jTabbedPane1.getForegroundAt(index); jTabbedPane1.setForegroundAt(index, Color.blue); try { Thread.sleep(350); } catch (Exception e) { } jTabbedPane1.setTabComponentAt(index, title); try { Thread.sleep(350); } catch (Exception e) { } jTabbedPane1.setForegroundAt(index, c); } }).start(); } else { throw new RuntimeException("UpdateType not accounted for"); } } }