Revision: 1930
http://obo.svn.sourceforge.net/obo/?rev=1930&view=rev
Author: balhoff
Date: 2008-07-29 18:47:20 +0000 (Tue, 29 Jul 2008)
Log Message:
-----------
Added post-composition editor and popup menu for phenotype table.
Modified Paths:
--------------
phenote/trunk/src/java/org/phenoscape/app/DocumentController.java
phenote/trunk/src/java/org/phenoscape/io/URLProxy.java
phenote/trunk/src/java/org/phenoscape/main/PhenoscapeStartupTask.java
phenote/trunk/src/java/org/phenoscape/model/OntologyController.java
phenote/trunk/src/java/org/phenoscape/model/PhenoscapeController.java
phenote/trunk/src/java/org/phenoscape/model/TermSet.java
phenote/trunk/src/java/org/phenoscape/swing/AutoCompleteSupport.java
phenote/trunk/src/java/org/phenoscape/view/PhenoscapeGUIComponent.java
phenote/trunk/src/java/org/phenoscape/view/PhenotypeTableComponent.java
phenote/trunk/src/java/org/phenoscape/view/SpecimenTableComponent.java
phenote/trunk/src/java/org/phenoscape/view/TaxonTableComponent.java
phenote/trunk/src/java/org/phenoscape/view/TermFilterator.java
phenote/trunk/src/java/org/phenoscape/view/TermRenderer.java
Added Paths:
-----------
phenote/trunk/src/java/org/phenoscape/swing/PopupListener.java
phenote/trunk/src/java/org/phenoscape/swing/WindowSizePrefsSaver.java
phenote/trunk/src/java/org/phenoscape/view/PostCompositionEditor.java
Removed Paths:
-------------
phenote/trunk/src/java/org/phenoscape/view/TermEditor.java
Modified: phenote/trunk/src/java/org/phenoscape/app/DocumentController.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/app/DocumentController.java 2008-07-29 17:11:22 UTC (rev 1929)
+++ phenote/trunk/src/java/org/phenoscape/app/DocumentController.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -3,24 +3,31 @@
import java.io.File;
import javax.swing.JFileChooser;
+import javax.swing.JFrame;
import org.apache.log4j.Logger;
import org.bbop.framework.GUIManager;
/**
- * A general class managing reading and writing of files and the data loaded from those files.
+ * A general class managing reading and writing of document files and the data loaded from those files.
* @author Jim Balhoff
*/
public abstract class DocumentController {
private File currentFile;
+ public DocumentController() {
+ this.setWindowTitle(null);
+ }
+
public void open() {
final JFileChooser fileChooser = new JFileChooser();
final int result = fileChooser.showOpenDialog(GUIManager.getManager().getFrame());
if (result == JFileChooser.APPROVE_OPTION) {
- final boolean success = this.readData(fileChooser.getSelectedFile());
- if (!success) { this.runFileReadErrorMessage(); }
+ final File file = fileChooser.getSelectedFile();
+ final boolean success = this.readData(file);
+ if (success) { this.setCurrentFile(file); }
+ else { this.runFileReadErrorMessage(); }
}
}
@@ -36,8 +43,10 @@
final JFileChooser fileChooser = new JFileChooser();
final int result = fileChooser.showSaveDialog(GUIManager.getManager().getFrame());
if (result == JFileChooser.APPROVE_OPTION) {
- final boolean success = this.writeData(fileChooser.getSelectedFile());
- if (!success) { this.runFileWriteErrorMessage(); }
+ final File file = fileChooser.getSelectedFile();
+ final boolean success = this.writeData(file);
+ if (success) { this.setCurrentFile(file); }
+ else { this.runFileWriteErrorMessage(); }
}
}
@@ -47,12 +56,26 @@
public void setCurrentFile(File aFile) {
this.currentFile = aFile;
+ this.setWindowTitle(aFile);
}
public abstract boolean readData(File aFile);
public abstract boolean writeData(File aFile);
+ public abstract JFrame getWindow();
+
+ private void setWindowTitle(File aFile) {
+ final JFrame window = this.getWindow();
+ if (window != null) {
+ if (aFile != null) {
+ window.setTitle(aFile.getName());
+ } else {
+ window.setTitle("Untitled");
+ }
+ }
+ }
+
private void runFileReadErrorMessage() {
log().error("Failed to load file data");
//TODO gui message
Modified: phenote/trunk/src/java/org/phenoscape/io/URLProxy.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/io/URLProxy.java 2008-07-29 17:11:22 UTC (rev 1929)
+++ phenote/trunk/src/java/org/phenoscape/io/URLProxy.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -91,7 +91,7 @@
*/
public File get(URL url, CacheOption option) throws IOException {
if ((option.equals(CacheOption.NO_CACHE)) || ((option.equals(CacheOption.USE_CACHE)) && (this.isOutOfDate(url)))) {
- log().debug("Need to download from web: " + url);
+ log().info("Need to download from web: " + url);
this.downloadToCache(url);
}
return this.getCacheFile(url);
Modified: phenote/trunk/src/java/org/phenoscape/main/PhenoscapeStartupTask.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/main/PhenoscapeStartupTask.java 2008-07-29 17:11:22 UTC (rev 1929)
+++ phenote/trunk/src/java/org/phenoscape/main/PhenoscapeStartupTask.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -9,16 +9,17 @@
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
-import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.bbop.framework.GUIComponentFactory;
+import org.bbop.framework.GUIManager;
import org.bbop.framework.dock.LayoutDriver;
import org.bbop.framework.dock.idw.IDWDriver;
import org.oboedit.gui.tasks.DefaultGUIStartupTask;
import org.phenoscape.app.CrossPlatform;
import org.phenoscape.model.PhenoscapeController;
+import org.phenoscape.swing.WindowSizePrefsSaver;
import org.phenoscape.view.CharacterTableComponentFactory;
import org.phenoscape.view.DataSetComponentFactory;
import org.phenoscape.view.MenuFactory;
@@ -59,7 +60,7 @@
@Override
protected void configureLogging() {
//TODO configure logging properly
- BasicConfigurator.configure();
+ // actually just need to set desired level in configuration file
final Logger rl = LogManager.getRootLogger();
rl.setLevel(Level.DEBUG);
}
@@ -95,23 +96,30 @@
@Override
protected String getAppID() {
- return "Phenoscape";
+ return "Phenex";
}
@Override
protected String getAppName() {
- //return "Phenoscape Annotator";
- return "Phenote";
+ return "Phenex";
}
@Override
protected JFrame createFrame() {
final JFrame frame = super.createFrame();
frame.setTitle(getAppName());
+ // the window prefs saver is not currently working because the BBOP MainFrame is trying to be too smart
+ new WindowSizePrefsSaver(frame, this.getClass().getName() + "mainwindow");
return frame;
}
@Override
+ protected void showFrame() {
+ // BBOP centers and makes frame a certain size - we are overriding this
+ GUIManager.getManager().getFrame().setVisible(true);
+ }
+
+ @Override
protected LayoutDriver createLayoutDriver() {
final LayoutDriver driver = super.createLayoutDriver();
if (driver instanceof IDWDriver) {
Modified: phenote/trunk/src/java/org/phenoscape/model/OntologyController.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/model/OntologyController.java 2008-07-29 17:11:22 UTC (rev 1929)
+++ phenote/trunk/src/java/org/phenoscape/model/OntologyController.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -43,6 +43,7 @@
config.setReadPaths(Arrays.asList(this.getPaths()));
config.setBasicSave(false);
config.setAllowDangling(true);
+ config.setFollowImports(false); // this is required because OBO currently fails if it tries to follow an import and there is no network connection
try {
SessionManager.getManager().setSession(this.fileAdapter.doOperation(OBOAdapter.READ_ONTOLOGY, config, null));
} catch (DataAdapterException e) {
@@ -103,7 +104,9 @@
}
public TermSet getRelationsTermSet() {
- return this.getTermSet(REL, REL_PROPOSED);
+ final TermSet set = this.getTermSet(REL, REL_PROPOSED);
+ set.setIncludesProperties(true);
+ return set;
}
private TermSet getTermSet(String... urls) {
Modified: phenote/trunk/src/java/org/phenoscape/model/PhenoscapeController.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/model/PhenoscapeController.java 2008-07-29 17:11:22 UTC (rev 1929)
+++ phenote/trunk/src/java/org/phenoscape/model/PhenoscapeController.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -5,8 +5,11 @@
import java.util.List;
import java.util.UUID;
+import javax.swing.JFrame;
+
import org.apache.log4j.Logger;
import org.apache.xmlbeans.XmlException;
+import org.bbop.framework.GUIManager;
import org.nexml.x10.NexmlDocument;
import org.phenoscape.app.DocumentController;
import org.phenoscape.io.NeXMLReader;
@@ -32,6 +35,7 @@
private NexmlDocument xmlDoc;
public PhenoscapeController() {
+ super();
this.charactersSelectionModel = new EventSelectionModel<Character>(this.dataSet.getCharacters());
this.charactersSelectionModel.setSelectionMode(EventSelectionModel.SINGLE_SELECTION);
this.taxaSelectionModel = new EventSelectionModel<Taxon>(this.dataSet.getTaxa());
@@ -102,13 +106,12 @@
public EventSelectionModel<Specimen> getCurrentSpecimensSelectionModel() {
return this.currentSpecimensSelectionModel;
}
-
+
@Override
public boolean readData(File aFile) {
log().debug("Read file: " + aFile);
try {
final NeXMLReader reader = new NeXMLReader(aFile);
- this.setCurrentFile(aFile);
this.xmlDoc = reader.getXMLDoc();
this.charactersBlockID = reader.getCharactersBlockID();
this.dataSet.getCharacters().clear(); //TODO this is not well encapsulated
@@ -129,6 +132,10 @@
return false;
}
+ public JFrame getWindow() {
+ return GUIManager.getManager().getFrame();
+ }
+
public SelectionManager getPhenoteSelectionManager() {
return SelectionManager.inst();
}
Modified: phenote/trunk/src/java/org/phenoscape/model/TermSet.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/model/TermSet.java 2008-07-29 17:11:22 UTC (rev 1929)
+++ phenote/trunk/src/java/org/phenoscape/model/TermSet.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -5,11 +5,11 @@
import java.util.List;
import org.obo.datamodel.Namespace;
-import org.obo.datamodel.OBOClass;
+import org.obo.datamodel.OBOObject;
import org.obo.datamodel.OBOSession;
import org.obo.query.QueryEngine;
-import org.obo.query.impl.CategoryQuery;
-import org.obo.query.impl.NamespaceQuery;
+import org.obo.query.impl.CategoryObjQuery;
+import org.obo.query.impl.NamespaceObjQuery;
/**
* A TermSet is used to define a collection of ontology terms. Currently the collection
@@ -21,6 +21,7 @@
private OBOSession session;
private Collection<Namespace> namespaces = new ArrayList<Namespace>();
private Collection<String> categories = new ArrayList<String>();
+ private boolean includesProperties = false;
/**
* @return The OBOSession from which this TermSet draws its terms.
@@ -63,18 +64,27 @@
public void setCategories(Collection<String> categories) {
this.categories = categories;
}
+
+ public boolean includesProperties() {
+ return this.includesProperties;
+ }
+
+ public void setIncludesProperties(boolean includeProperties) {
+ this.includesProperties = includeProperties;
+ }
/**
* @return All terms matching the search criteria of this TermSet, such as its namespaces and categories.
*/
- public Collection<OBOClass> getTerms() {
+ public Collection<OBOObject> getTerms() {
final QueryEngine engine = new QueryEngine(this.getOBOSession());
final List<String> namespaceIDs = new ArrayList<String>();
for (Namespace ns : this.getNamespaces()) { namespaceIDs.add(ns.getID()); }
- final NamespaceQuery query = new NamespaceQuery(namespaceIDs, false, true);
- final Collection<OBOClass> termsInNamespaces = engine.query(query);
+ final NamespaceObjQuery query = new NamespaceObjQuery(namespaceIDs, false, true);
+ query.setJustTerms(!this.includesProperties());
+ final Collection<OBOObject> termsInNamespaces = engine.query(query);
if (this.hasAnyCategory()) {
- return engine.subquery(termsInNamespaces, new CategoryQuery(this.getCategories())).getResults();
+ return engine.subquery(termsInNamespaces, new CategoryObjQuery(this.getCategories())).getResults();
} else {
return termsInNamespaces;
}
Modified: phenote/trunk/src/java/org/phenoscape/swing/AutoCompleteSupport.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/swing/AutoCompleteSupport.java 2008-07-29 17:11:22 UTC (rev 1929)
+++ phenote/trunk/src/java/org/phenoscape/swing/AutoCompleteSupport.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -421,8 +421,7 @@
this.renderer = format == null && defaultRendererInstalled ? null : new StringFunctionRenderer();
// is this combo box a TableCellEditor?
- this.isTableCellEditor = true;
- //this.isTableCellEditor = Boolean.TRUE.equals(comboBox.getClientProperty("JComboBox.isTableCellEditor"));
+ this.isTableCellEditor = Boolean.TRUE.equals(comboBox.getClientProperty("JComboBox.isTableCellEditor"));
// build the ComboBoxModel capable of filtering its values
this.filterMatcherEditor = new TextMatcherEditor<E>(filterator == null ? new DefaultTextFilterator() : filterator);
Added: phenote/trunk/src/java/org/phenoscape/swing/PopupListener.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/swing/PopupListener.java (rev 0)
+++ phenote/trunk/src/java/org/phenoscape/swing/PopupListener.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -0,0 +1,36 @@
+package org.phenoscape.swing;
+
+import java.awt.Point;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+import javax.swing.JPopupMenu;
+
+public class PopupListener extends MouseAdapter {
+ final JPopupMenu menu;
+ Point p;
+
+ public PopupListener(JPopupMenu popupMenu) {
+ this.menu = popupMenu;
+ }
+
+ public void mousePressed(MouseEvent e) {
+ maybeShowPopup(e);
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ maybeShowPopup(e);
+ }
+
+ public Point getLocation() {
+ return this.p;
+ }
+
+ private void maybeShowPopup(MouseEvent e) {
+ p = e.getPoint();
+ if (e.isPopupTrigger()) {
+ this.menu.show(e.getComponent(), e.getX(), e.getY());
+ }
+ }
+
+}
\ No newline at end of file
Added: phenote/trunk/src/java/org/phenoscape/swing/WindowSizePrefsSaver.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/swing/WindowSizePrefsSaver.java (rev 0)
+++ phenote/trunk/src/java/org/phenoscape/swing/WindowSizePrefsSaver.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -0,0 +1,114 @@
+package org.phenoscape.swing;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Window;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.util.prefs.Preferences;
+
+import org.apache.log4j.Logger;
+
+public class WindowSizePrefsSaver {
+
+ private final Window window;
+ private final String autoSaveName;
+ private final WindowWindowListener windowListener = new WindowWindowListener();
+ private final WindowComponentListener componentListener = new WindowComponentListener();
+
+ public WindowSizePrefsSaver(Window window, String autoSaveName) {
+ this.window = window;
+ this.autoSaveName = autoSaveName;
+ this.window.addWindowListener(this.windowListener);
+ this.window.addComponentListener(this.componentListener);
+ this.sizeWindow();
+ }
+
+ /**
+ * Tells this object to remove any listeners from its window.
+ */
+ public void dispose() {
+ this.window.removeWindowListener(this.windowListener);
+ }
+
+ private void sizeWindow() {
+ //TODO need to verify window is on screen and not too big
+ if (!this.hasWindowPrefs()) {
+ log().debug("Window prefs not found");
+ this.window.setLocationRelativeTo(null);
+ } else {
+ this.window.setLocation(this.getWindowLocationPref());
+ this.window.setSize(this.getWindowSizePref());
+ }
+ }
+
+ private void saveWindowPrefs() {
+ this.getSizeNode().putInt("width", this.window.getWidth());
+ this.getSizeNode().putInt("height", this.window.getHeight());
+ this.getLocationNode().putInt("x", this.window.getLocation().x);
+ this.getLocationNode().putInt("y", this.window.getLocation().y);
+ }
+
+ private boolean hasWindowPrefs() {
+ final Dimension size = this.getWindowSizePref();
+ final Point location = this.getWindowLocationPref();
+ return (size.height > -1) && (size.width > -1) && (location.x > -1) && (location.y > -1);
+ }
+
+ private Dimension getWindowSizePref() {
+ return new Dimension(this.getSizeNode().getInt("width", -1), this.getSizeNode().getInt("height", -1));
+ }
+
+ private Point getWindowLocationPref() {
+ return new Point(this.getLocationNode().getInt("x", -1), this.getLocationNode().getInt("y", -1));
+ }
+
+ private Preferences getSizeNode() {
+ return this.getPrefsRoot().node("size");
+ }
+
+ private Preferences getLocationNode() {
+ return this.getPrefsRoot().node("location");
+ }
+
+ private Preferences getPrefsRoot() {
+ return Preferences.userNodeForPackage(this.getClass()).node(this.autoSaveName);
+ }
+
+ private class WindowWindowListener implements WindowListener {
+
+ public void windowActivated(WindowEvent e) {}
+
+ public void windowClosed(WindowEvent e) {}
+
+ public void windowClosing(WindowEvent e) { saveWindowPrefs(); }
+
+ public void windowDeactivated(WindowEvent e) {}
+
+ public void windowDeiconified(WindowEvent e) {}
+
+ public void windowIconified(WindowEvent e) {}
+
+ public void windowOpened(WindowEvent e) {}
+
+ }
+
+ private class WindowComponentListener implements ComponentListener {
+
+ public void componentHidden(ComponentEvent e) {}
+
+ public void componentMoved(ComponentEvent e) { saveWindowPrefs(); }
+
+ public void componentResized(ComponentEvent e) { saveWindowPrefs(); }
+
+ public void componentShown(ComponentEvent e) {}
+
+ }
+
+ private Logger log() {
+ return Logger.getLogger(this.getClass());
+ }
+
+}
Modified: phenote/trunk/src/java/org/phenoscape/view/PhenoscapeGUIComponent.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/view/PhenoscapeGUIComponent.java 2008-07-29 17:11:22 UTC (rev 1929)
+++ phenote/trunk/src/java/org/phenoscape/view/PhenoscapeGUIComponent.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -15,6 +15,7 @@
import org.apache.log4j.Logger;
import org.bbop.framework.AbstractGUIComponent;
import org.obo.datamodel.OBOClass;
+import org.obo.datamodel.OBOObject;
import org.phenoscape.model.PhenoscapeController;
import org.phenoscape.swing.AutoCompleteSupport;
@@ -56,14 +57,24 @@
this.getController().getPhenoteSelectionManager().selectTerm(this, term, false);
}
- protected TableCellEditor createAutocompleteEditor(Collection<OBOClass> terms) {
+ protected JComboBox createAutocompleteBox(Collection<OBOObject> terms) {
+ return this.createAutocompleteBox(terms, false);
+ }
+
+ private JComboBox createAutocompleteBox(Collection<OBOObject> terms, boolean cellEditor) {
final JComboBox comboBox = new JComboBox();
- final AutoCompleteSupport<OBOClass> acs = AutoCompleteSupport.install(comboBox, GlazedLists.eventList(terms), new TermFilterator());
- acs.setValidItemClass(OBOClass.class);
+ comboBox.putClientProperty("JComboBox.isTableCellEditor", cellEditor);
+ final AutoCompleteSupport<OBOObject> acs = AutoCompleteSupport.install(comboBox, GlazedLists.eventList(terms), new TermFilterator());
+ acs.setValidItemClass(OBOObject.class);
+ final ComboPopup popup = this.getComboPopup(comboBox);
+ if (popup != null) { popup.getList().addListSelectionListener(new CompletionListListener()); }
+ return comboBox;
+ }
+
+ protected TableCellEditor createAutocompleteEditor(Collection<OBOObject> terms) {
+ final JComboBox comboBox = this.createAutocompleteBox(terms, true);
final DefaultCellEditor editor = new DefaultCellEditor(comboBox);
editor.setClickCountToStart(2);
- final ComboPopup popup = this.getComboPopup(comboBox);
- if (popup != null) { popup.getList().addListSelectionListener(new CompletionListListener()); }
return editor;
}
Modified: phenote/trunk/src/java/org/phenoscape/view/PhenotypeTableComponent.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/view/PhenotypeTableComponent.java 2008-07-29 17:11:22 UTC (rev 1929)
+++ phenote/trunk/src/java/org/phenoscape/view/PhenotypeTableComponent.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -1,6 +1,7 @@
package org.phenoscape.view;
import java.awt.BorderLayout;
+import java.awt.Point;
import java.awt.event.ActionEvent;
import java.io.FileNotFoundException;
import java.util.Comparator;
@@ -8,6 +9,8 @@
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JButton;
+import javax.swing.JOptionPane;
+import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
@@ -15,10 +18,13 @@
import org.apache.log4j.Logger;
import org.obo.datamodel.OBOClass;
+import org.obo.datamodel.OBOObject;
import org.phenoscape.model.PhenoscapeController;
import org.phenoscape.model.Phenotype;
import org.phenoscape.model.State;
+import org.phenoscape.model.TermSet;
import org.phenoscape.swing.PlaceholderRenderer;
+import org.phenoscape.swing.PopupListener;
import phenote.gui.BugWorkaroundTable;
import phenote.gui.SortDisabler;
@@ -39,6 +45,9 @@
private JButton addPhenotypeButton;
private JButton deletePhenotypeButton;
+ private PopupListener tablePopup;
+ private PhenotypesTableFormat tableFormat;
+ private JTable phenotypesTable;
private final SortedList<Phenotype> sortedPhenotypes;
public PhenotypeTableComponent(String id, PhenoscapeController controller) {
@@ -54,21 +63,23 @@
private void initializeInterface() {
this.setLayout(new BorderLayout());
- final PhenotypesTableFormat tableFormat = new PhenotypesTableFormat();
- final EventTableModel<Phenotype> phenotypesTableModel = new EventTableModel<Phenotype>(this.sortedPhenotypes, tableFormat);
- final JTable phenotypesTable = new BugWorkaroundTable(phenotypesTableModel);
- phenotypesTable.setSelectionModel(this.getController().getCurrentPhenotypesSelectionModel());
- phenotypesTable.setDefaultRenderer(Object.class, new PlaceholderRenderer("None"));
- phenotypesTable.setDefaultRenderer(OBOClass.class, new TermRenderer("None"));
- for (int i = 0; i < phenotypesTable.getColumnCount(); i++) {
- final TableCellEditor editor = tableFormat.getColumnEditor(i);
- if (editor != null) { phenotypesTable.getColumnModel().getColumn(i).setCellEditor(editor); }
+ this.tableFormat = new PhenotypesTableFormat();
+ final EventTableModel<Phenotype> phenotypesTableModel = new EventTableModel<Phenotype>(this.sortedPhenotypes, this.tableFormat);
+ this.phenotypesTable = new BugWorkaroundTable(phenotypesTableModel);
+ this.phenotypesTable.setSelectionModel(this.getController().getCurrentPhenotypesSelectionModel());
+ this.phenotypesTable.setDefaultRenderer(Object.class, new PlaceholderRenderer("None"));
+ this.phenotypesTable.setDefaultRenderer(OBOObject.class, new TermRenderer("None"));
+ for (int i = 0; i < this.phenotypesTable.getColumnCount(); i++) {
+ final TableCellEditor editor = this.tableFormat.getColumnEditor(i);
+ if (editor != null) { this.phenotypesTable.getColumnModel().getColumn(i).setCellEditor(editor); }
}
- phenotypesTable.putClientProperty("Quaqua.Table.style", "striped");
- new TableColumnPrefsSaver(phenotypesTable, this.getClass().getName());
- final TableComparatorChooser<Phenotype> sortChooser = new TableComparatorChooser<Phenotype>(phenotypesTable, this.sortedPhenotypes, false);
+ this.phenotypesTable.putClientProperty("Quaqua.Table.style", "striped");
+ new TableColumnPrefsSaver(this.phenotypesTable, this.getClass().getName());
+ this.tablePopup = new PopupListener(this.createTablePopupMenu());
+ this.phenotypesTable.addMouseListener(this.tablePopup);
+ final TableComparatorChooser<Phenotype> sortChooser = new TableComparatorChooser<Phenotype>(this.phenotypesTable, this.sortedPhenotypes, false);
sortChooser.addSortActionListener(new SortDisabler());
- this.add(new JScrollPane(phenotypesTable), BorderLayout.CENTER);
+ this.add(new JScrollPane(this.phenotypesTable), BorderLayout.CENTER);
this.add(this.createToolBar(), BorderLayout.NORTH);
}
@@ -106,6 +117,20 @@
return null;
}
}
+
+ private void runPostCompositionForTermAtPoint(Point p) {
+ final int column = this.phenotypesTable.getTableHeader().columnAtPoint(p);
+ final int row = this.phenotypesTable.rowAtPoint(p);
+ if (!this.tableFormat.getColumnClass(column).equals(OBOObject.class)) return;
+ final Phenotype phenotype = this.sortedPhenotypes.get(row);
+ final OBOClass term = (OBOClass)(this.tableFormat.getColumnValue(phenotype, column));
+ final PostCompositionEditor pce = new PostCompositionEditor(this.getController(), tableFormat.getColumnTermSet(column));
+ pce.setTerm(term);
+ final int result = pce.runPostCompositionDialog();
+ if (result == JOptionPane.OK_OPTION) {
+ this.tableFormat.setColumnValue(phenotype, pce.getTerm(), column);
+ }
+ }
private JToolBar createToolBar() {
final JToolBar toolBar = new JToolBar();
@@ -131,6 +156,16 @@
return toolBar;
}
+ private JPopupMenu createTablePopupMenu() {
+ final JPopupMenu menu = new JPopupMenu();
+ menu.add(new AbstractAction("Create Post-composed Term") {
+ public void actionPerformed(ActionEvent e) {
+ runPostCompositionForTermAtPoint(tablePopup.getLocation());
+ }
+ });
+ return menu;
+ }
+
private class PhenotypesTableFormat implements WritableTableFormat<Phenotype>, AdvancedTableFormat<Phenotype> {
public boolean isEditable(Phenotype phenotype, int column) {
@@ -168,14 +203,27 @@
}
}
+ public TermSet getColumnTermSet(int column) {
+ switch (column) {
+ case 0: return getController().getOntologyController().getEntityTermSet();
+ case 1: return getController().getOntologyController().getQualityTermSet();
+ case 2: return getController().getOntologyController().getRelatedEntityTermSet();
+ case 3: return null;
+ case 4: return null;
+ case 5: return getController().getOntologyController().getUnitTermSet();
+ case 6: return null;
+ default: return null;
+ }
+ }
+
public TableCellEditor getColumnEditor(int column) {
switch (column) {
- case 0: return createAutocompleteEditor(getController().getOntologyController().getEntityTermSet().getTerms());
- case 1: return createAutocompleteEditor(getController().getOntologyController().getQualityTermSet().getTerms());
- case 2: return createAutocompleteEditor(getController().getOntologyController().getRelatedEntityTermSet().getTerms());
+ case 0: return createAutocompleteEditor(this.getColumnTermSet(column).getTerms());
+ case 1: return createAutocompleteEditor(this.getColumnTermSet(column).getTerms());
+ case 2: return createAutocompleteEditor(this.getColumnTermSet(column).getTerms());
case 3: return null;
case 4: return null;
- case 5: return createAutocompleteEditor(getController().getOntologyController().getUnitTermSet().getTerms());
+ case 5: return createAutocompleteEditor(this.getColumnTermSet(column).getTerms());
case 6: return null;
default: return null;
}
@@ -196,12 +244,12 @@
public Class<?> getColumnClass(int column) {
switch (column) {
- case 0: return OBOClass.class;
- case 1: return OBOClass.class;
- case 2: return OBOClass.class;
+ case 0: return OBOObject.class;
+ case 1: return OBOObject.class;
+ case 2: return OBOObject.class;
case 3: return Integer.class;
case 4: return Float.class;
- case 5: return OBOClass.class;
+ case 5: return OBOObject.class;
case 6: return String.class;
default: return null;
}
@@ -221,7 +269,7 @@
}
}
-
+
private Logger log() {
return Logger.getLogger(this.getClass());
}
Added: phenote/trunk/src/java/org/phenoscape/view/PostCompositionEditor.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/view/PostCompositionEditor.java (rev 0)
+++ phenote/trunk/src/java/org/phenoscape/view/PostCompositionEditor.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -0,0 +1,269 @@
+package org.phenoscape.view;
+
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.io.FileNotFoundException;
+import java.util.Comparator;
+
+import javax.swing.AbstractAction;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JToolBar;
+import javax.swing.table.TableCellEditor;
+
+import org.apache.log4j.Logger;
+import org.obo.datamodel.Link;
+import org.obo.datamodel.LinkedObject;
+import org.obo.datamodel.OBOClass;
+import org.obo.datamodel.OBOObject;
+import org.obo.datamodel.OBOProperty;
+import org.phenoscape.model.PhenoscapeController;
+import org.phenoscape.model.TermSet;
+
+import phenote.datamodel.OboUtil;
+import phenote.gui.BugWorkaroundTable;
+import phenote.util.FileUtil;
+import ca.odell.glazedlists.BasicEventList;
+import ca.odell.glazedlists.EventList;
+import ca.odell.glazedlists.GlazedLists;
+import ca.odell.glazedlists.gui.AdvancedTableFormat;
+import ca.odell.glazedlists.gui.WritableTableFormat;
+import ca.odell.glazedlists.swing.EventSelectionModel;
+import ca.odell.glazedlists.swing.EventTableModel;
+
+public class PostCompositionEditor extends PhenoscapeGUIComponent {
+
+ private OBOClass genus;
+ private EventList<Differentia> diffs = new BasicEventList<Differentia>();
+ private EventSelectionModel<Differentia> selectionModel = new EventSelectionModel<Differentia>(diffs);
+ private final TermSet termSet;
+ private JComboBox genusBox;
+ private JButton addDifferentiaButton;
+ private JButton deleteDifferentiaButton;
+
+ public PostCompositionEditor(String id, PhenoscapeController controller, TermSet terms) {
+ super(id, controller);
+ this.termSet = terms;
+ }
+
+ public PostCompositionEditor(PhenoscapeController controller, TermSet terms) {
+ this("", controller, terms);
+ this.initializeInterface();
+ }
+
+ @Override
+ public void init() {
+ super.init();
+ this.initializeInterface();
+ }
+
+ public void addDifferentia() {
+ this.diffs.add(new Differentia());
+ }
+
+ public void deleteSelectedDifferentia() {
+ this.selectionModel.getSelected().clear();
+ }
+
+ private void updateGenus() {
+ this.genus = (OBOClass)(this.genusBox.getSelectedItem());
+ }
+
+ public OBOClass getTerm() {
+ for (Differentia diff : this.diffs) {
+ if (!diff.isComplete()) {
+ this.diffs.remove(diff);
+ }
+ }
+ if (this.diffs.isEmpty()) {
+ return this.genus;
+ } else {
+ final OboUtil util = OboUtil.initPostCompTerm(this.genus);
+ for (Differentia diff : this.diffs) {
+ util.addRelDiff(diff.getRelation(), diff.getTerm());
+ }
+ return util.getPostCompTerm();
+ }
+ }
+
+ public void setTerm(OBOClass aTerm) {
+ this.diffs.clear();
+ if ((aTerm != null) && (OboUtil.isPostCompTerm(aTerm))) {
+ this.genus = OboUtil.getGenusTerm(aTerm);
+ for(Link link : OboUtil.getAllDifferentia(aTerm)) {
+ final Differentia diff = new Differentia();
+ diff.setRelation(link.getType());
+ final LinkedObject parent = link.getParent();
+ if (parent instanceof OBOClass) {
+ diff.setTerm((OBOClass)parent);
+ } else {
+ log().error("Differentia is not an OBOClass: " + parent);
+ }
+ this.diffs.add(diff);
+ }
+ } else {
+ this.genus = aTerm;
+ }
+ this.genusBox.setSelectedItem((OBOObject)this.genus);
+ }
+
+ public int runPostCompositionDialog() {
+ if (this.genusBox == null) {
+ this.init();
+ }
+ this.setPreferredSize(new Dimension(300, 200));
+ return JOptionPane.showConfirmDialog(null, this, "Post-composition Editor", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
+ }
+
+ public void initializeInterface() {
+ this.setLayout(new GridBagLayout());
+ final GridBagConstraints labelConstraints = new GridBagConstraints();
+ this.add(new JLabel("Genus:"), labelConstraints);
+ final GridBagConstraints comboConstraints = new GridBagConstraints();
+ comboConstraints.gridx = 1;
+ comboConstraints.fill = GridBagConstraints.HORIZONTAL;
+ comboConstraints.weightx = 1.0;
+ this.genusBox = this.createAutocompleteBox(this.termSet.getTerms());
+ this.genusBox.setAction(new AbstractAction() {
+ public void actionPerformed(ActionEvent e) {
+ updateGenus();
+ }
+ });
+ this.add(this.genusBox, comboConstraints);
+ final DifferentiaTableFormat format = new DifferentiaTableFormat();
+ final EventTableModel<Differentia> model = new EventTableModel<Differentia>(this.diffs, format);
+ final JTable diffTable = new BugWorkaroundTable(model);
+ diffTable.setSelectionModel(this.selectionModel);
+ diffTable.setDefaultRenderer(OBOObject.class, new TermRenderer("None"));
+ diffTable.putClientProperty("Quaqua.Table.style", "striped");
+ diffTable.getColumnModel().getColumn(0).setCellEditor(format.getColumnEditor(0));
+ diffTable.getColumnModel().getColumn(1).setCellEditor(format.getColumnEditor(1));
+ final GridBagConstraints tableConstraints = new GridBagConstraints();
+ tableConstraints.gridy = 1;
+ tableConstraints.gridwidth = 2;
+ tableConstraints.fill = GridBagConstraints.BOTH;
+ tableConstraints.weighty = 1.0;
+ this.add(new JScrollPane(diffTable), tableConstraints);
+ final GridBagConstraints toolbarConstraints = new GridBagConstraints();
+ toolbarConstraints.gridy = 2;
+ toolbarConstraints.gridwidth = 2;
+ toolbarConstraints.fill = GridBagConstraints.HORIZONTAL;
+ toolbarConstraints.weightx = 1.0;
+ this.add(this.createToolBar(), toolbarConstraints);
+ }
+
+ private JToolBar createToolBar() {
+ final JToolBar toolBar = new JToolBar();
+ try {
+ this.addDifferentiaButton = new JButton(new AbstractAction(null, new ImageIcon(FileUtil.findUrl("images/list-add.png"))) {
+ public void actionPerformed(ActionEvent e) {
+ addDifferentia();
+ }
+ });
+ this.addDifferentiaButton.setToolTipText("Add Differentia");
+ toolBar.add(this.addDifferentiaButton);
+ this.deleteDifferentiaButton = new JButton(new AbstractAction(null, new ImageIcon(FileUtil.findUrl("images/list-remove.png"))) {
+ public void actionPerformed(ActionEvent e) {
+ deleteSelectedDifferentia();
+ }
+ });
+ this.deleteDifferentiaButton.setToolTipText("Delete Differentia");
+ toolBar.add(this.deleteDifferentiaButton);
+ } catch (FileNotFoundException e) {
+ log().error("Couldn't find toolbar icons", e);
+ }
+ toolBar.setFloatable(false);
+ return toolBar;
+ }
+
+ private static class Differentia {
+
+ private OBOProperty relation;
+ private OBOClass term;
+
+ public OBOProperty getRelation() {
+ return this.relation;
+ }
+
+ public void setRelation(OBOProperty relation) {
+ this.relation = relation;
+ }
+
+ public OBOClass getTerm() {
+ return this.term;
+ }
+
+ public void setTerm(OBOClass term) {
+ this.term = term;
+ }
+
+ public boolean isComplete() {
+ return (this.relation == null) || (this.term == null);
+ }
+
+ }
+
+ private class DifferentiaTableFormat implements WritableTableFormat<Differentia>, AdvancedTableFormat<Differentia> {
+
+ public boolean isEditable(Differentia diff, int column) {
+ return true;
+ }
+
+ public TableCellEditor getColumnEditor(int column) {
+ switch (column) {
+ case 0: return createAutocompleteEditor(getController().getOntologyController().getRelationsTermSet().getTerms());
+ case 1: return createAutocompleteEditor(termSet.getTerms());
+ default: return null;
+ }
+ }
+
+ public Differentia setColumnValue(Differentia diff, Object editedValue, int column) {
+ switch(column) {
+ case 0: diff.setRelation((OBOProperty)editedValue); break;
+ case 1: diff.setTerm((OBOClass)editedValue); break;
+ }
+ return diff;
+ }
+
+ public int getColumnCount() {
+ return 2;
+ }
+
+ public String getColumnName(int column) {
+ switch(column) {
+ case 0: return "Relationship";
+ case 1: return "Differentia";
+ }
+ return null;
+ }
+
+ public Object getColumnValue(Differentia diff, int column) {
+ switch(column) {
+ case 0: return diff.getRelation();
+ case 1: return diff.getTerm();
+ }
+ return null;
+ }
+
+ public Class<?> getColumnClass(int column) {
+ return OBOObject.class;
+ }
+
+ public Comparator<?> getColumnComparator(int column) {
+ return GlazedLists.comparableComparator();
+ }
+
+ }
+
+ private Logger log() {
+ return Logger.getLogger(this.getClass());
+ }
+
+}
Modified: phenote/trunk/src/java/org/phenoscape/view/SpecimenTableComponent.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/view/SpecimenTableComponent.java 2008-07-29 17:11:22 UTC (rev 1929)
+++ phenote/trunk/src/java/org/phenoscape/view/SpecimenTableComponent.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -14,6 +14,7 @@
import org.apache.log4j.Logger;
import org.obo.datamodel.OBOClass;
+import org.obo.datamodel.OBOObject;
import org.phenoscape.model.PhenoscapeController;
import org.phenoscape.model.Specimen;
import org.phenoscape.model.Taxon;
@@ -92,7 +93,7 @@
final JTable specimensTable = new BugWorkaroundTable(specimensTableModel);
specimensTable.setSelectionModel(this.getController().getCurrentSpecimensSelectionModel());
specimensTable.setDefaultRenderer(Object.class, new PlaceholderRenderer("None"));
- specimensTable.setDefaultRenderer(OBOClass.class, new TermRenderer("None"));
+ specimensTable.setDefaultRenderer(OBOObject.class, new TermRenderer("None"));
specimensTable.getColumnModel().getColumn(0).setCellEditor(this.createAutocompleteEditor(this.getController().getOntologyController().getCollectionTermSet().getTerms()));
specimensTable.putClientProperty("Quaqua.Table.style", "striped");
new TableColumnPrefsSaver(specimensTable, this.getClass().getName());
@@ -164,7 +165,7 @@
public Class<?> getColumnClass(int column) {
switch(column) {
- case 0: return OBOClass.class;
+ case 0: return OBOObject.class;
case 1: return String.class;
default: return null;
}
Modified: phenote/trunk/src/java/org/phenoscape/view/TaxonTableComponent.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/view/TaxonTableComponent.java 2008-07-29 17:11:22 UTC (rev 1929)
+++ phenote/trunk/src/java/org/phenoscape/view/TaxonTableComponent.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -14,6 +14,7 @@
import org.apache.log4j.Logger;
import org.obo.datamodel.OBOClass;
+import org.obo.datamodel.OBOObject;
import org.phenoscape.model.PhenoscapeController;
import org.phenoscape.model.Taxon;
import org.phenoscape.swing.PlaceholderRenderer;
@@ -76,7 +77,7 @@
final JTable taxaTable = new BugWorkaroundTable(taxaTableModel);
taxaTable.setSelectionModel(this.getController().getTaxaSelectionModel());
taxaTable.setDefaultRenderer(Object.class, new PlaceholderRenderer("None"));
- taxaTable.setDefaultRenderer(OBOClass.class, new TermRenderer("None"));
+ taxaTable.setDefaultRenderer(OBOObject.class, new TermRenderer("None"));
taxaTable.getColumnModel().getColumn(0).setCellEditor(this.createAutocompleteEditor(this.getController().getOntologyController().getTaxonTermSet().getTerms()));
taxaTable.putClientProperty("Quaqua.Table.style", "striped");
new TableColumnPrefsSaver(taxaTable, this.getClass().getName());
@@ -147,7 +148,7 @@
public Class<?> getColumnClass(int column) {
switch (column) {
- case 0: return OBOClass.class;
+ case 0: return OBOObject.class;
case 1: return String.class;
default: return null;
}
Deleted: phenote/trunk/src/java/org/phenoscape/view/TermEditor.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/view/TermEditor.java 2008-07-29 17:11:22 UTC (rev 1929)
+++ phenote/trunk/src/java/org/phenoscape/view/TermEditor.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -1,54 +0,0 @@
-package org.phenoscape.view;
-
-import java.awt.Component;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.Collection;
-
-import javax.swing.JTable;
-import javax.swing.JTextField;
-
-import org.obo.datamodel.OBOClass;
-import org.phenoscape.model.TermSet;
-
-import phenote.gui.CorrectLineBorderCellEditor;
-
-// this class is temporary, unfinished, and just for playing around
-public class TermEditor extends CorrectLineBorderCellEditor implements ActionListener {
-
- private OBOClass currentTerm;
- private final JTextField textField;
- private final TermSet termSet;
-
- public TermEditor(JTextField textField, TermSet terms) {
- super(textField);
- this.textField = textField;
- this.textField.addActionListener(this);
- this.termSet = terms;
- }
-
- @Override
- public Object getCellEditorValue() {
- return this.currentTerm;
- }
-
- @Override
- public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
- this.currentTerm = (OBOClass)value;
- final String editValue = this.currentTerm == null ? "" : this.currentTerm.getName();
- return super.getTableCellEditorComponent(table, editValue, isSelected, row, column);
- }
-
- public void actionPerformed(ActionEvent e) {
- final String candidateText = this.textField.getText();
- final Collection<OBOClass> terms = this.termSet.getTerms();
- for (OBOClass term : terms) {
- if (term.getName().equals(candidateText)) {
- this.currentTerm = term;
- return;
- }
- }
- this.currentTerm = null;
- }
-
-}
Modified: phenote/trunk/src/java/org/phenoscape/view/TermFilterator.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/view/TermFilterator.java 2008-07-29 17:11:22 UTC (rev 1929)
+++ phenote/trunk/src/java/org/phenoscape/view/TermFilterator.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -2,14 +2,14 @@
import java.util.List;
-import org.obo.datamodel.OBOClass;
+import org.obo.datamodel.OBOObject;
import org.obo.datamodel.Synonym;
import ca.odell.glazedlists.TextFilterator;
-public class TermFilterator implements TextFilterator<OBOClass> {
+public class TermFilterator implements TextFilterator<OBOObject> {
- public void getFilterStrings(List<String> list, OBOClass term) {
+ public void getFilterStrings(List<String> list, OBOObject term) {
list.add(term.getName());
for (Synonym synonym : term.getSynonyms()) {
list.add(synonym.getText());
Modified: phenote/trunk/src/java/org/phenoscape/view/TermRenderer.java
===================================================================
--- phenote/trunk/src/java/org/phenoscape/view/TermRenderer.java 2008-07-29 17:11:22 UTC (rev 1929)
+++ phenote/trunk/src/java/org/phenoscape/view/TermRenderer.java 2008-07-29 18:47:20 UTC (rev 1930)
@@ -4,7 +4,7 @@
import javax.swing.JTable;
-import org.obo.datamodel.OBOClass;
+import org.obo.datamodel.OBOObject;
import org.phenoscape.swing.PlaceholderRenderer;
/**
@@ -21,7 +21,7 @@
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value != null) {
- final OBOClass term = (OBOClass)value;
+ final OBOObject term = (OBOObject)value;
this.setToolTipText(term.getID());
return super.getTableCellRendererComponent(table, term.getName(), isSelected, hasFocus, row, column);
} else {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|