diff --git a/uk/ac/sanger/artemis/components/genebuilder/BasicGeneBuilderFrame.java b/uk/ac/sanger/artemis/components/genebuilder/BasicGeneBuilderFrame.java index 1bcc11e409b7d51114a19193fd997b3be7159f7f..16e0558cd80b22d4200486c6a718de5df297fb02 100644 --- a/uk/ac/sanger/artemis/components/genebuilder/BasicGeneBuilderFrame.java +++ b/uk/ac/sanger/artemis/components/genebuilder/BasicGeneBuilderFrame.java @@ -32,6 +32,7 @@ import java.awt.event.ActionListener; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; +import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -71,6 +72,7 @@ import uk.ac.sanger.artemis.components.MessageDialog; import uk.ac.sanger.artemis.components.QualifierTextArea; import uk.ac.sanger.artemis.components.Utilities; import uk.ac.sanger.artemis.components.genebuilder.cv.CVPanel; + import uk.ac.sanger.artemis.components.genebuilder.gff.BasicPropertiesPanel; import uk.ac.sanger.artemis.components.genebuilder.gff.PropertiesPanel; import uk.ac.sanger.artemis.components.genebuilder.ortholog.MatchPanel; @@ -107,6 +109,7 @@ public class BasicGeneBuilderFrame extends JFrame private CVPanel cvPanel; private MatchPanel matchForm; private BasicPropertiesPanel propertiesPanel; + private ReferencesPanel refPanel; private QualifierTextArea qualifier_text_area; private JTabbedPane tabPane = new JTabbedPane(); private JTextField locationText = new JTextField(60); @@ -490,22 +493,30 @@ public class BasicGeneBuilderFrame extends JFrame panel.setBackground(Color.WHITE); propertiesPanel = new BasicPropertiesPanel(chadoGene, this); - addToPanel(propertiesPanel, panel, "Properties",""); + addToPanel(propertiesPanel, panel, "Properties",null); Feature protein = (Feature) chadoGene.getProteinOfTranscript(transcriptName).getUserData(); GeneUtils.addLazyQualifiers((GFFStreamFeature)protein.getEmblFeature()); - + + // + // literature + refPanel = new ReferencesPanel(protein); + addToPanel(refPanel, panel, "Literature/Dbxref", null); + + // + // core text qualifier_text_area = new QualifierTextArea(); cvPanel = new CVPanel(protein); matchForm = new MatchPanel(protein, (DocumentEntry)getFeature().getEmblFeature().getEntry()); - qualifier_text_area.getDocument().addDocumentListener(new TextAreaDocumentListener()); + qualifier_text_area.getDocument().addDocumentListener( + new TextAreaDocumentListener(qualifier_text_area)); qualifier_text_area.setText(getQualifierString(entry_group, protein)); - addToPanel(qualifier_text_area, panel, "Core", ""); + addToPanel(qualifier_text_area, panel, "Core", null); addToPanel(cvPanel, panel, "Controlled Vocabulary", CVPanel.getDescription()); matchForm.updateFromFeature(protein); @@ -515,18 +526,6 @@ public class BasicGeneBuilderFrame extends JFrame ((JComponent)tabPane.getSelectedComponent()).add(jsp); tabPane.addChangeListener(changeListener); } - - private void setQualifierTextAreaSize(Document doc) - { - Element root = doc.getDefaultRootElement(); - int lines = root.getElementCount(); - int lineHeight = qualifier_text_area.getFontMetrics( - qualifier_text_area.getFont()).getHeight(); - - qualifier_text_area.setPreferredSize( - new Dimension( qualifier_text_area.getPreferredSize().width, - lineHeight*lines)); - } /** * Return a string containing one qualifier per line. These are the @@ -548,6 +547,7 @@ public class BasicGeneBuilderFrame extends JFrame if( (CVPanel.isCvTag(this_qualifier)) || (PropertiesPanel.isPropertiesTag(this_qualifier, feature)) || (MatchPanel.isMatchTag(this_qualifier)) || + (ReferencesPanel.isReferenceTag(this_qualifier)) || (ProteinMapPanel.isProteinMapElement(this_qualifier)) ) continue; @@ -700,6 +700,13 @@ public class BasicGeneBuilderFrame extends JFrame if(orthologQualifiers != null && orthologQualifiers.size() > 0) qualifiers.addAll(orthologQualifiers); } + + if(refPanel != null) + { + QualifierVector referenceQualifiers = refPanel.getQualifiers(); + if(referenceQualifiers != null && referenceQualifiers.size() > 0) + qualifiers.addAll(referenceQualifiers); + } } catch(QualifierParseException exception) { @@ -991,24 +998,4 @@ public class BasicGeneBuilderFrame extends JFrame repaint(); } - class TextAreaDocumentListener implements DocumentListener - { - public void insertUpdate(DocumentEvent e) - { - updateSize(e); - } - public void removeUpdate(DocumentEvent e) - { - updateSize(e); - } - - //Plain text components do not fire these events - public void changedUpdate(DocumentEvent e) {} - - public void updateSize(DocumentEvent e) - { - setQualifierTextAreaSize( (Document)e.getDocument() ); - } - } - } diff --git a/uk/ac/sanger/artemis/components/genebuilder/ReferencesPanel.java b/uk/ac/sanger/artemis/components/genebuilder/ReferencesPanel.java new file mode 100644 index 0000000000000000000000000000000000000000..10074b0313b69d0f1e9256cac9c08ff53d613c47 --- /dev/null +++ b/uk/ac/sanger/artemis/components/genebuilder/ReferencesPanel.java @@ -0,0 +1,172 @@ +/* ReferencesPanel.java + * This file is part of Artemis + * + * Copyright (C) 2009 Genome Research Limited + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/components/genebuilder/gff/PropertiesPanel.java,v 1.11 2009-08-17 12:50:42 tjc Exp $ + */ + +package uk.ac.sanger.artemis.components.genebuilder; + +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; + +import javax.swing.BorderFactory; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import uk.ac.sanger.artemis.Feature; +import uk.ac.sanger.artemis.components.QualifierTextArea; +import uk.ac.sanger.artemis.io.Qualifier; +import uk.ac.sanger.artemis.io.QualifierVector; +import uk.ac.sanger.artemis.util.StringVector; + +public class ReferencesPanel extends JPanel +{ + private static final long serialVersionUID = 1L; + private QualifierTextArea literatureTextArea; + private QualifierTextArea dbxrefTextArea; + + public ReferencesPanel(final Feature feature) + { + super(new FlowLayout(FlowLayout.LEFT)); + updateFromFeature(feature); + } + + /** + * Return true if this is a literature or dbxref qualifier + * @param qualifier + * @return + */ + public static boolean isReferenceTag(final Qualifier qualifier) + { + if(qualifier.getName().equals("literature") || + qualifier.getName().equalsIgnoreCase("Dbxref")) + return true; + return false; + } + + private void updateFromFeature(Feature feature) + { + GridBagConstraints c = new GridBagConstraints(); + JPanel gridPanel = new JPanel(new GridBagLayout()); + gridPanel.setBackground(Color.white); + + // + // literature & dbxref + literatureTextArea = new QualifierTextArea(1,81); + literatureTextArea.setBorder(BorderFactory.createLineBorder(Color.gray)); + dbxrefTextArea = new QualifierTextArea(1,81); + dbxrefTextArea.setBorder(BorderFactory.createLineBorder(Color.gray)); + + literatureTextArea.getDocument().addDocumentListener( + new TextAreaDocumentListener(literatureTextArea)); + + dbxrefTextArea.getDocument().addDocumentListener( + new TextAreaDocumentListener(dbxrefTextArea)); + + final QualifierVector qualifiers = feature.getQualifiers().copy(); + final StringBuffer litBuffer = new StringBuffer(); + final StringBuffer dbxrefBuffer = new StringBuffer(); + + for(int i = 0 ; i < qualifiers.size(); ++i) + { + Qualifier this_qualifier = (Qualifier)qualifiers.elementAt(i); + if(this_qualifier.getName().equals("literature")) + appendToBuffer(this_qualifier.getValues(), litBuffer); + else if(this_qualifier.getName().equalsIgnoreCase("Dbxref")) + appendToBuffer(this_qualifier.getValues(), dbxrefBuffer); + } + + c.gridx = 0; + c.gridy = 0; + c.ipadx = 5; + c.ipady = 5; + c.anchor = GridBagConstraints.NORTHWEST; + c.fill = GridBagConstraints.NONE; + gridPanel.add(new JLabel("Literature"),c); + c.gridx = 1; + gridPanel.add(literatureTextArea,c); + + c.gridx = 0; + c.gridy = 1; + gridPanel.add(new JLabel("Dbxref"),c); + c.gridx = 1; + gridPanel.add(dbxrefTextArea,c); + + add(gridPanel); + + literatureTextArea.setText(litBuffer.toString()+"\n"); + dbxrefTextArea.setText(dbxrefBuffer.toString()+"\n"); + } + + private void appendToBuffer(StringVector qualifierStr, StringBuffer buff) + { + for (int j = 0; j < qualifierStr.size(); ++j) + { + String str = (String) qualifierStr.elementAt(j); + if(j!=0) + buff.append(", "+str); + else + buff.append(str); + } + } + + /** + * Get the latest (edited) literature/dbxref qualifiers + * @return + */ + public QualifierVector getQualifiers() + { + QualifierVector referenceQualifier = null; + String literatureTxt = literatureTextArea.getText().trim(); + + if(!literatureTxt.equals("")) + { + referenceQualifier = new QualifierVector(); + String[] lits = getValues(literatureTxt); + StringVector litValues = new StringVector(lits); + Qualifier literature = new Qualifier("literature",litValues); + referenceQualifier.setQualifier(literature); + } + + String dbxrefTxt = dbxrefTextArea.getText().trim(); + if(!dbxrefTxt.equals("")) + { + if(referenceQualifier == null) + referenceQualifier = new QualifierVector(); + String[] dbxrefs = getValues(dbxrefTxt); + StringVector dbxrefsValues = new StringVector(dbxrefs); + Qualifier dbxrefsQualifier = new Qualifier("Dbxref",dbxrefsValues); + referenceQualifier.setQualifier(dbxrefsQualifier); + } + + return referenceQualifier; + } + + private String[] getValues(String txt) + { + String delim = "[\t\n\f\r,]"; + String[] lits = txt.split(delim); + for(int i=0; i<lits.length; i++) + lits[i] = lits[i].trim(); + return lits; + } + +} \ No newline at end of file diff --git a/uk/ac/sanger/artemis/components/genebuilder/TextAreaDocumentListener.java b/uk/ac/sanger/artemis/components/genebuilder/TextAreaDocumentListener.java new file mode 100644 index 0000000000000000000000000000000000000000..37a482f1e0453b27e8a6d2a5d261c852223b9b57 --- /dev/null +++ b/uk/ac/sanger/artemis/components/genebuilder/TextAreaDocumentListener.java @@ -0,0 +1,148 @@ +/* TextAreaDocumentListener + * + * This file is part of Artemis + * + * Copyright(C) 2009 Genome Research Limited + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or(at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ +package uk.ac.sanger.artemis.components.genebuilder; + +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.util.StringTokenizer; + +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.Document; + +import uk.ac.sanger.artemis.components.QualifierTextArea; + + +public class TextAreaDocumentListener implements DocumentListener +{ + private QualifierTextArea qta; + + public TextAreaDocumentListener(QualifierTextArea qta) + { + this.qta = qta; + } + + public void insertUpdate(DocumentEvent e) + { + updateSize(e); + } + + public void removeUpdate(DocumentEvent e) + { + updateSize(e); + } + + // Plain text components do not fire these events + public void changedUpdate(DocumentEvent e) + { + } + + private void updateSize(DocumentEvent e) + { + setQualifierTextAreaSize((Document) e.getDocument()); + } + +/* private int getLineCount(Document doc) + { + // get last visible character's offset + int lineEndOffset = 0; + int line = 0; + // go to end of each line until last character of last line is reached + try + { + while (lineEndOffset < qta.getDocument().getEndPosition().getOffset() && line < 50) + { + lineEndOffset = Utilities.getRowEnd(qta, lineEndOffset+1); + line++; + } + } + catch (BadLocationException e){} + + if(line == 50) + { + Element root = doc.getDefaultRootElement(); + line = root.getElementCount(); + } + return line; + }*/ + + /** + * Calculate the number of lines, taking into account line wrapping at + * word boundaries (whitespace). + * @param fm + * @param text + * @param width + * @return + */ + private int getNumberOfLines(final int width) + { + String text = qta.getText(); + String lines[] = text.split("\n"); + int lineCount = lines.length; + for(int i=0; i<lines.length; i++) + lineCount += getWrappedLineCount(lines[i], width); + + if(lineCount < 1) + lineCount = 1; + return lineCount; + } + + /** + * For a given line count how many times it is wrapped. + * @param text + * @param width + * @return + */ + private int getWrappedLineCount(final String text, final int width) + { + String delim = " \t\n\f\r"; + StringTokenizer tok = new StringTokenizer(text, delim, true); + FontMetrics fm = qta.getFontMetrics(qta.getFont()); + + int lineOffset = 0; + int lineNumber = 0; + while(tok.hasMoreTokens()) + { + int thisWordLength = fm.stringWidth(tok.nextToken()); + lineOffset+=thisWordLength; + if(lineOffset>width) + { + lineNumber++; + lineOffset = thisWordLength; + } + } + return lineNumber; + } + + /** + * Set the size from the number of lines. + * @param doc + */ + private void setQualifierTextAreaSize(Document doc) + { + int lines = getNumberOfLines(qta.getPreferredSize().width); + int lineHeight = qta.getFontMetrics(qta.getFont()).getHeight(); + + qta.setPreferredSize(new Dimension(qta.getPreferredSize().width, + lineHeight * lines)); + } +} \ No newline at end of file