Newer
Older
/* GraphMenu.java
*
* created: Tue Sep 18 2001
*
* This file is part of Artemis
*
* Copyright (C) 2001 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/GraphMenu.java,v 1.11 2009-08-03 10:29:32 tjc Exp $
import uk.ac.sanger.artemis.EntryGroup;
import uk.ac.sanger.artemis.Options;
import uk.ac.sanger.artemis.chado.Graph;
import uk.ac.sanger.artemis.io.DatabaseDocumentEntry;
import uk.ac.sanger.artemis.io.DocumentEntry;
import uk.ac.sanger.artemis.plot.Algorithm;
import uk.ac.sanger.artemis.plot.BaseAlgorithm;
import uk.ac.sanger.artemis.plot.CodonUsageAlgorithm;
import uk.ac.sanger.artemis.plot.CodonUsageWeight;
import uk.ac.sanger.artemis.plot.UserDataAlgorithm;
import uk.ac.sanger.artemis.sequence.Strand;
import uk.ac.sanger.artemis.util.DatabaseDocument;
import uk.ac.sanger.artemis.util.Document;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Vector;
import javax.swing.*;
/**
* This menu controls one particular BasePlotGroup.
*
* @author Kim Rutherford <kmr@sanger.ac.uk>
* @version $Id: GraphMenu.java,v 1.11 2009-08-03 10:29:32 tjc Exp $
public class GraphMenu extends JMenu
{
private static final long serialVersionUID = 1L;
/**
* The JFrame reference that was passed to the constructor.
**/
private JFrame frame;
/**
* The BasePlotGroup that was passed to the constructor.
**/
private BasePlotGroup base_plot_group;
/**
* The EntryGroup object that was passed to the constructor.
**/
private EntryGroup entry_group = null;
/**
* The FeatureDisplay that was passed to the constructor.
**/
private FeatureDisplay feature_display;
private JMenu menuSubMenu = new JMenu("Other Graphs");
/**
* This list of the CheckboxMenuItems for the graphs is stored so that we
* can turn them all off with "Hide All Graphs".
**/
private Vector algorithm_menu_items = new Vector ();
/**
* Create a new GraphMenu object and all it's menu items.
* @param frame The JFrame that owns this JMenu.
* @param entry_group The EntryGroup containing the sequence to plot.
* @param base_plot_group The BasePlotGroup that this menu controls.
* @param view_menu This ViewMenu is updated when a usage plot is added.
* @param add_menu This AddMenu is updated when a usage plot is added.
* @param menu_name The name of the new menu.
**/
public GraphMenu (final JFrame frame,
final EntryGroup entry_group,
final BasePlotGroup base_plot_group,
final FeatureDisplay feature_display,
final String menu_name,
final JSplitPane splitPane)
super (menu_name);
this.frame = frame;
this.entry_group = entry_group;
this.base_plot_group = base_plot_group;
this.feature_display = feature_display;
final BaseAlgorithm [] orig_algorithms =
base_plot_group.getPlotAlgorithms ();
final JMenuItem hide_all_graphs_item = new JMenuItem ("Hide All Graphs");
hide_all_graphs_item.addActionListener (new ActionListener ()
{
public void actionPerformed (ActionEvent event)
{
final BaseAlgorithm [] current_algorithms =
base_plot_group.getPlotAlgorithms ();
for (int i = 0 ; i < current_algorithms.length ; ++i)
{
final BaseAlgorithm this_algorithm = current_algorithms[i];
base_plot_group.setVisibleByAlgorithm (this_algorithm, false);
final JCheckBoxMenuItem this_menu_item =
(JCheckBoxMenuItem) algorithm_menu_items.elementAt (i);
this_menu_item.setState (false);
}
// XXX change to revalidate().
frame.validate ();
}
}
});
add (hide_all_graphs_item);
addSeparator ();
final JMenuItem usage_plot_item = new JMenuItem ("Add Usage Plots ...");
usage_plot_item.addActionListener (new ActionListener ()
{
public void actionPerformed (ActionEvent event)
{
}
});
add (usage_plot_item);
final JMenuItem user_plot_item = new JMenuItem ("Add User Plot ...");
user_plot_item.addActionListener (new ActionListener ()
{
public void actionPerformed (ActionEvent event)
{
addUserPlot (null);
adjustSplitPane(true);
}
catch(java.lang.OutOfMemoryError emem)
{
JOptionPane.showMessageDialog(frame,
"Out of memory. Increase the maximum memory"+
"\navailable for this application and try again.",
"Out Of Memory",
JOptionPane.WARNING_MESSAGE);
frame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
if(getEntryGroup().getSequenceEntry().getEMBLEntry() instanceof
DatabaseDocumentEntry)
{
final JMenu database_user_plot = new JMenu("Add Database Plot ...");
final DatabaseDocument dbDoc =
(DatabaseDocument) ((DocumentEntry) entry_group
.getSequenceEntry().getEMBLEntry()).getDocument();
try
{
boolean hasGraphs = addDatabaseUserPlot(dbDoc, database_user_plot);
database_user_plot.setEnabled(hasGraphs);
add(database_user_plot);
}
catch(Exception e)
{
e.printStackTrace();
}
if(this_algorithm.getAlgorithmName().startsWith("Cumulative AT"))
useSubMenu = true;
addAlgorithm (this_algorithm, false, useSubMenu);
if (Options.getOptions ().getProperty ("codon_usage_file") != null)
{
final String codon_usage_file_name =
Options.getOptions ().getProperty ("codon_usage_file");
addUsagePlot (new File (codon_usage_file_name), true, false);
addUsagePlot (new File (codon_usage_file_name), false, false);
new MessageDialog (frame, "error while reading usage data: " + e);
}
}
// add user plots from the command line JVM option
if(System.getProperty("userplot") != null)
{
String plots[] = System.getProperty("userplot").split("[\\s,]");
try
{
for(int i=0;i<plots.length; i++)
{
if(plots[i].startsWith("http:") ||
plots[i].startsWith("file:") ||
plots[i].startsWith("ftp:"))
{
uk.ac.sanger.artemis.util.Document document =
new uk.ac.sanger.artemis.util.URLDocument (new URL(plots[i]));
addUserPlot (document);
}
{
File f = new File(plots[i]);
if(f.exists())
{
uk.ac.sanger.artemis.util.Document document =
new uk.ac.sanger.artemis.util.FileDocument (f);
addUserPlot (document);
}
else
System.err.println(plots[i]+" not found.");
}
}
splitPane.setDividerSize(3);
splitPane.setDividerLocation(150);
}
catch(Exception e){}
}
}
/**
* Create a new GraphMenu object and all it's menu items.
* @param frame The JFrame that owns this JMenu.
* @param entry_group The EntryGroup containing the sequence to plot.
* @param base_plot_group The BasePlotGroup that this menu controls.
* @param view_menu This ViewMenu is updated when a usage plot is added.
* @param add_menu This AddMenu is updated when a usage plot is added.
* @param menu_name The name of the new menu.
**/
public GraphMenu (final JFrame frame,
final EntryGroup entry_group,
final BasePlotGroup base_plot_group,
final FeatureDisplay feature_display,
final JSplitPane splitPane)
this (frame, entry_group, base_plot_group, feature_display, "Graph",splitPane);
}
/**
* Add a menu item for the given algorithm to the Display menu.
* @param is_visible The JCheckBoxMenuItem starts in the true state if and
* only if this is true.
* @return The new JCheckBoxMenuItem
**/
private JCheckBoxMenuItem addAlgorithm (final BaseAlgorithm algorithm,
new JCheckBoxMenuItem (algorithm.getAlgorithmName (), is_visible);
new_item.addItemListener (new ItemListener ()
{
public void itemStateChanged(ItemEvent event)
{
new_item.isSelected());
adjustSplitPane(new_item.isSelected());
if(useSubMenu)
menuSubMenu.add(new_item);
else
add (new_item);
algorithm_menu_items.addElement (new_item);
return new_item;
}
/**
* Adjust the JSplitPane divider position if all plots are
* hidden or if a single graph has been made visible.
* @param thisGraphOn
*/
private void adjustSplitPane(final boolean thisGraphOn)
{
if(splitPane == null)
return;
final BaseAlgorithm [] current_algorithms =
base_plot_group.getPlotAlgorithms ();
int nvisible = 0;
for (int i = 0 ; i < current_algorithms.length ; ++i)
{
final JCheckBoxMenuItem this_menu_item =
(JCheckBoxMenuItem) algorithm_menu_items.elementAt (i);
if(this_menu_item.isSelected())
if(this_menu_item.getText().indexOf("Codon Usage") > -1)
usageDisplayed = true;
else
usageDisplayed = false;
}
}
if(nvisible == 0)
{
splitPane.setDividerSize(0);
splitPane.setDividerLocation(0);
}
else if( ( thisGraphOn && nvisible == 1 ) ||
(usageDisplayed && nvisible == 2) )
{
splitPane.setDividerSize(3);
splitPane.setDividerLocation(0.2d);
}
}
/**
* Ask the user for a file name, then read the codon usage data from that
* file, then make and add forward and a reverse BasePlot component using
* the data.
**/
final JFrame frame = Utilities.getComponentFrame (base_plot_group);
final StickyFileChooser dialog = new StickyFileChooser ();
dialog.setDialogTitle ("Select a codon usage data file name ...");
dialog.setDialogType (JFileChooser.OPEN_DIALOG);
final int status = dialog.showOpenDialog (frame);
if (status != JFileChooser.APPROVE_OPTION ||
return;
}
final File file =
new File (dialog.getCurrentDirectory (),
dialog.getSelectedFile ().getName ());
final BasePlot new_forward_plot =
addUsagePlot (file, true, true);
final BasePlot new_reverse_plot =
addUsagePlot (file, false, true);
final Algorithm forward_algorithm = new_forward_plot.getAlgorithm ();
final Algorithm reverse_algorithm = new_reverse_plot.getAlgorithm ();
base_plot_group.setVisibleByAlgorithm (forward_algorithm, true);
base_plot_group.setVisibleByAlgorithm (reverse_algorithm, true);
new MessageDialog (Utilities.getComponentFrame (base_plot_group),
"error while reading usage data: " + e);
}
}
}
/**
* Read the codon usage data from the given File, then make and add a
* BasePlot component using the data.
* @param use_forward_strand The plot will be a forward plot if and only if
* this is true.
* @param is_visible The plot will start off visible if and only if this is
* true.
* @return The BasePlot that was added.
**/
private BasePlot addUsagePlot (final File codon_usage_file,
final boolean use_forward_strand,
final boolean is_visible)
final Strand forward_strand =
entry_group.getBases ().getForwardStrand ();
final CodonUsageWeight usage_weights =
new CodonUsageWeight (codon_usage_file, forward_strand);
codon_usage_algorithm =
new CodonUsageAlgorithm (forward_strand, usage_weights);
final Strand backward_strand =
entry_group.getBases ().getReverseStrand ();
final CodonUsageWeight usage_weights =
new CodonUsageWeight (codon_usage_file, backward_strand);
codon_usage_algorithm =
new CodonUsageAlgorithm (backward_strand, usage_weights);
}
addAlgorithm (codon_usage_algorithm, is_visible, false);
final BasePlot new_plot =
base_plot_group.addAlgorithm (codon_usage_algorithm);
base_plot_group.setVisibleByAlgorithm (codon_usage_algorithm, is_visible);
// XXX hack to force the BasePlot to initialise
final DisplayAdjustmentEvent event =
new DisplayAdjustmentEvent (this,
feature_display.getFirstVisibleForwardBase (),
feature_display.getLastVisibleForwardBase (),
feature_display.getMaxVisibleBases (),
feature_display.getScaleValue (),
feature_display.getScaleFactor (),
feature_display.isRevCompDisplay (),
DisplayAdjustmentEvent.ALL_CHANGE_ADJUST_EVENT);
base_plot_group.displayAdjustmentValueChanged (event);
return new_plot;
}
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
/**
* Add a UserDataAlgorithm from the database to the display.
* This returns true only if graph data is found.
* @param dbDoc
* @param database_user_plot
* @return
*/
private boolean addDatabaseUserPlot(final DatabaseDocument dbDoc,
final JMenu database_user_plot)
{
List graphs = dbDoc.getGraphs();
if(graphs == null || graphs.size() == 0)
return false;
for (int i = 0; i < graphs.size(); i++)
{
final Graph graph = (Graph) graphs.get(i);
JMenuItem menuGraph = new JMenuItem(graph.getName());
database_user_plot.add(menuGraph);
menuGraph.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
try
{
Document doc = dbDoc.getGraphData(graph.getGraphId(), graph.getName());
final JCheckBox logTransform = new JCheckBox("Use log(data+1)", false);
JOptionPane.showMessageDialog(frame, logTransform,
"Transform", JOptionPane.QUESTION_MESSAGE);
frame.setCursor(new Cursor(Cursor.WAIT_CURSOR));
try
{
UserDataAlgorithm new_algorithm = new UserDataAlgorithm(
getEntryGroup().getBases().getForwardStrand(), doc,
logTransform.isSelected());
final BasePlot new_base_plot = base_plot_group.addAlgorithm(new_algorithm);
base_plot_group.setVisibleByAlgorithm(new_algorithm, true);
addAlgorithm(new_algorithm, true, false);
// XXX hack to force the BasePlot to initialise
final DisplayAdjustmentEvent e = new DisplayAdjustmentEvent(
this, feature_display.getFirstVisibleForwardBase(),
feature_display.getLastVisibleForwardBase(),
feature_display.getMaxVisibleBases(),
feature_display.getScaleValue(),
feature_display.getScaleFactor(),
feature_display.isRevCompDisplay(),
DisplayAdjustmentEvent.ALL_CHANGE_ADJUST_EVENT);
base_plot_group.displayAdjustmentValueChanged(e);
}
catch (IOException e)
{
e.printStackTrace();
}
frame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
adjustSplitPane(true);
}
catch (java.lang.OutOfMemoryError emem)
{
JOptionPane.showMessageDialog(frame,
"Out of memory. Increase the maximum memory"
+ "\navailable for this application and try again.",
"Out Of Memory", JOptionPane.WARNING_MESSAGE);
frame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
}
});
}
return true;
}
private void addUserPlot (uk.ac.sanger.artemis.util.Document document)
{
final JCheckBox logTransform = new JCheckBox("Use log(data+1)", false);
final JFrame frame = Utilities.getComponentFrame(base_plot_group);
final StickyFileChooser dialog = new StickyFileChooser();
dialog.setDialogTitle("Select a data file name ...");
dialog.setDialogType(JFileChooser.OPEN_DIALOG);
dialog.setAccessory(logTransform);
final int status = dialog.showOpenDialog(frame);
if(status != JFileChooser.APPROVE_OPTION ||
dialog.getSelectedFile() == null)
{
return;
}
File file = new File(dialog.getCurrentDirectory(),
dialog.getSelectedFile().getName());
document =
new uk.ac.sanger.artemis.util.FileDocument (file);
frame.setCursor(new Cursor(Cursor.WAIT_CURSOR));
new UserDataAlgorithm (forward_strand, document, logTransform.isSelected());
final BasePlot new_base_plot =
base_plot_group.addAlgorithm (new_algorithm);
base_plot_group.setVisibleByAlgorithm (new_algorithm, true);
// XXX hack to force the BasePlot to initialise
final DisplayAdjustmentEvent event =
new DisplayAdjustmentEvent (this,
feature_display.getFirstVisibleForwardBase (),
feature_display.getLastVisibleForwardBase (),
feature_display.getMaxVisibleBases (),
feature_display.getScaleValue (),
feature_display.getScaleFactor (),
feature_display.isRevCompDisplay (),
DisplayAdjustmentEvent.ALL_CHANGE_ADJUST_EVENT);
base_plot_group.displayAdjustmentValueChanged (event);
new MessageDialog (Utilities.getComponentFrame (base_plot_group),
"error while reading user data: " + e);
}
frame.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
/**
* Return the JFrame that was passed to the constructor.
**/
return frame;
}
/**
* Return the EntryGroup that was passed to the constructor.
**/