From: <mg...@us...> - 2006-10-12 15:06:49
|
Revision: 153 http://svn.sourceforge.net/obo/?rev=153&view=rev Author: mgibson Date: 2006-10-12 08:06:22 -0700 (Thu, 12 Oct 2006) Log Message: ----------- well this was a big refactoring much needed - so up til now ive gotten away with butting datamodel objects - oboClass & OBOProperty in atuo combo box's vector of items - this worked as the toString method gave back the name of the term. but now that we want more than just the name - [syn] [obs] marker, cut off if too long, relations toString was funny - it became apparent phenote needed actual view completion wrappers of its model - which are CompletionTerm & CompletionRelation - and i repackaged - new package phenote.gui.field for all fieldy things in gui - AutoComboBox is now AbstractAutoCompList with 2 subclasses RelationCompList and TermCompList for relation & terms also moved searching ontolo terms to new class CompListSearcher from Ontology - which outputs the view objects for searching not model. presently the only manifestation of these changes is that relations wont show id as well as name (silly toString method for oboProp) but more is coming. renamed TermPanel field.FieldPanel tested out and things look ok (test suite ok) - but wouldnt be surprised if another bug or 2 comes up Modified Paths: -------------- phenote/trunk/src/java/phenote/dataadapter/fly/FlyCharacter.java phenote/trunk/src/java/phenote/datamodel/Ontology.java phenote/trunk/src/java/phenote/datamodel/OntologyManager.java phenote/trunk/src/java/phenote/gui/CharacterTablePanel.java phenote/trunk/src/java/phenote/gui/GridBagUtil.java phenote/trunk/src/java/phenote/gui/TermInfo.java phenote/trunk/src/java/phenote/main/Phenote.java phenote/trunk/src/java/phenote/servlet/PhenoteServlet.java phenote/trunk/src/java/test/phenote/gui/TestPhenote.java Added Paths: ----------- phenote/trunk/src/java/phenote/datamodel/OntologyException.java phenote/trunk/src/java/phenote/gui/AbstractAutoCompList.java phenote/trunk/src/java/phenote/gui/SearchParamsI.java phenote/trunk/src/java/phenote/gui/field/ phenote/trunk/src/java/phenote/gui/field/AbstractAutoCompList.java phenote/trunk/src/java/phenote/gui/field/CharFieldGui.java phenote/trunk/src/java/phenote/gui/field/CompListSearcher.java phenote/trunk/src/java/phenote/gui/field/CompletionRelation.java phenote/trunk/src/java/phenote/gui/field/CompletionTerm.java phenote/trunk/src/java/phenote/gui/field/FieldPanel.java phenote/trunk/src/java/phenote/gui/field/PostCompGui.java phenote/trunk/src/java/phenote/gui/field/RelationCompList.java phenote/trunk/src/java/phenote/gui/field/SearchParamPanel.java phenote/trunk/src/java/phenote/gui/field/SearchParamsI.java phenote/trunk/src/java/phenote/gui/field/TermCompList.java Removed Paths: ------------- phenote/trunk/src/java/phenote/datamodel/SearchParamsI.java phenote/trunk/src/java/phenote/gui/AutoComboBox.java phenote/trunk/src/java/phenote/gui/CharFieldGui.java phenote/trunk/src/java/phenote/gui/PostCompGui.java phenote/trunk/src/java/phenote/gui/SearchParamPanel.java phenote/trunk/src/java/phenote/gui/TermPanel.java Modified: phenote/trunk/src/java/phenote/dataadapter/fly/FlyCharacter.java =================================================================== --- phenote/trunk/src/java/phenote/dataadapter/fly/FlyCharacter.java 2006-10-10 17:20:06 UTC (rev 152) +++ phenote/trunk/src/java/phenote/dataadapter/fly/FlyCharacter.java 2006-10-12 15:06:22 UTC (rev 153) @@ -5,6 +5,7 @@ import phenote.datamodel.CharacterI; import phenote.datamodel.Character; import phenote.datamodel.OntologyManager; +import phenote.datamodel.OntologyManager.TermNotFoundException; public class FlyCharacter implements FlyCharacterI { @@ -75,13 +76,15 @@ String id = termParts[1].trim(); if (id == null || id.equals("")) throw new TermException("Failed to get term id "+id); - OBOClass oc = OntologyManager.inst().getOboClass(id); - if (oc == null) + try { + OBOClass oc = OntologyManager.inst().getOboClass(id); // ex + if (!oc.getName().equals(name)) + throw new TermException("Data name "+name+" and ontology name "+oc.getName()+ + "are inconsistent for id "+id); + return oc; + } catch (TermNotFoundException e) { throw new TermException("Couldnt find ontology term for id "+id); - if (!oc.getName().equals(name)) - throw new TermException("Data name "+name+" and ontology name "+oc.getName()+ - "are inconsistent for id "+id); - return oc; + } } private class TermException extends Exception { Modified: phenote/trunk/src/java/phenote/datamodel/Ontology.java =================================================================== --- phenote/trunk/src/java/phenote/datamodel/Ontology.java 2006-10-10 17:20:06 UTC (rev 152) +++ phenote/trunk/src/java/phenote/datamodel/Ontology.java 2006-10-12 15:06:22 UTC (rev 153) @@ -63,107 +63,112 @@ public String getName() { return name; } - /** returns null if dont have class for id */ - public OBOClass getOboClass(String id) { - return oboSession.getTerm(id); + /** returns null if dont have class for id, throws OntologyException if id is not + found */ + public OBOClass getOboClass(String id) throws OntologyException { + OBOClass oc = oboSession.getTerm(id); + if (oc == null) throw new OntologyException(id +" id not found in ontology "+name); + return oc; } /** Returns true if ontology holds obo class */ boolean hasOboClass(OBOClass oboClass) { // if this is too slow can do optimizations with prefixes - return getOboClass(oboClass.getID()) != null; + try {getOboClass(oboClass.getID()); } + catch (OntologyException e) { return false; } + return true; // no exception - it has it } - /** Returns a Vector of OBOClass from ontology that contain input string - constrained by compParams. compParams specifies syns,terms,defs,& obs - should input be just part of search params? - its a vector as thats what ComboBox requires - put in separate class? */ - public Vector<OBOClass> getSearchTerms(String input,SearchParamsI searchParams) { - Vector<OBOClass> searchTerms = new Vector<OBOClass>(); - if (input == null || input.equals("")) - return searchTerms; +// /** Returns a Vector of OBOClass from ontology that contain input string +// constrained by compParams. compParams specifies syns,terms,defs,& obs +// should input be just part of search params? +// its a vector as thats what ComboBox requires +// put in separate class? */ +// public Vector<OBOClass> getSearchTerms(String input,SearchParamsI searchParams) { +// Vector<OBOClass> searchTerms = new Vector<OBOClass>(); +// if (input == null || input.equals("")) +// return searchTerms; - // gets term set for currently selected ontology - //Set ontologyTermList = getCurrentOntologyTermSet(); - List<OBOClass> ontologyTermList = getSortedTerms(); // non obsolete - searchTerms = getSearchTerms(input,ontologyTermList,searchParams); +// // gets term set for currently selected ontology +// //Set ontologyTermList = getCurrentOntologyTermSet(); +// List<OBOClass> ontologyTermList = getSortedTerms(); // non obsolete +// searchTerms = getSearchTerms(input,ontologyTermList,searchParams); - // if obsoletes set then add them in addition to regulars - if (searchParams.searchObsoletes()) { - ontologyTermList = getSortedObsoleteTerms(); - Vector obsoletes = getSearchTerms(input,ontologyTermList,searchParams); - searchTerms.addAll(obsoletes); - } - return searchTerms; - } +// // if obsoletes set then add them in addition to regulars +// if (searchParams.searchObsoletes()) { +// ontologyTermList = getSortedObsoleteTerms(); +// Vector obsoletes = getSearchTerms(input,ontologyTermList,searchParams); +// searchTerms.addAll(obsoletes); +// } +// return searchTerms; +// } - /** helper fn for getSearchTerms(String,SearhParamsI) */ - private Vector<OBOClass> getSearchTerms(String input, List<OBOClass> ontologyTermList, - SearchParamsI searchParams) { - // need a unique list - UniqueTermList has quick check for uniqueness, checking - // whole list is very very slow - how is it possible to get a dup term? i forget? - // the dup term was a BUG! in synonym - woops - SearchTermList uniqueTermList = new SearchTermList(); - //Vector searchTerms = new Vector(); - if (ontologyTermList == null) - return uniqueTermList.getVector();//searchTerms; +// /** helper fn for getSearchTerms(String,SearhParamsI) */ +// private Vector<OBOClass> getSearchTerms(String input, List<OBOClass> ontologyTermList, +// SearchParamsI searchParams) { +// // need a unique list - UniqueTermList has quick check for uniqueness, checking +// // whole list is very very slow - how is it possible to get a dup term? i forget? +// // the dup term was a BUG! in synonym - woops +// SearchTermList uniqueTermList = new SearchTermList(); +// //Vector searchTerms = new Vector(); +// if (ontologyTermList == null) +// return uniqueTermList.getVector();//searchTerms; - boolean ignoreCase = true; // param? - if (ignoreCase) - input = input.toLowerCase(); +// boolean ignoreCase = true; // param? +// if (ignoreCase) +// input = input.toLowerCase(); - // i think iterators are more efficient than get(i) ?? - Iterator<OBOClass> iter = ontologyTermList.iterator(); - while (iter.hasNext()) { - // toString extracts name from OBOClass - OBOClass oboClass = iter.next(); - String originalTerm = oboClass.getName();//toString(); +// // i think iterators are more efficient than get(i) ?? +// Iterator<OBOClass> iter = ontologyTermList.iterator(); +// while (iter.hasNext()) { +// // toString extracts name from OBOClass +// OBOClass oboClass = iter.next(); +// String originalTerm = oboClass.getName();//toString(); - boolean termAdded = false; +// boolean termAdded = false; - if (searchParams.searchTerms()) { - // adds originalTerm to searchTerms if match (1st if exact) - termAdded = compareAndAddTerm(input,originalTerm,oboClass,uniqueTermList); - if (termAdded) - continue; - } +// if (searchParams.searchTerms()) { +// // adds originalTerm to searchTerms if match (1st if exact) +// termAdded = compareAndAddTerm(input,originalTerm,oboClass,uniqueTermList); +// if (termAdded) +// continue; +// } - if (searchParams.searchSynonyms()) { - Set synonyms = oboClass.getSynonyms(); - for (Iterator i = synonyms.iterator(); i.hasNext() &&!termAdded; ) { - String syn = i.next().toString(); - //log().debug("syn "+syn+" for "+originalTerm); - termAdded = compareAndAddTerm(input,syn,oboClass,uniqueTermList); - //if (termAdded) continue; // woops continues this for not the outer! - } - } - if (termAdded) continue; +// if (searchParams.searchSynonyms()) { +// Set synonyms = oboClass.getSynonyms(); +// for (Iterator i = synonyms.iterator(); i.hasNext() &&!termAdded; ) { +// String syn = i.next().toString(); +// //log().debug("syn "+syn+" for "+originalTerm); +// termAdded = compareAndAddTerm(input,syn,oboClass,uniqueTermList); +// //if (termAdded) continue; // woops continues this for not the outer! +// } +// } +// if (termAdded) continue; - if (searchParams.searchDefinitions()) { - String definition = oboClass.getDefinition(); - if (definition != null & !definition.equals("")) - termAdded = compareAndAddTerm(input,definition,oboClass,uniqueTermList); - if (termAdded) - continue; // not really necesary as its last - } +// if (searchParams.searchDefinitions()) { +// String definition = oboClass.getDefinition(); +// if (definition != null & !definition.equals("")) +// termAdded = compareAndAddTerm(input,definition,oboClass,uniqueTermList); +// if (termAdded) +// continue; // not really necesary as its last +// } - } - return uniqueTermList.getVector();//searchTerms; - } +// } +// return uniqueTermList.getVector();//searchTerms; +// } - public Vector<OBOProperty> getStringMatchRelations(String input) { - Vector<OBOProperty> matches = new Vector<OBOProperty>(); - for (OBOProperty rel : getSortedRelations()) { - if (rel.toString().contains(input)) - matches.add(rel); - } - return matches; - } +// public Vector<OBOProperty> getStringMatchRelations(String input) { +// Vector<OBOProperty> matches = new Vector<OBOProperty>(); +// for (OBOProperty rel : getSortedRelations()) { +// if (rel.toString().contains(input)) +// matches.add(rel); +// } +// return matches; +// } - private List<OBOProperty> getSortedRelations() { + public List<OBOProperty> getSortedRelations() { if (sortedRelations == null) { //sortedRelations=new ArrayList<OBOProperty>(); not Comparable! List sorRel = new ArrayList(); @@ -184,78 +189,20 @@ } } - /** User input is already lower cased, this potentially adds oboClass to - * searchTerms if input & compareTerm match. Puts it first if exact. - * for term names comp = obo, for syns comp is the syn. - Returns true if term is a match & either gets added or already is added - * Also checks if term is in list already - not needed - woops! - Theres a speed issue here - the vector needs to be unique. if check every time - with whole list very very slow. 2 alternatives to try. - 1) have separate hash for checking uniqueness (downside 2 data structures). - could make a data structure that had both map & vector - 2) use LinkedHashSet, which does uniqueness & maintains order of insertion - nice - its 1 data structure BUT exact matches go 1st, no way in linked hash set - to insert 1st elements so would need to keep separate list of exact matches, which - i guess there can be more than one with synonyms (do syns count for exact matches? - should they?) - downside of #2 is need Vector for combo box - - this wont fly for having different display strings for syn & obs as compareTerm - can be syn obs term or def and its lost here - i think these methods need to be moved to gui.TermSearcher that utilizes Ontology - but produces CompListTerms */ - private boolean compareAndAddTerm(String input, String compareTerm, OBOClass oboClass, - SearchTermList searchTermList) { - - String oboTerm = oboClass.getName(); - String lowerComp = compareTerm; - boolean ignoreCase = true; // discard? param for? - if (ignoreCase) - lowerComp = compareTerm.toLowerCase(); - - //boolean doContains = true; // discard? param for? - // exact match goes first in list - if (lowerComp.equals(input)) { - searchTermList.addTermFirst(oboClass); // adds if not present - return true; - } - // new paradigm - put starts with first - else if (lowerComp.startsWith(input)) { - searchTermList.addTerm(oboClass); - return true; - } - // Contains - else if (contains(lowerComp,input) && !termFilter(lowerComp)) { - searchTermList.addContainsTerm(oboClass); - return true; - } - return false; - } - - // 1.5 has a contains! use when we shift - private boolean contains(String term, String input) { - return term.contains(input); // 1.5!! - //return term.indexOf(input) != -1; - } - /** Oboedit getTerms returns some terms with obo: prefix that should be filtered - * out. Returns true if starts with obo: */ - private boolean termFilter(String term) { - return term.startsWith("obo:"); - } - /** non obsolete terms - sorted */ - private List<OBOClass> getSortedTerms() { + public List<OBOClass> getSortedTerms() { return sortedTerms; } - private List<OBOClass> getSortedObsoleteTerms() { + public List<OBOClass> getSortedObsoleteTerms() { return sortedObsoleteTerms; } private OBOSession getOboSession() { return oboSession; } - private List<OBOClass> getSortedTerms(Set terms) { + public List<OBOClass> getSortedTerms(Set terms) { List<OBOClass> sortedTerms = new ArrayList<OBOClass>(); sortedTerms.addAll(terms); Collections.sort(sortedTerms); @@ -270,37 +217,6 @@ public String getSource() { return source; } - /** does unique check w map - dont need unique check - it was a bug in synonyms - how silly! - but actually this data structure will be handy for putting starts with - before contains! UniqueTermList -> SearchTermList*/ - private class SearchTermList { - private Vector<OBOClass> searchTerms = new Vector<OBOClass>(); - //private Map<OBOClass,OBOClass> uniqueCheck = new HashMap<OBOClass,OBOClass>(); - // list of terms that are contained but NOT startsWith - private Vector<OBOClass> containTerms = new Vector<OBOClass>(); - private void addTerm(OBOClass oboClass) { - addTerm(oboClass,false); - } - private void addTermFirst(OBOClass oboClass) { - addTerm(oboClass,true); - } - private void addTerm(OBOClass oboClass,boolean first) { - //if (uniqueCheck.containsKey(oboClass)) { - //log().debug("dup term in search "+oboClass); - // new Throwable().printStackTrace(); return; } - if (first) searchTerms.add(0,oboClass); - else searchTerms.add(oboClass); - //uniqueCheck.put(oboClass,null); // dont need value - } - /** Add term thats not startsWith but contains */ - private void addContainsTerm(OBOClass oboClass) { - containTerms.add(oboClass); - } - private Vector<OBOClass> getVector() { - searchTerms.addAll(containTerms); - return searchTerms; - } - } public void setFilter(String filterOutString) { @@ -332,6 +248,64 @@ // GARBAGE +// /** User input is already lower cased, this potentially adds oboClass to +// * searchTerms if input & compareTerm match. Puts it first if exact. +// * for term names comp = obo, for syns comp is the syn. +// Returns true if term is a match & either gets added or already is added +// * Also checks if term is in list already - not needed - woops! +// Theres a speed issue here - the vector needs to be unique. if check every time +// with whole list very very slow. 2 alternatives to try. +// 1) have separate hash for checking uniqueness (downside 2 data structures). +// could make a data structure that had both map & vector +// 2) use LinkedHashSet, which does uniqueness & maintains order of insertion +// nice - its 1 data structure BUT exact matches go 1st, no way in linked hash set +// to insert 1st elements so would need to keep separate list of exact matches, which +// i guess there can be more than one with synonyms (do syns count for exact matches? +// should they?) - downside of #2 is need Vector for combo box + +// this wont fly for having different display strings for syn & obs as compareTerm +// can be syn obs term or def and its lost here +// i think these methods need to be moved to gui.TermSearcher that utilizes Ontology +// but produces CompListTerms */ +// private boolean compareAndAddTerm(String input, String compareTerm, OBOClass oboClass, +// SearchTermList searchTermList) { + +// String oboTerm = oboClass.getName(); + +// String lowerComp = compareTerm; +// boolean ignoreCase = true; // discard? param for? +// if (ignoreCase) +// lowerComp = compareTerm.toLowerCase(); + +// //boolean doContains = true; // discard? param for? +// // exact match goes first in list +// if (lowerComp.equals(input)) { +// searchTermList.addTermFirst(oboClass); // adds if not present +// return true; +// } +// // new paradigm - put starts with first +// else if (lowerComp.startsWith(input)) { +// searchTermList.addTerm(oboClass); +// return true; +// } +// // Contains +// else if (contains(lowerComp,input) && !termFilter(lowerComp)) { +// searchTermList.addContainsTerm(oboClass); +// return true; +// } +// return false; +// } + +// // 1.5 has a contains! use when we shift +// private boolean contains(String term, String input) { +// return term.contains(input); // 1.5!! +// //return term.indexOf(input) != -1; +// } +// /** Oboedit getTerms returns some terms with obo: prefix that should be filtered +// * out. Returns true if starts with obo: */ +// private boolean termFilter(String term) { +// return term.startsWith("obo:"); +// } //if (!searchTerms.contains(oboClass)) {// this takes a long time w long lists! //searchTerms.add(0,oboClass); //if (!searchTerms.contains(oboClass)) searchTerms.add(oboClass); Added: phenote/trunk/src/java/phenote/datamodel/OntologyException.java =================================================================== --- phenote/trunk/src/java/phenote/datamodel/OntologyException.java (rev 0) +++ phenote/trunk/src/java/phenote/datamodel/OntologyException.java 2006-10-12 15:06:22 UTC (rev 153) @@ -0,0 +1,5 @@ +package phenote.datamodel; + +public class OntologyException extends Exception { + public OntologyException(String m) { super(m); } +} Modified: phenote/trunk/src/java/phenote/datamodel/OntologyManager.java =================================================================== --- phenote/trunk/src/java/phenote/datamodel/OntologyManager.java 2006-10-10 17:20:06 UTC (rev 152) +++ phenote/trunk/src/java/phenote/datamodel/OntologyManager.java 2006-10-12 15:06:22 UTC (rev 153) @@ -51,13 +51,16 @@ public List<CharField> getCharFieldList() { return charFieldList; } /** Returns ontology with name, null if not found */ - public static Ontology getOntologyForName(String ontologyName) { // static? + public Ontology getOntologyForName(String ontologyName) + throws OntologyException { // static? for (CharField cf : inst().getCharFieldList()) { if (cf.hasOntology(ontologyName)) return cf.getOntologyForName(ontologyName); } - System.out.println("ERROR: no ontology found for name "+ontologyName); - return null; + String m = "no ontology found for name "+ontologyName; + log().error(m); + throw new OntologyException(m); + //return null; } @@ -73,18 +76,21 @@ the id prefix AO,GO,PATO... Should this deal with post comp? if ^ then create a post comp term on fly? im not sure if this is the right place for it, maybe method should be renamed - but ill put it here for now */ - public OBOClass getOboClass(String id) { + but ill put it here for now + merge this with getOboClassWithEx? */ + public OBOClass getOboClass(String id) throws TermNotFoundException { OBOClass oboClass; // this seems to be the sole reason for ontology list - silly! Iterator<Ontology> iter = allOntologyList.iterator(); while (iter.hasNext()) { Ontology o = iter.next(); - oboClass = o.getOboClass(id); + try { oboClass = o.getOboClass(id); } + catch (OntologyException e) { continue; } if (oboClass != null) return oboClass; } - return null; // not found - null + //return null; // not found - null -- ex? + throw new TermNotFoundException("ID "+id+" not found in loaded ontologies"); } public OBOClass getTermOrPostComp(String id) throws TermNotFoundException { @@ -94,6 +100,7 @@ return getOboClassWithExcep(id); } + // phase out - put ex in getOboClass! public OBOClass getOboClassWithExcep(String id) throws TermNotFoundException { OBOClass term = getOboClass(id); if (term == null) Deleted: phenote/trunk/src/java/phenote/datamodel/SearchParamsI.java =================================================================== --- phenote/trunk/src/java/phenote/datamodel/SearchParamsI.java 2006-10-10 17:20:06 UTC (rev 152) +++ phenote/trunk/src/java/phenote/datamodel/SearchParamsI.java 2006-10-12 15:06:22 UTC (rev 153) @@ -1,14 +0,0 @@ -package phenote.datamodel; - -// package phenote.ontology?? dataadapter? - -public interface SearchParamsI { - - public boolean searchTerms(); - public boolean searchSynonyms(); - public boolean searchDefinitions(); - /** Whether to include obsoletes in searching terms, syns, & definitions - This should be in conjunction with the other 3 */ - public boolean searchObsoletes(); - -} Copied: phenote/trunk/src/java/phenote/gui/AbstractAutoCompList.java (from rev 149, phenote/trunk/src/java/phenote/gui/AutoComboBox.java) =================================================================== --- phenote/trunk/src/java/phenote/gui/AbstractAutoCompList.java (rev 0) +++ phenote/trunk/src/java/phenote/gui/AbstractAutoCompList.java 2006-10-12 15:06:22 UTC (rev 153) @@ -0,0 +1,632 @@ +package phenote.gui; + +import java.awt.Dimension; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.Vector; +import javax.swing.JComboBox; +import javax.swing.JList; +import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.DefaultComboBoxModel; +import javax.swing.text.Document; +import javax.swing.plaf.basic.BasicComboBoxEditor; +//import javax.swing.plaf.basic.BasicComboBoxUI; +import javax.swing.plaf.ComboBoxUI; +import javax.swing.plaf.metal.MetalComboBoxUI; + +import org.apache.log4j.Logger; + +import org.geneontology.oboedit.datamodel.OBOClass; +import org.geneontology.oboedit.datamodel.OBOProperty; + +import phenote.datamodel.CharField; +import phenote.datamodel.CharFieldEnum; +import phenote.datamodel.CharacterI; +import phenote.datamodel.Ontology; +import phenote.datamodel.SearchParamsI; +import phenote.edit.EditManager; +import phenote.edit.UpdateTransaction; +import phenote.gui.selection.SelectionManager; +import phenote.gui.selection.UseTermEvent; +import phenote.gui.selection.UseTermListener; + +/** The jcombobox that does auto completion - i had to do some tricks(hacks) to get it + working with mouse over which doesnt come naturally to jcombobox */ + +class AutoComboBox extends JComboBox { + + private Ontology ontology; + private boolean changingCompletionList = false; + private boolean keyTyped = false; + private String previousInput = ""; + private boolean doCompletion = true; + // should we keep state of currentOboClass which is null if not a valid one? + // default combo box.getSelectedItem sortof does this imperfectly + private OBOClass currentOboClass=null; + private OBOProperty currentRel=null; + private DefaultComboBoxModel defaultComboBoxModel; + private SearchParamsI searchParams; + private boolean inTestMode = false; + //private AutoTextFieldEditor autoTextFieldEditor; + private AutoTextField autoTextField; + private CharField charField; + ///** Whether differentia of a post composed term */ + //private boolean isDifferentia = false; + /** if false then model is not edited */ + private boolean editModel; + private CompletionListListener compListListener = new CompletionListListener(); + + /** @param editModel if false then ACB doesnt edit model directly (post comp) */ + AutoComboBox(Ontology ontology,SearchParamsI sp,boolean editModel) { + // this inner class enables retrieving of JList for mouse over + // this will probably throw errors if non metal look & feel is used + setUI(new MetalListComboUI()); + //setFont(new Font("Courier",Font.PLAIN,12)); + + setOntology(ontology); + searchParams = sp; // singleton access? part of ontology? + setEditable(true); + AutoTextFieldEditor autoTextFieldEditor = new AutoTextFieldEditor(); + this.setEditor(autoTextFieldEditor); + setPreferredSize(new Dimension(350,22)); + + enableTermInfoListening(true); // default + //addCompletionListListener(compList); + + //if (editModel) // ComboBoxActionListener edits the model + this.editModel = editModel; + addActionListener(new ComboBoxActionListener()); + + } + + void setOntology(Ontology o) { ontology = o; } + + //void setSearchParams(SearchParamsI sp) { searchParams = sp; } + + void setCharField(CharField charField) { this.charField = charField; } + + ///** If true than the auto combo is for setting the differentia in a post comp term, + // if false (default) than no post comp or genus in post comp */ + //void setIsDifferentia(boolean isDiff) { isDifferentia = isDiff; } + + /** Set text in editable text field of j combo (eg from table select) */ + void setText(String text) { + // do not do term completion on externally set text! + boolean doCompletion = false; + setText(text,doCompletion); + } + + // text from selecting table doesnt do completion, TestPhenote does + void setText(String text, boolean doCompletion) { + this.doCompletion = doCompletion; + this.keyTyped = doCompletion; // key has to be typed for completion + getEditor().setItem(text); + this.doCompletion = true; // set back to default + } + + /** rename setTerm? */ + void setOboClass(OBOClass term) { + if (term == null) { + log().error("Attempt to set term to null"); + return; // debug stack trace? + } + currentOboClass = term; + setText(term.getName(),false); // no completion + } + + /** for relationships (post comp rel) */ + void setRel(OBOProperty rel) { + if (rel == null) { + log().error("Attempt to set term to null"); + return; // debug stack trace? + } + currentRel = rel; + setText(rel.toString(),false); // eventually .getName() + } + + /** Throws exception if there isnt a current obo class, if the user + has typed something that isnt yet a term - hasnt selected a term */ + OBOClass getCurrentOboClass() throws Exception { + if (currentOboClass == null) throw new Exception("term is null"); + if (!currentOboClass.getName().equals(getText())) + throw new Exception("(obo class "+currentOboClass+" and input "+getText()+ + " dont match)"); + return currentOboClass; + } + + /** Throws exception if there isnt a current relation - for relation lists + (post comp), if the user + has typed something that isnt yet a rel - hasnt selected a rel */ + OBOProperty getCurrentRelation() throws Exception { + if (currentRel == null) throw new Exception("term is null"); + if (!currentRel.toString().equals(getText())) + throw new Exception("(relation "+currentRel+" and input "+getText()+ + " dont match)"); + return currentRel; + + } + + /** Return text in text field */ + String getText() { + //return (String)getSelectedItem(); + return getEditor().getItem().toString(); // or editor.getText() ? + } + + + void clear() { + setText(""); + } + + + /** This gets obo class selected in completion list - not from text box + Returns null if nothing selected - can happen amidst changing selection + also used by PostCompGui + this doesnt necasarily stay current with user input hmmm.... + throws OboException if dont have valid term */ + OBOClass getSelectedCompListOboClass() throws OboException { + Object obj = getSelectedObject(); // throws oboex + return oboClassDowncast(obj); // throws oboex + } + + private class OboException extends Exception { + private OboException() { super(); } + private OboException(String s) { super(s); } + } + +// private OBOClass getCompListOboClass(int index) { +// Object obj = defaultComboBoxModel.getElementAt(index); +// return oboClassDowncast(obj); +// } + + // strings get in somehow - need to figure out where they are coming from + private OBOClass oboClassDowncast(Object obj) throws OboException { + if (obj == null) throw new OboException(); + if ( ! (obj instanceof OBOClass)) { + //log.info("Item in completion list not obo class "+obj.getClass()); + throw new OboException("Item in completion list not obo class "+obj.getClass()); + } + return (OBOClass)obj; + } + + private OBOProperty oboPropertyDowncast(Object obj) throws OboException { + if (obj == null) throw new OboException(); + if ( ! (obj instanceof OBOProperty)) { + //log.info("Item in completion list not obo class "+obj.getClass()); + throw new OboException("Item in completion list not obo prop "+obj.getClass()); + } + return (OBOProperty)obj; + } + + /** returns currently selected relation, for auto combos of relations, + throws obo ex if there is no current relation */ + private OBOProperty getSelectedRelation() throws OboException { + Object obj = getSelectedObject(); // throws oboex + return oboPropertyDowncast(obj); // throws oboex + } + + private Object getSelectedObject() throws OboException { + if (defaultComboBoxModel == null) throw new OboException(); // ?? + Object obj = defaultComboBoxModel.getSelectedItem(); + if (obj == null) throw new OboException(); + return obj; + } + + + /** BasicComboBoxEditor uses JTextField as its editing component but is + * only available as a protected variable - odd + adds auto doc & auto key listeners to combo box edit field */ + private class AutoTextFieldEditor extends BasicComboBoxEditor { + + private AutoTextFieldEditor() { + autoTextField = new AutoTextField(); + editor = autoTextField; // protected editor var from BCBE + addDocumentListener(new AutoDocumentListener()); + getTextField().addKeyListener(new AutoKeyListener()); + } + + // editor is protected JTextField - wacky + private JTextField getTextField() { + return editor; + } + + private Document getDocument() { + return getTextField().getDocument(); + } + private void addDocumentListener(DocumentListener dl) { + getDocument().addDocumentListener(dl); + } + } + + + /** AutoTextField inner class - ignores set text when in + * changingCompletionList mode - this is the text field for the + combo box */ + private class AutoTextField extends JTextField { + + private AutoTextField() { + super(25); // width + } + + /** dont set text if changing completion list, if changing text turn off + completion, as changing text is coming from outside not user typing + thus wont get completion on user selection, leaving popup hanging */ + public void setText(String text) { + if (changingCompletionList) + return; + // this makes setText(text,true) turn to false (called from TextPhenote) + // but this is needed from mouse release on selection set text + // is called and will cause completion list to come up after sel + // w/o it + doCompletion = false; + super.setText(text); + doCompletion = true; + } + + protected void processKeyEvent(KeyEvent e) { + //boolean fiddle = KeyboardState.shouldProcess(e); + super.processKeyEvent(e); + } + } + + void simulateLKeyStroke() { + autoTextField.processKeyEvent(new KeyEvent(this,KeyEvent.KEY_PRESSED,0,0,KeyEvent.VK_L,'l')); + autoTextField.processKeyEvent(new KeyEvent(this,KeyEvent.KEY_TYPED,0,0,KeyEvent.VK_UNDEFINED,'l')); + } + + void simulateKeyStroke(int keyCode, char c) { + KeyEvent k = new KeyEvent(this,KeyEvent.KEY_PRESSED,0,0,keyCode,c); + autoTextField.processKeyEvent(k); + k.setKeyCode(KeyEvent.KEY_RELEASED); + autoTextField.processKeyEvent(k); + k = new KeyEvent(this,KeyEvent.KEY_TYPED,0,0,KeyEvent.VK_UNDEFINED,c); + autoTextField.processKeyEvent(k); + } + + private class AutoKeyListener extends KeyAdapter { + // keyTyped doesnt seem to catch backspace in 1.5 - but did in 1.4 - odd +// public void keyTyped(KeyEvent e) { +// // return & tab should be ignored, as well as a lot of other things +// keyTyped = true; +// // this may be funny but with key type event the text has not yet be set +// // this catches cases where text changed due select/action - kinda cheap +// previousInput = getText(); +// } + public void keyReleased(KeyEvent e) { + // return & tab should be ignored, as well as a lot of other things + keyTyped = true; + // this may be funny but with key type event the text has not yet be set + // this catches cases where text changed due select/action - kinda cheap + previousInput = getText(); + } + } + + + /** disable completion for item being selected - otherwise a popup comes up after + the selection - probably no harm in keeping this but this may be redundant with + the turning off of doCompletion in inner ATF.setText which is more + comprehensive */ + public void setSelectedItem(Object item) { + doCompletion = false; + super.setSelectedItem(item); + doCompletion = true; + } + + /** If combo box is relationship then the items will be OBOProperties not + OBOClasses */ + private boolean isRelationshipList() { + return charField.isRelationship(); + } + private boolean isTermList() { return !isRelationshipList(); } + + /** MAKE COMPLETION LIST FROM USER INPUT + Populates defaultComboBoxModel with Vector of OBOClasses - OBOClass.toString + is the name of the term - thats why its possible - at least for moment + if we want to put syn in brackets that makes this not possible - certainly + handy */ + private void doCompletion() { + if (!doCompletion) // flag set if text filled in externally (from table sel) + return; + // so AbstractDoc.replace does a remove and then insert, the remove sets + // text to "" and then keyTyped gets set to false, so the insert doesnt go + // through, taking out keyTyped, inputChanged may be sufficient +// if (!keyTyped) // if user hasnt typed anything dont bother +// return; + if (!inputChanged()) // if input is actually same no need to recomp + return; + keyTyped = false; + // too soon - text field doesnt have text yet.... hmmmm.... + String input = getText(); + // this is a vector of OBOClasses + // i think ultimately we will need to wrap the OBOClass to be able to + // have more control over the string - cut off w ... & [syn][obs] tags + Vector v; + if (isRelationshipList()) + v = ontology.getStringMatchRelations(input); + else + v = getTerms(input); + // throws IllegalStateException, Attempt to mutate in notification + // this tries to change text field amidst notification hmmmm..... + changingCompletionList = true; + defaultComboBoxModel = new DefaultComboBoxModel(v); + setModel(defaultComboBoxModel); + changingCompletionList = false; + // showPopup can hang during test but not during real run - bizarre + showPopup(); // only show popup on key events - actually only do comp w key + } + + /** This is cheesy but theres a hanging bug with showPopup that only happens + in test mode - dont know why but doesnt actually matter, so setting flag + to turn off showpopup in test - if hangs in nontest will investigate */ + void setTestMode(boolean inTestMode) { + this.inTestMode = inTestMode; + } + + /** This is cheesy but theres a hanging bug with showPopup that only happens + in test mode - dont know why but doesnt actually matter, so if inTestMode + then dont showpopup - if hangs in nontest will investigate */ + public void showPopup() { + if (inTestMode) + return; + super.showPopup(); + } + + + /** returns true if input changed from previously recorded input */ + private boolean inputChanged() { + String newInput = getText(); + boolean inputChanged = ! previousInput.equals(newInput); + if (inputChanged) + previousInput = newInput; + return inputChanged; + } + + /** call Ontology to get a Vector of OBOClass's that contain "in" + in ontology */ + private Vector<OBOClass> getTerms(String in) { + // or CompletionList.getCompletionList(getOntology()) ?? + //CompletionList cl = CompletionList.getCompletionList(); + //return cl.getCompletionTerms(getOntology(),in,searchParams); + return ontology.getSearchTerms(in,searchParams); // vector of OBOClass's + } + + private class AutoDocumentListener implements DocumentListener { + public void changedUpdate(DocumentEvent e) { doCompletion(); } + public void insertUpdate(DocumentEvent e) { doCompletion(); } + public void removeUpdate(DocumentEvent e) { doCompletion(); } + } + + /** This is touchy stuff - so i want to be able to display info about term in + TermInfo when user mouses over terms in combo boxes JList. This is not + explicitly supported by JComboBox. have to dig into its UI to get JList. + The combo box ui selects items in JList on mouse over, this listener + will listen for those mouse over selections + should this be done with a selection event - or is that + overkill, i guess the question will anyone besides term info + ever care about these mouse over selection - if so make generic */ +// void addCompletionListListener(ListSelectionListener lsl) { +// if (!canGetUIJList()) return; +// getUIJList().addListSelectionListener(lsl); } + void enableTermInfoListening(boolean enable) { + if (!canGetUIJList()) + return; + if (enable) + getUIJList().addListSelectionListener(compListListener); + else + getUIJList().removeListSelectionListener(compListListener); + } + + /** this is for MOUSE OVER TERM INFO - changes selection */ + private class CompletionListListener implements ListSelectionListener { + public void valueChanged(ListSelectionEvent e) { + Object source = e.getSource(); + // hate to cast but it is handy here... and it is in fact a JList + if (!(source instanceof JList)) { + System.out.println("source of combo box mouse over event is not JList "+ + source.getClass()); + return; + } + JList jList = (JList)source; + Object selectedValue = jList.getSelectedValue(); + if (selectedValue == null) + return; + //System.out.println("sel val "+selectedValue.getClass()+" name "+selectedValue); + // the selected item should be an OBOClass + if (!(selectedValue instanceof OBOClass)) { + System.out.println("selected completion term is not obo class " + +selectedValue.getClass()); + return; + } + OBOClass oboClass = (OBOClass)selectedValue; + getSelectionManager().selectTerm(AutoComboBox.this,oboClass,getUseTermListener()); + //setTextFromOboClass(oboClass); + } + } // end of CompletionListListener inner class + + private UseTermListener useTermListener; + private UseTermListener getUseTermListener() { + if (useTermListener == null) useTermListener = new ComboUseTermListener(); + return useTermListener; + } + + private class ComboUseTermListener implements UseTermListener { + public void useTerm(UseTermEvent e) { + setOboClass(e.getTerm()); + if (editModel) editModel(); + } + } + + private SelectionManager getSelectionManager() { + return SelectionManager.inst(); + } + + private CharacterI getSelectedCharacter() { + return getSelectionManager().getSelectedCharacter(); + } + + private boolean canGetUIJList() { + return getUIJList() != null; + } + + /** This may return null if not using Metal/Java UI/Look & Feel as JList comes + from the UI - need to implement getting JList from each UI I guess */ + private JList getUIJList() { + ComboBoxUI comboBoxUI = getUI(); + if (!(comboBoxUI instanceof MetalListComboUI)) { + System.out.println("Cant retrieve JList for look & feel, cant do mouse overs " + +comboBoxUI.getClass()); + return null; + } + return ((MetalListComboUI)comboBoxUI).getJList(); + } + + // for TestPhenote + void doMouseOver(int itemNumber) { + //System.out.println("AutoComboBox.doMouseOver not implemented yet"); + if (!canGetUIJList()) return; + JList jList = getUIJList(); + jList.setSelectedIndex(itemNumber); + } + + private class MetalListComboUI extends MetalComboBoxUI { + private JList getJList() { + return listBox; // protected JList in BasicComboBoxUI + } + } + + + + /** Listens for actions from combo boxes and edits model/character + * actions come from mouse select of term as well as return & tab */ + private class ComboBoxActionListener implements ActionListener { + //private OBOClass previousOboClass=null; + + private ComboBoxActionListener() {} + public void actionPerformed(ActionEvent e) { + editCharField(); + } + + /** edits Character field via EditManager. + checks that text in text field from user + is actually an item in completion list, is an obo term. */ + private void editCharField() { + String input = getText(); + if (input == null) return; // probably doesnt happen + // the input should be from selected obo class shouldnt it? is it possible + // for this not to be so? returns null if no oboclass? + // TERM + if (isTermList()) { + try { currentOboClass = getSelectedCompListOboClass(); } + // happens on return on invalid term name + catch (OboException e) { return; } // error msg? + //if (oboClass == null) return; currentOboClass = oboClass; + } + // RELATIONSHIP + else { + try { currentRel = getSelectedRelation(); } + catch (OboException e) { return; } + } + + // EDIT MODEL + if (editModel) + editModel(); +// CharacterI c = getSelectedCharacter(); // from selectionManager +// CharFieldEnum cfe = charField.getCharFieldEnum(); +// UpdateTransaction ut = new UpdateTransaction(c,cfe,oboClass); +// EditManager.inst().updateModel(this,ut); + } + } + + private void editModel() { + OBOClass oboClass; + try { oboClass = getCurrentOboClass(); } + catch (Exception e) { return; } // shouldnt happen, error? + if (charField == null) return; // shouldnt happen + CharacterI c = getSelectedCharacter(); // from selectionManager + CharFieldEnum cfe = charField.getCharFieldEnum(); + // isDifferentia boolean? + UpdateTransaction ut = new UpdateTransaction(c,cfe,oboClass); + EditManager.inst().updateModel(this,ut); + } + + private Logger log; + private Logger log() { + if (log == null) log = Logger.getLogger(getClass()); + return log; + } +} + +// GARBAGE + //private Ontology getOntology() { return ontology; } + + /** Return true if input String matches name of OBOClass in + * defaultComboBoxModel - rename this? this isnt used anymore - delete? + */ +// boolean isInCompletionList(String input) { +// if (defaultComboBoxModel == null) +// return false; +// if (input == null) { +// return false; +// } +// // this is wrong as it holds OBOClasses not Strings! +// //return defaultComboBoxModel.getIndexOf(input) != -1; +// // have to go through all OBOClasses and extract there names - bummer +// // most likely input is selected one check that first +// OBOClass selectedClass = getSelectedCompListOboClass(); +// if (selectedClass != null && input.equals(selectedClass.getName())) +// return true; +// // selected failed(is this possible?) - try everything in the list then... +// for (int i=0; i<defaultComboBoxModel.getSize(); i++) { +// if (input.equals(getCompListOboClass(i).getName())) +// return true; +// } +// return false; +// } + + // mac bug workaround where list covers up textfield on < 12 items no scroll + // from http://www.orbital-computer.de/JComboBox/#usage + // it does note this may cause class cast excpetions?? + // it does cause exception when down arror is typed... hmmm... + //setUI(new BasicComboBoxUI()); // now setting metal look & feel for whole app +//String ontology,AutoComboBox cb) { + //private String previousModelValue=null; + //this.ontology = ontology; + //comboBox = cb; + //setTableFromField(ontology); + //t.editModel(); // or charField.editModel? + // CharacterChangeEvent e = new CharacterChangeEvent(t); + // OR CharEditManager.inst().updateModel(c,cfe,input,previousModelValue); + // CEM.handleTransaction(new UT), CEM.updateModel(UT) + // fireChangeEvent(e); + + // check if input is a real term - i think we can get away with checking + // if in present term completion list - not sure + // i think this is replaced by check above - make sure does the same... +// boolean valid = isInCompletionList(oboClass); //input); +// if (!valid) +// return; + + +// doesnt work - would need to subclass editor component i thing - hassle +// // for TestPhenote +// void simulateBackspace() { +// KeyEvent ke = new KeyEvent(this,KeyEvent.VK_DELETE,java.util.Calendar.getInstance().getTimeInMillis(),0,KeyEvent.VK_UNDEFINED,KeyEvent.CHAR_UNDEFINED); +// //patoComboBox.processKeyEvent(ke); +// getEditor().getEditorComponent().processKeyEvent(ke); + +// } +// Document d = e.getDocument(); +// String input; +// try { +// input = d.getText(0,d.getLength()); +// } +// catch (javax.swing.text.BadLocationException ex) { +// System.out.println(ex); +// return; +// } Deleted: phenote/trunk/src/java/phenote/gui/AutoComboBox.java =================================================================== --- phenote/trunk/src/java/phenote/gui/AutoComboBox.java 2006-10-10 17:20:06 UTC (rev 152) +++ phenote/trunk/src/java/phenote/gui/AutoComboBox.java 2006-10-12 15:06:22 UTC (rev 153) @@ -1,632 +0,0 @@ -package phenote.gui; - -import java.awt.Dimension; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.util.Vector; -import javax.swing.JComboBox; -import javax.swing.JList; -import javax.swing.JTextField; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.DefaultComboBoxModel; -import javax.swing.text.Document; -import javax.swing.plaf.basic.BasicComboBoxEditor; -//import javax.swing.plaf.basic.BasicComboBoxUI; -import javax.swing.plaf.ComboBoxUI; -import javax.swing.plaf.metal.MetalComboBoxUI; - -import org.apache.log4j.Logger; - -import org.geneontology.oboedit.datamodel.OBOClass; -import org.geneontology.oboedit.datamodel.OBOProperty; - -import phenote.datamodel.CharField; -import phenote.datamodel.CharFieldEnum; -import phenote.datamodel.CharacterI; -import phenote.datamodel.Ontology; -import phenote.datamodel.SearchParamsI; -import phenote.edit.EditManager; -import phenote.edit.UpdateTransaction; -import phenote.gui.selection.SelectionManager; -import phenote.gui.selection.UseTermEvent; -import phenote.gui.selection.UseTermListener; - -/** The jcombobox that does auto completion - i had to do some tricks(hacks) to get it - working with mouse over which doesnt come naturally to jcombobox */ - -class AutoComboBox extends JComboBox { - - private Ontology ontology; - private boolean changingCompletionList = false; - private boolean keyTyped = false; - private String previousInput = ""; - private boolean doCompletion = true; - // should we keep state of currentOboClass which is null if not a valid one? - // default combo box.getSelectedItem sortof does this imperfectly - private OBOClass currentOboClass=null; - private OBOProperty currentRel=null; - private DefaultComboBoxModel defaultComboBoxModel; - private SearchParamsI searchParams; - private boolean inTestMode = false; - //private AutoTextFieldEditor autoTextFieldEditor; - private AutoTextField autoTextField; - private CharField charField; - ///** Whether differentia of a post composed term */ - //private boolean isDifferentia = false; - /** if false then model is not edited */ - private boolean editModel; - private CompletionListListener compListListener = new CompletionListListener(); - - /** @param editModel if false then ACB doesnt edit model directly (post comp) */ - AutoComboBox(Ontology ontology,SearchParamsI sp,boolean editModel) { - // this inner class enables retrieving of JList for mouse over - // this will probably throw errors if non metal look & feel is used - setUI(new MetalListComboUI()); - //setFont(new Font("Courier",Font.PLAIN,12)); - - setOntology(ontology); - searchParams = sp; // singleton access? part of ontology? - setEditable(true); - AutoTextFieldEditor autoTextFieldEditor = new AutoTextFieldEditor(); - this.setEditor(autoTextFieldEditor); - setPreferredSize(new Dimension(350,22)); - - enableTermInfoListening(true); // default - //addCompletionListListener(compList); - - //if (editModel) // ComboBoxActionListener edits the model - this.editModel = editModel; - addActionListener(new ComboBoxActionListener()); - - } - - void setOntology(Ontology o) { ontology = o; } - - //void setSearchParams(SearchParamsI sp) { searchParams = sp; } - - void setCharField(CharField charField) { this.charField = charField; } - - ///** If true than the auto combo is for setting the differentia in a post comp term, - // if false (default) than no post comp or genus in post comp */ - //void setIsDifferentia(boolean isDiff) { isDifferentia = isDiff; } - - /** Set text in editable text field of j combo (eg from table select) */ - void setText(String text) { - // do not do term completion on externally set text! - boolean doCompletion = false; - setText(text,doCompletion); - } - - // text from selecting table doesnt do completion, TestPhenote does - void setText(String text, boolean doCompletion) { - this.doCompletion = doCompletion; - this.keyTyped = doCompletion; // key has to be typed for completion - getEditor().setItem(text); - this.doCompletion = true; // set back to default - } - - /** rename setTerm? */ - void setOboClass(OBOClass term) { - if (term == null) { - log().error("Attempt to set term to null"); - return; // debug stack trace? - } - currentOboClass = term; - setText(term.getName(),false); // no completion - } - - /** for relationships (post comp rel) */ - void setRel(OBOProperty rel) { - if (rel == null) { - log().error("Attempt to set term to null"); - return; // debug stack trace? - } - currentRel = rel; - setText(rel.toString(),false); // eventually .getName() - } - - /** Throws exception if there isnt a current obo class, if the user - has typed something that isnt yet a term - hasnt selected a term */ - OBOClass getCurrentOboClass() throws Exception { - if (currentOboClass == null) throw new Exception("term is null"); - if (!currentOboClass.getName().equals(getText())) - throw new Exception("(obo class "+currentOboClass+" and input "+getText()+ - " dont match)"); - return currentOboClass; - } - - /** Throws exception if there isnt a current relation - for relation lists - (post comp), if the user - has typed something that isnt yet a rel - hasnt selected a rel */ - OBOProperty getCurrentRelation() throws Exception { - if (currentRel == null) throw new Exception("term is null"); - if (!currentRel.toString().equals(getText())) - throw new Exception("(relation "+currentRel+" and input "+getText()+ - " dont match)"); - return currentRel; - - } - - /** Return text in text field */ - String getText() { - //return (String)getSelectedItem(); - return getEditor().getItem().toString(); // or editor.getText() ? - } - - - void clear() { - setText(""); - } - - - /** This gets obo class selected in completion list - not from text box - Returns null if nothing selected - can happen amidst changing selection - also used by PostCompGui - this doesnt necasarily stay current with user input hmmm.... - throws OboException if dont have valid term */ - OBOClass getSelectedCompListOboClass() throws OboException { - Object obj = getSelectedObject(); // throws oboex - return oboClassDowncast(obj); // throws oboex - } - - private class OboException extends Exception { - private OboException() { super(); } - private OboException(String s) { super(s); } - } - -// private OBOClass getCompListOboClass(int index) { -// Object obj = defaultComboBoxModel.getElementAt(index); -// return oboClassDowncast(obj); -// } - - // strings get in somehow - need to figure out where they are coming from - private OBOClass oboClassDowncast(Object obj) throws OboException { - if (obj == null) throw new OboException(); - if ( ! (obj instanceof OBOClass)) { - //log.info("Item in completion list not obo class "+obj.getClass()); - throw new OboException("Item in completion list not obo class "+obj.getClass()); - } - return (OBOClass)obj; - } - - private OBOProperty oboPropertyDowncast(Object obj) throws OboException { - if (obj == null) throw new OboException(); - if ( ! (obj instanceof OBOProperty)) { - //log.info("Item in completion list not obo class "+obj.getClass()); - throw new OboException("Item in completion list not obo prop "+obj.getClass()); - } - return (OBOProperty)obj; - } - - /** returns currently selected relation, for auto combos of relations, - throws obo ex if there is no current relation */ - private OBOProperty getSelectedRelation() throws OboException { - Object obj = getSelectedObject(); // throws oboex - return oboPropertyDowncast(obj); // throws oboex - } - - private Object getSelectedObject() throws OboException { - if (defaultComboBoxModel == null) throw new OboException(); // ?? - Object obj = defaultComboBoxModel.getSelectedItem(); - if (obj == null) throw new OboException(); - return obj; - } - - - /** BasicComboBoxEditor uses JTextField as its editing component but is - * only available as a protected variable - odd - adds auto doc & auto key listeners to combo box edit field */ - private class AutoTextFieldEditor extends BasicComboBoxEditor { - - private AutoTextFieldEditor() { - autoTextField = new AutoTextField(); - editor = autoTextField; // protected editor var from BCBE - addDocumentListener(new AutoDocumentListener()); - getTextField().addKeyListener(new AutoKeyListener()); - } - - // editor is protected JTextField - wacky - private JTextField getTextField() { - return editor; - } - - private Document getDocument() { - return getTextField().getDocument(); - } - private void addDocumentListener(DocumentListener dl) { - getDocument().addDocumentListener(dl); - } - } - - - /** AutoTextField inner class - ignores set text when in - * changingCompletionList mode - this is the text field for the - combo box */ - private class AutoTextField extends JTextField { - - private AutoTextField() { - super(25); // width - } - - /** dont set text if changing completion list, if changing text turn off - completion, as changing text is coming from outside not user typing - thus wont get completion on user selection, leaving popup hanging */ - public void setText(String text) { - if (changingCompletionList) - return; - // this makes setText(text,true) turn to false (called from TextPhenote) - // but this is needed from mouse release on selection set text - // is called and will cause completion list to come up after sel - // w/o it... [truncated message content] |