public boolean handleAnnotationChangeEvent(AnnotationChangeEvent evt) { if (this.isVisible() && evt.getSource() != this) { if (evt.isCompound()) { for (int i = 0; i < evt.getNumberOfChildren(); ++i) { handleAnnotationChangeEvent(evt.getChildChangeEvent(i)); } return true; } if (evt.isEndOfEditSession()) { // Dont want scrolling on ann change, also sf for redraw is the // gene, so it just goes to 1st trans which is problematic. displayAnnot(currentAnnot); repaint(); // this is the needed repaint after the changes return true; } /* AnnotatedFeatureI gene = evt.getChangedAnnot(); for (Object o : szap.getAnnotations().getFeatures()) { AnnotatedFeatureI feat = (AnnotatedFeatureI)o; if (feat.getId().equals(gene.getId())) { //gene = feat; break; } } */ if (evt.isAdd()) { AnnotatedFeatureI annotToDisplay = null; AnnotatedFeatureI gene = evt.getChangedAnnot(); int trans_count = gene.size(); for (int i = 0; i < trans_count; ++i) { Transcript t = (Transcript) gene.getFeatureAt(i); if (evt.isUndo()) { // System.out.printf("Attaching %s(%d)\n", t, t.hashCode()); editorPanel.attachAnnot(t); if (currentAnnot != null && t.getName().equals(currentAnnot.getName())) { annotToDisplay = t; } } } if (annotToDisplay == null) { annotToDisplay = (AnnotatedFeatureI) evt.getChangedAnnot().getFeatureAt(0); } displayAnnot(annotToDisplay); return true; } if (evt.isDelete()) { AnnotatedFeatureI gene = evt.getChangedAnnot(); int trans_count = gene.size(); for (int i = 0; i < trans_count; ++i) { if (evt.isUndo()) { Transcript t = (Transcript) gene.getFeatureAt(i); // System.out.printf("Detaching %s(%d)\n", t, t.hashCode()); editorPanel.detachTranscript(t); } } return true; } /* // getAnnotation() can be null after a delete - return if null? SeqFeatureI sf = evt.getAnnotTop(); // If the annotation event is not for the editors strand then return boolean is_reverse = (sf.getStrand() == -1); if (editorPanel.getReverseStrand() != is_reverse) return false; if (evt.isDelete() && evt.isRootAnnotChange()) { AnnotatedFeatureI gene = evt.getChangedAnnot(); int trans_count = gene.size(); for (int i = 0; i < trans_count; i++) { Transcript t = (Transcript) gene.getFeatureAt (i); editorPanel.detachTranscript (t); if (t == currentAnnot) currentAnnot = null; } } else if (evt.isDelete() && evt.isTranscriptChange()) { Transcript t = (Transcript) evt.getChangedAnnot(); editorPanel.detachTranscript (t); if (t == currentAnnot) currentAnnot = null; } else if ((evt.isAdd() || evt.isSplit() || evt.isMerge()) && evt.isRootAnnotChange()) { AnnotatedFeatureI gene = evt.getChangedAnnot(); int trans_count = gene.size(); for (int i = 0; i < trans_count; i++) { Transcript t = (Transcript) gene.getFeatureAt (i); int tier = editorPanel.attachAnnot (t); } } else if (evt.isAdd() && evt.isTranscriptChange()) { Transcript t = (Transcript) evt.getChangedAnnot(); int tier = editorPanel.attachAnnot (t); } // Exon split or intron made - same thing isnt it? else if (evt.isAdd() && evt.isExonChange()) { Transcript t = (Transcript) evt.getParentFeature(); // removing and adding transcript will force editorPanel // to pick up new exon editorPanel.detachTranscript(t); editorPanel.attachAnnot(t); } else if (evt.isDelete() && evt.isExonChange()) { Transcript t = (Transcript) evt.getParentFeature(); // removing and adding transcript will force editorPanel to remove exon editorPanel.detachTranscript(t); editorPanel.attachAnnot(t); // or editorPanel.removeFeature((Exon)evt.getSecondFeature()); } // else if (evt.isReplace()) { //&&evt.isTopAnnotChange - always true of replace // AnnotatedFeatureI old_gene = evt.getReplacedFeature(); // AnnotatedFeatureI new_gene = (AnnotatedFeatureI)evt.getChangedFeature(); // int trans_count = old_gene.size(); // /* This does assume that there are no changes in the number // of transcripts between the old and the new. Might be safer // to separate the 2 loops */ // for (int i = 0; i < trans_count; i++) { // Transcript t; // t = (Transcript) old_gene.getFeatureAt (i); // editorPanel.detachTranscript (t); // t = (Transcript) new_gene.getFeatureAt (i); // int tier = editorPanel.attachTranscript (t); // } // // This is so that we don't select a different transcript // AnnotatedFeatureI current_gene = (current_transcript != null ? // current_transcript.getGene() : null); // if (current_gene != null && current_gene == old_gene) { // int index = current_gene.getFeatureIndex(current_transcript); // current_transcript = (Transcript) new_gene.getFeatureAt(index); // } // } // this isnt possible - all replaces are for top annots // else if (evt.isReplace() && evt.isTranscriptChange()) { // Transcript old_trans = (Transcript)evt.getReplacedFeature(); // Transcript new_trans = (Transcript)evt.getChangedFeature(); // editorPanel.detachTranscript (old_trans); // int tier = editorPanel.attachTranscript (new_trans); // // This is so that we don't select a different transcript // if (current_transcript != null && current_transcript == old_trans) { // current_transcript = new_trans; // } // } } return true; }
/** For annotations, try to find the appropriate identifier to add to the base URL. */ protected String generateAnnotURL(AnnotatedFeatureI g, String baseAnnotURL) { if (baseAnnotURL == null || baseAnnotURL.equals("")) return null; Hashtable id_hash = new Hashtable(); String id; for (int i = 0; i < g.getDbXrefs().size(); i++) { DbXref ref = (DbXref) g.getDbXrefs().elementAt(i); id = ref.getIdValue(); // Apparently, if the id starts with FBan we want to replace "FBan" with "CG". if (id.startsWith("FBan")) { id = id.substring("FBan".length()); try { int cg_num = Integer.parseInt(id); id = "CG" + cg_num; id_hash.put(id, id); } catch (Exception e) { } } else if (id.startsWith("FB")) { // FBgn, FBab, etc. id_hash.put(id, id); } else if (id.startsWith("TE")) { // FBgn, FBab, etc. id_hash.put(id, id); } } id = getCG(g.getId(), "CG"); if (id != null) id_hash.put(id, id); else { id = getCG(g.getId(), "CR"); if (id != null) id_hash.put(id, id); else { id = getCG(g.getId(), "FB"); if (id != null) id_hash.put(id, id); } } id = getCG(g.getName(), "CG"); if (id != null) id_hash.put(id, id); else { id = getCG(g.getName(), "CR"); if (id != null) id_hash.put(id, id); } for (int i = 0; i < g.getSynonyms().size(); i++) { Synonym syn = (Synonym) (g.getSynonyms().elementAt(i)); id = getCG(syn.getName(), "CG"); if (id != null) id_hash.put(id, id); else { id = getCG(syn.getName(), "CR"); if (id != null) id_hash.put(id, id); else { id = getCG(g.getId(), "FB"); if (id != null) id_hash.put(id, id); } } } // The code here was glomming together all the elements into one // big |ed string, but that's not what the FlyBase annotation report CGI wants. // An FB or CG or CR identifier should be sufficient. StringBuffer query_str = new StringBuffer(); for (Enumeration e = id_hash.elements(); e.hasMoreElements(); ) { String namepart = (String) e.nextElement(); // System.out.println("Considering namepart " + namepart); // DEL if (namepart.indexOf("FB") == 0 || namepart.indexOf("CG") == 0 || namepart.indexOf("CR") == 0) { if (query_str.length() > 0) query_str.replace(0, query_str.length(), namepart); else query_str.append(namepart); break; } if (query_str.length() > 0) query_str.append('|'); query_str.append(namepart); } // if not FlyBase ID, use the annotation's regular ID if (query_str.length() == 0) { query_str.append(g.getId()); } String url = null; // System.out.println("generateAnnotUrl: query = " + query_str); // DEL if (query_str.length() > 0) { // if a custom URL is setup for this type in the tiers file, use that - otherwise use the // global // one setup in the style file FeatureProperty fp = Config.getPropertyScheme().getFeatureProperty(g.getTopLevelType()); if (fp.getURLString() != null && fp.getURLString().length() > 0) { url = fp.getURLString() + g.getId(); } else { url = baseAnnotURL + query_str.toString(); } } return url; }