package org.clothocore.util.basic; import java.awt.Component; import java.awt.Font; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Hashtable; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JSeparator; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; import org.clothocore.api.core.Collator; import org.clothocore.api.core.Collector; import org.clothocore.api.core.wrapper.ViewerWrapper; import org.clothocore.api.data.*; import org.clothocore.util.elements.AutoComboBox; public class ObjBasePopup { /** * Create an ObjBase popup, but don't show it. This constructor * will log the appropriate listeners onto the GUI such that the popup * shows up on right click. * * @param Container * @param o */ public ObjBasePopup(Component container, ObjBase o) { _myObject = o; _guiComponent = container; initiatePopup(o); // define a MouseListener for the window that displays // a JPopupMenu when the popup trigger event occurs _guiComponent.addMouseListener( new MouseAdapter() { @Override public void mousePressed( MouseEvent e ) { checkForTriggerEvent( e ); } @Override public void mouseReleased( MouseEvent e ) { checkForTriggerEvent( e ); } private void checkForTriggerEvent( MouseEvent e ) { if ( e.isPopupTrigger() && _isActive) popupMenu.show( e.getComponent(), e.getX(), e.getY() ); } } ); } /** * Create and show an ObjBasePopup without the listeners on the calling * Component. No listeners get logged in by this constructor, the popup * just appears and then will disappear when the user clicks elsewhere. * @param selObj */ public ObjBasePopup(Component c, ObjBase o, Point p) { _myObject = o; _guiComponent = c; initiatePopup(o); popupMenu.show( c, p.x, p.y ); } /** * Add a JMenuItem the end of the popup table with the display string * label and the actionlistener ahandler * @param label the label that will be displayed on the menu * @param ahandler the action performed when the menuitem is selected */ public void addMenuItem(String label, ActionListener ahandler) { if(!this._hasPluginHeader) { //Add a "Special Actions" label: JLabel jumplabel = new JLabel(); jumplabel.setText("Special actions:"); jumplabel.setFont(new Font("Arial", Font.ITALIC, 10)); popupMenu.add( jumplabel ); //Add a separator JSeparator jsep2 = new JSeparator(); popupMenu.add( jsep2 ); _hasPluginHeader = true; } JMenuItem aMenu = new JMenuItem( label ); menuOptions.add(aMenu); popupMenu.add( aMenu ); aMenu.addActionListener( ahandler ); } /** * Add a JMenu to the end of the popup table. Use this if the * menu should branch out and do something fancy with its own * sub-JMenuItems * @param item */ public void addMenuItem(JMenu item) { popupMenu.add( item ); } /** * Add a JMenuItem to the end of the popup table * You need to have pre-added an ActionListener to the JMenuItem * for this to do anything * @param item */ public void addMenuItem(JMenuItem item) { popupMenu.add( item ); } private void initiatePopup(ObjBase o) { popupMenu = new JPopupMenu(); constructPopup(o, popupMenu); } private void constructPopup(ObjBase o, JComponent pooper) { Object[] _viewers = Collator.getAvailableViewers(o.getType()).toArray(); ItemHandler handler = new ItemHandler(o); JLabel headerlabel = new JLabel(); headerlabel.setText(o.getType().toString() + " " + o.getName()); headerlabel.setFont(new Font("Arial", Font.ITALIC, 10)); pooper.add( headerlabel ); //Add Save menu option JMenuItem saveMenu = new JMenuItem( "Save to database" ); menuOptions.add(saveMenu); pooper.add( saveMenu ); saveMenu.addActionListener( handler ); //Add Delete menu option JMenuItem delMenu = new JMenuItem( "Delete" ); menuOptions.add(delMenu); // pooper.add( delMenu ); //since method isn't implemented, this is currently silenced delMenu.addActionListener( handler ); //Add Update menu option JMenuItem updateMenu = new JMenuItem( "Update" ); menuOptions.add(updateMenu); pooper.add( updateMenu ); updateMenu.addActionListener( handler ); //Add Delete menu option JMenuItem revMenu = new JMenuItem( "Revert" ); menuOptions.add(revMenu); pooper.add( revMenu ); revMenu.addActionListener( handler ); //Add undo menu option JMenuItem undoMenu = new JMenuItem( "Undo" ); menuOptions.add(undoMenu); pooper.add( undoMenu ); undoMenu.addActionListener( handler ); //Add redo menu option JMenuItem redoMenu = new JMenuItem( "Redo" ); menuOptions.add(redoMenu); pooper.add( redoMenu ); redoMenu.addActionListener( handler ); //Add copy menu option JMenuItem copyMenu = new JMenuItem( "Copy to clipboard" ); menuOptions.add(copyMenu); pooper.add( copyMenu ); copyMenu.addActionListener( handler ); //Add paste menu option JMenuItem pasteMenu = new JMenuItem( "Paste from clipboard" ); menuOptions.add(pasteMenu); pooper.add( pasteMenu ); pasteMenu.addActionListener( handler ); //Add export to xml menu option JMenuItem xmlMenu = new JMenuItem( "Export to XML" ); menuOptions.add(xmlMenu); pooper.add( xmlMenu ); xmlMenu.addActionListener( handler ); //Add export to xml menu option final subMenu searchTagMenu = new subMenu( "Search tags" ); pooper.add( searchTagMenu ); //Add add tag submenu JMenuItem addTagMenu = new JMenuItem( "Add search tag" ); menuOptions.add(addTagMenu); searchTagMenu.add( addTagMenu ); addTagMenu.addActionListener( handler ); //Add list tags submenu final JMenu listTagMenu = new JMenu( "List tags" ); searchTagMenu.add( listTagMenu ); listTagMenu.addMenuListener(new MenuAdapter() { @Override public void menuSelected(MenuEvent e) { if(searchTagMenu.isInitiated) { return; } for(final String tag: _myObject.getSearchTags()) { //List the tags JMenu tagMenu = new JMenu( tag ); listTagMenu.add( tagMenu ); JMenuItem removeTagItem = new JMenuItem( "remove" ); tagMenu.add( removeTagItem ); removeTagItem.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { _myObject.removeSearchTag(tag); } }); } searchTagMenu.isInitiated = true; } }); //Add a "launch" label: JLabel launchlabel = new JLabel(); launchlabel.setText("Launch Viewer:"); launchlabel.setFont(new Font("Arial", Font.ITALIC, 10)); pooper.add( launchlabel ); //Add a separator JSeparator jsep1 = new JSeparator(); pooper.add( jsep1 ); //Add launch preferred viewer menu option JMenuItem launchMenu = new JMenuItem( "Preferred Viewer" ); menuOptions.add(launchMenu); pooper.add( launchMenu ); launchMenu.addActionListener( handler ); //Add launch viewer JMenu to fill with options JMenu chooseViewerMenu = new JMenu( "Choose Viewer" ); pooper.add( chooseViewerMenu ); // construct each menu item and add to popup menu; also // enable event handling for each menu item for ( int i = 0; i < _viewers.length; i++ ) { JMenuItem amenu = new JMenuItem( _viewers[i].toString() ); menuOptions.add(amenu); chooseViewerMenu.add( amenu ); amenu.addActionListener( handler ); viewerHash.put(_viewers[i].toString(), (ViewerWrapper) _viewers[i]); } addItemSpecificFields(pooper, o); } private void addJumpToSeparator(JComponent pooper) { //Add a "Jump To" label: JLabel jumplabel = new JLabel(); jumplabel.setText("Jump To:"); jumplabel.setFont(new Font("Arial", Font.ITALIC, 10)); pooper.add( jumplabel ); //Add a separator JSeparator jsep2 = new JSeparator(); pooper.add( jsep2 ); } private void addSubField(final JComponent menu, String title, final ObjBase obj) { final subMenu menuitem1 = new subMenu( title ); menuitem1.addMenuListener(new MenuAdapter() { @Override public void menuSelected(MenuEvent e) { if(!menuitem1.isInitiated) { constructPopup(obj, menuitem1); menuitem1.isInitiated = true; } } }); menu.add( menuitem1 ); } /** * This is specific to Collection objBases to avoid retrieving everything * @param acoll * @param menu */ private void addCollectionSubFields(final Collection acoll, JComponent menu) { final subMenu rootMenu = new subMenu("Contents"); //For each ObjType create a header for(final ObjType type : ObjType.values()) { final subMenu menuitem1 = new subMenu(type.toString() ); menuitem1.addMenuListener(new MenuAdapter() { @Override public void menuSelected(MenuEvent e) { if(menuitem1.isInitiated) { return; } final subMenu objtypeItems = new subMenu( "Retrieve all" ); objtypeItems.addMenuListener(new MenuAdapter() { @Override public void menuSelected(MenuEvent e) { if(objtypeItems.isInitiated) { return; } @SuppressWarnings (value="unchecked") ArrayList<ObjBase> objbases = (ArrayList<ObjBase>)acoll.getAll(type); for( ObjBase obj : objbases) { if(obj!=null) { addSubField(objtypeItems, obj.getName(), obj); } } objtypeItems.isInitiated = true; } }); menuitem1.isInitiated=true; menuitem1.add(objtypeItems); } }); rootMenu.add( menuitem1 ); rootMenu.isInitiated = true; } menu.add(rootMenu); } public void disable() { _isActive = false; } public void enable() { _isActive = true; } private class MenuAdapter implements MenuListener { @Override public void menuSelected(MenuEvent e) { } @Override public void menuDeselected(MenuEvent e) { } @Override public void menuCanceled(MenuEvent e) { } } private void addObjBaseList(final JComponent menu, String title, java.util.Collection objs) { final subMenu rootItem = new subMenu( title ); for( Object objecto : objs) { ObjBase obj = (ObjBase) objecto; addSubField(rootItem, obj.getName(), obj); } menu.add(rootItem); } private class subMenu extends JMenu { public subMenu(String title) { super(title); } //VARIABLES// public boolean isInitiated=false; } private void addItemSpecificFields(JComponent pooper, ObjBase obj) { // <editor-fold defaultstate="collapsed" desc="Generated Code"> final Point location = pooper.getLocation(); switch(obj.getType()) { case COLLECTION: final Collection coll = (Collection) obj; addJumpToSeparator(pooper); if(coll.getAuthor()!=null) { addSubField(pooper, "Author", coll.getAuthor()); } addCollectionSubFields(coll, pooper); break; case PART: final Part p = (Part) obj; addJumpToSeparator(pooper); addSubField(pooper, "Sequence", p.getSeq()); addSubField(pooper, "Author", p.getAuthor()); addSubField(pooper, "Format", p.getFormat()); break; case NUCSEQ: final NucSeq nuc = (NucSeq) obj; addJumpToSeparator(pooper); addObjBaseList(pooper, "Annotations", nuc.getAnnotations()); break; case VECTOR: final Vector v = (Vector) obj; addJumpToSeparator(pooper); addSubField(pooper, "Sequence", v.getSeq()); addSubField(pooper, "Author", v.getAuthor()); addSubField(pooper, "Format", v.getFormat()); break; case PLASMID: final Plasmid pl = (Plasmid) obj; addJumpToSeparator(pooper); addSubField(pooper, "Sequence", pl.getSeq()); addSubField(pooper, "Author", pl.getAuthor()); addSubField(pooper, "Format", pl.getFormat()); addSubField(pooper, "Part", pl.getPart()); addSubField(pooper, "Vector", pl.getVector()); break; case PERSON: final Person pe = (Person) obj; addJumpToSeparator(pooper); addSubField(pooper, "Lab", pe.getLab()); addSubField(pooper, "Biography", pe.getBiography()); addSubField(pooper, "Collection", pe.getHerCollection()); break; case LAB: final Lab l = (Lab) obj; addJumpToSeparator(pooper); addSubField(pooper, "PI", l.getPI()); addSubField(pooper, "Institution", l.getInstitution()); break; case CONTAINER: final Container acon = (Container) obj; addJumpToSeparator(pooper); addSubField(pooper, "Plate", acon.getPlate()); Sample asam = acon.getSample(); if(asam!=null) { addSubField(pooper, "Sample", asam); } break; case PLATE: final Plate aplate = (Plate) obj; addJumpToSeparator(pooper); addSubField(pooper, "Plate Type", aplate.getPlateType()); addSubField(pooper, "Author", aplate.getAuthor()); break; case SAMPLE: final Sample sam = (Sample) obj; addJumpToSeparator(pooper); addSubField(pooper, "Container", sam.getContainer()); addSubField(pooper, "Author", sam.getAuthor()); switch(sam.getSampleType()) { case PLASMID_SAMPLE: //add Plasmid final PlasmidSample ps = (PlasmidSample) sam; final JMenuItem menuitem21 = new JMenuItem( "Plasmid" ); addSubField(pooper, "Plasmid", ps.getPlasmid()); break; case CELL_SAMPLE: //add Strain break; case OLIGO_SAMPLE: //add Oligo break; } addObjBaseList(pooper, "Data", sam.getData()); break; case FEATURE: final Feature fe = (Feature) obj; addJumpToSeparator(pooper); addSubField(pooper, "Sequence", fe.getSeq()); addSubField(pooper, "Author", fe.getAuthor()); addObjBaseList(pooper, "Families", fe.getFamilies()); addObjBaseList(pooper, "Notes", fe.getNotes()); break; case FACTOID: final Factoid fact = (Factoid) obj; addJumpToSeparator(pooper); addSubField(pooper, "Author", fact.getAuthor()); addObjBaseList(pooper, "Notes", fact.getNotes()); break; case NOTE: final Note anote = (Note) obj; addJumpToSeparator(pooper); addSubField(pooper, "Author", anote.getAuthor()); addObjBaseList(pooper, "Factoids", anote.getFactoids()); break; case OLIGO: final Oligo ol = (Oligo) obj; addJumpToSeparator(pooper); addSubField(pooper, "Sequence", ol.getSeq()); addSubField(pooper, "Author", ol.getAuthor()); break; } }// </editor-fold> private void addSearchTag() { Object[] params = new Object[2]; String message = "What keyword to you want to add?."; params[0] = message; ArrayList<String> listy = Collector.getAllSearchTags(); listy.add("(Enter new Tag)"); AutoComboBox acb = new AutoComboBox(listy); params[1] = acb; int n = JOptionPane.showConfirmDialog(null, params, "Save objects before quiting", JOptionPane.YES_NO_OPTION ); if(n==0) { String tag = (String) acb.getSelectedItem(); if(tag.equals("(Enter new Tag)")) { tag = JOptionPane.showInputDialog( "What tag do you wish to add?" ); if(tag!=null) { _myObject.addSearchTag(tag); } } } } private class ItemHandler implements ActionListener { private ObjBase handledObj; public ItemHandler(ObjBase obj) { super(); handledObj = obj; } @Override public void actionPerformed( ActionEvent e ) { // determine which menu item was selected for(JMenuItem jm : menuOptions) { if ( e.getSource() == jm ) { String selected = jm.getText(); //Do the action appropriate to the string selected if(selected.equals("Delete")) { handledObj.deleteFromDatabase(); } else if(selected.equals("Update")) { System.out.println("Objbasepopup calling update"); handledObj.update(); } else if(selected.equals("Undo")) { handledObj.undo(); } else if(selected.equals("Redo")) { handledObj.redo(); } else if(selected.equals("Revert")) { handledObj.revert(); } else if(selected.equals("Export to XML")) { handledObj.exportToXML(); } else if(selected.equals("Copy to clipboard")) { Collector.copyToClipboard(handledObj); } else if(selected.equals("Add search tag")) { addSearchTag(); } else if(selected.equals("Paste from clipboard")) { ObjBase obj = Collector.getFromClipboard(); if(obj!=null) { handledObj.addObject(obj); } } else if(selected.equals("Preferred Viewer")) { ViewerWrapper vw = Collator.getPreferredViewer(handledObj.getType()); if(vw!=null) { vw.launch(handledObj); } } else if(selected.equals("Save to database")) { handledObj.saveDefault(); } else { if(viewerHash.containsKey(selected)) { viewerHash.get(selected).launch(handledObj); } } if(_guiComponent!=null) { _guiComponent.repaint(); } return; } } } } /*----------------- variables -----------------*/ private ArrayList<JMenuItem> menuOptions = new ArrayList<JMenuItem>(); private Hashtable<String, ViewerWrapper> viewerHash = new Hashtable<String, ViewerWrapper>(); private Component _guiComponent; private ObjBase _myObject; private boolean _hasJumpHeader = false; private boolean _hasPluginHeader = false; private boolean _isActive = true; JPopupMenu popupMenu; }