2 * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1)
3 * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21 import jalview.bin.Cache;
25 import java.awt.datatransfer.*;
26 import java.awt.dnd.*;
27 import java.awt.event.*;
28 import java.io.BufferedInputStream;
29 import java.io.BufferedOutputStream;
31 import java.io.FileOutputStream;
32 import java.io.InputStream;
33 import java.lang.reflect.Constructor;
35 import java.net.URLConnection;
36 import java.nio.channels.ReadableByteChannel;
40 import javax.swing.event.MenuEvent;
41 import javax.swing.event.MenuListener;
49 public class Desktop extends jalview.jbgui.GDesktop implements
50 DropTargetListener, ClipboardOwner, IProgressIndicator
53 public static Desktop instance;
55 // Need to decide if the Memory Usage is to be included in
56 // Next release or not.
57 public static MyDesktopPane desktop;
59 // public static JDesktopPane desktop;
61 static int openFrameCount = 0;
63 static final int xOffset = 30;
65 static final int yOffset = 30;
67 public static jalview.ws.Discoverer discoverer;
69 public static Object[] jalviewClipboard;
71 public static boolean internalCopy = false;
73 static int fileLoadingCount = 0;
76 * Creates a new Desktop object.
81 * A note to implementors. It is ESSENTIAL that any activities that might
82 * block are spawned off as threads rather than waited for during this
86 doVamsasClientCheck();
89 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
90 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
91 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
93 boolean showjconsole = jalview.bin.Cache.getDefault(
94 "SHOW_JAVA_CONSOLE", false);
95 desktop = new MyDesktopPane(selmemusage);
96 showMemusage.setSelected(selmemusage);
97 desktop.setBackground(Color.white);
98 getContentPane().setLayout(new BorderLayout());
99 getContentPane().add(desktop, BorderLayout.CENTER);
100 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
102 // This line prevents Windows Look&Feel resizing all new windows to maximum
103 // if previous window was maximised
104 desktop.setDesktopManager(new DefaultDesktopManager());
106 Rectangle dims = getLastKnownDimensions("");
113 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
114 setBounds((int) (screenSize.width - 900) / 2,
115 (int) (screenSize.height - 650) / 2, 900, 650);
117 jconsole = new Console(this);
118 showConsole(showjconsole);
120 this.addWindowListener(new WindowAdapter()
122 public void windowClosing(WindowEvent evt)
128 this.addMouseListener(new MouseAdapter()
130 public void mousePressed(MouseEvent evt)
132 if (SwingUtilities.isRightMouseButton(evt))
134 showPasteMenu(evt.getX(), evt.getY());
139 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
140 // Spawn a thread that shows the splashscreen
141 SwingUtilities.invokeLater(new Runnable()
149 discoverer = new jalview.ws.Discoverer(); // Only gets started if gui is
154 * recover the last known dimensions for a jalview window
156 * - empty string is desktop, all other windows have unique prefix
157 * @return null or last known dimensions scaled to current geometry (if last
158 * window geom was known)
160 Rectangle getLastKnownDimensions(String windowName)
162 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
163 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
164 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
165 String width = jalview.bin.Cache.getProperty(windowName
167 String height = jalview.bin.Cache.getProperty(windowName
169 if ((x != null) && (y != null) && (width != null) && (height != null))
171 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
172 .parseInt(width), ih = Integer.parseInt(height);
173 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
175 // attempt #1 - try to cope with change in screen geometry - this
176 // version doesn't preserve original jv aspect ratio.
177 // take ratio of current screen size vs original screen size.
178 double sw = ( (1f*screenSize.width)
179 / (1f*Integer.parseInt(jalview.bin.Cache
180 .getProperty("SCREENGEOMETRY_WIDTH"))))
182 double sh = ( (1f*screenSize.height)
183 / (1f*Integer.parseInt(jalview.bin.Cache
184 .getProperty("SCREENGEOMETRY_HEIGHT"))));
185 // rescale the bounds depending upon the current screen geometry.
186 ix = (int) (ix * sw);
187 iw = (int) (iw * sw);
188 iy = (int) (iy * sh);
189 ih = (int) (ih * sh);
190 jalview.bin.Cache.log.debug("Got last known dimensions for "+windowName+": x:"+ix + " y:"+iy + " width:"+iw+" height:"+ih);
192 // return dimensions for new instance
193 return new Rectangle(ix, iy, iw, ih);
198 private void doVamsasClientCheck()
200 if (jalview.bin.Cache.vamsasJarsPresent())
202 setupVamsasDisconnectedGui();
203 VamsasMenu.setVisible(true);
204 final Desktop us = this;
205 VamsasMenu.addMenuListener(new MenuListener()
207 // this listener remembers when the menu was first selected, and
208 // doesn't rebuild the session list until it has been cleared and
210 boolean refresh = true;
212 public void menuCanceled(MenuEvent e)
217 public void menuDeselected(MenuEvent e)
222 public void menuSelected(MenuEvent e)
226 us.buildVamsasStMenu();
231 vamsasStart.setVisible(true);
235 void showPasteMenu(int x, int y)
237 JPopupMenu popup = new JPopupMenu();
238 JMenuItem item = new JMenuItem("Paste To New Window");
239 item.addActionListener(new ActionListener()
241 public void actionPerformed(ActionEvent evt)
248 popup.show(this, x, y);
255 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
256 Transferable contents = c.getContents(this);
258 if (contents != null)
260 String file = (String) contents
261 .getTransferData(DataFlavor.stringFlavor);
263 String format = new IdentifyFile().Identify(file,
264 FormatAdapter.PASTE);
266 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
269 } catch (Exception ex)
272 .println("Unable to paste alignment from system clipboard:\n"
289 public static synchronized void addInternalFrame(
290 final JInternalFrame frame, String title, int w, int h)
292 addInternalFrame(frame, title, w, h, true);
309 public static synchronized void addInternalFrame(
310 final JInternalFrame frame, String title, int w, int h,
314 // TODO: consider fixing method to update entries in the window submenu with
315 // the current window title
317 frame.setTitle(title);
318 if (frame.getWidth() < 1 || frame.getHeight() < 1)
322 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
323 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
324 // IF JALVIEW IS RUNNING HEADLESS
325 // ///////////////////////////////////////////////
326 if (System.getProperty("java.awt.headless") != null
327 && System.getProperty("java.awt.headless").equals("true"))
334 frame.setVisible(true);
335 frame.setClosable(true);
336 frame.setResizable(resizable);
337 frame.setMaximizable(resizable);
338 frame.setIconifiable(resizable);
339 frame.setFrameIcon(null);
341 if (frame.getX() < 1 && frame.getY() < 1)
343 frame.setLocation(xOffset * openFrameCount, yOffset
344 * ((openFrameCount - 1) % 10) + yOffset);
347 final JMenuItem menuItem = new JMenuItem(title);
349 .addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
351 public void internalFrameActivated(
352 javax.swing.event.InternalFrameEvent evt)
354 JInternalFrame itf = desktop.getSelectedFrame();
362 public void internalFrameClosed(
363 javax.swing.event.InternalFrameEvent evt)
365 PaintRefresher.RemoveComponent(frame);
367 windowMenu.remove(menuItem);
368 JInternalFrame itf = desktop.getSelectedFrame();
377 menuItem.addActionListener(new ActionListener()
379 public void actionPerformed(ActionEvent e)
383 frame.setSelected(true);
384 frame.setIcon(false);
385 } catch (java.beans.PropertyVetoException ex)
392 windowMenu.add(menuItem);
398 frame.setSelected(true);
399 frame.requestFocus();
400 } catch (java.beans.PropertyVetoException ve)
405 public void lostOwnership(Clipboard clipboard, Transferable contents)
409 Desktop.jalviewClipboard = null;
412 internalCopy = false;
415 public void dragEnter(DropTargetDragEvent evt)
419 public void dragExit(DropTargetEvent evt)
423 public void dragOver(DropTargetDragEvent evt)
427 public void dropActionChanged(DropTargetDragEvent evt)
437 public void drop(DropTargetDropEvent evt)
439 Transferable t = evt.getTransferable();
440 java.util.List files = null;
441 java.util.List protocols = null;
445 DataFlavor uriListFlavor = new DataFlavor(
446 "text/uri-list;class=java.lang.String");
447 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
449 // Works on Windows and MacOSX
450 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
451 files = (java.util.List) t
452 .getTransferData(DataFlavor.javaFileListFlavor);
454 else if (t.isDataFlavorSupported(uriListFlavor))
456 // This is used by Unix drag system
457 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
458 String data = (String) t.getTransferData(uriListFlavor);
459 files = new java.util.ArrayList(1);
460 protocols = new java.util.ArrayList(1);
461 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
462 data, "\r\n"); st.hasMoreTokens();)
464 String s = st.nextToken();
465 if (s.startsWith("#"))
467 // the line is a comment (as per the RFC 2483)
470 java.net.URI uri = new java.net.URI(s);
471 if (uri.getScheme().toLowerCase().startsWith("http"))
473 protocols.add(FormatAdapter.URL);
474 files.add(uri.toString());
478 // otherwise preserve old behaviour: catch all for file objects
479 java.io.File file = new java.io.File(uri);
480 protocols.add(FormatAdapter.FILE);
481 files.add(file.toString());
485 } catch (Exception e)
493 for (int i = 0; i < files.size(); i++)
495 String file = files.get(i).toString();
496 String protocol = (protocols == null) ? FormatAdapter.FILE
497 : (String) protocols.get(i);
498 String format = null;
500 if (file.endsWith(".jar"))
507 format = new IdentifyFile().Identify(file, protocol);
510 new FileLoader().LoadFile(file, protocol, format);
513 } catch (Exception ex)
525 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
527 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
528 .getProperty("LAST_DIRECTORY"),
529 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
530 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
531 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
533 chooser.setFileView(new JalviewFileView());
534 chooser.setDialogTitle("Open local file");
535 chooser.setToolTipText("Open");
537 int value = chooser.showOpenDialog(this);
539 if (value == JalviewFileChooser.APPROVE_OPTION)
541 String choice = chooser.getSelectedFile().getPath();
542 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
543 .getSelectedFile().getParent());
545 String format = null;
546 if (chooser.getSelectedFormat().equals("Jalview"))
552 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
555 if (viewport != null)
557 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
562 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
573 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
575 // This construct allows us to have a wider textfield
577 JLabel label = new JLabel("Enter URL of Input File");
578 final JComboBox history = new JComboBox();
580 JPanel panel = new JPanel(new GridLayout(2, 1));
583 history.setPreferredSize(new Dimension(400, 20));
584 history.setEditable(true);
585 history.addItem("http://www.");
587 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
591 if (historyItems != null)
593 st = new StringTokenizer(historyItems, "\t");
595 while (st.hasMoreTokens())
597 history.addItem(st.nextElement());
601 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
602 "Input Alignment From URL", JOptionPane.OK_CANCEL_OPTION);
604 if (reply != JOptionPane.OK_OPTION)
609 String url = history.getSelectedItem().toString();
611 if (url.toLowerCase().endsWith(".jar"))
613 if (viewport != null)
615 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
620 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
625 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
627 if (format.equals("URL NOT FOUND"))
629 JOptionPane.showInternalMessageDialog(Desktop.desktop,
630 "Couldn't locate " + url, "URL not found",
631 JOptionPane.WARNING_MESSAGE);
636 if (viewport != null)
638 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
642 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
653 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
655 CutAndPasteTransfer cap = new CutAndPasteTransfer();
656 cap.setForInput(viewport);
657 Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
665 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
667 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
668 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
670 storeLastKnownDimensions("",new Rectangle(getBounds().x,getBounds().y, getWidth(), getHeight()));
672 if (jconsole != null)
674 storeLastKnownDimensions("JAVA_CONSOLE_",jconsole.getBounds());
675 jconsole.stopConsole();
680 private void storeLastKnownDimensions(String string, Rectangle jc)
682 jalview.bin.Cache.log.debug("Storing last known dimensions for "+string+": x:"+jc.x + " y:"+jc.y + " width:"+jc.width+" height:"+jc.height);
684 jalview.bin.Cache.setProperty(string+"SCREEN_X",jc.x + "");
685 jalview.bin.Cache.setProperty(string+"SCREEN_Y", jc.y + "");
686 jalview.bin.Cache.setProperty(string+"SCREEN_WIDTH", jc.width + "");
687 jalview.bin.Cache.setProperty(string+"SCREEN_HEIGHT", jc.height
697 public void aboutMenuItem_actionPerformed(ActionEvent e)
699 StringBuffer message = new StringBuffer("Jalview version "
700 + jalview.bin.Cache.getProperty("VERSION") + "; last updated: "
701 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
703 if (!jalview.bin.Cache.getProperty("LATEST_VERSION").equals(
704 jalview.bin.Cache.getProperty("VERSION")))
707 .append("\n\n!! Jalview version "
708 + jalview.bin.Cache.getProperty("LATEST_VERSION")
709 + " is available for download from http://www.jalview.org !!\n");
712 // TODO: update this text for each release or centrally store it for lite
715 .append("\nAuthors: Andrew Waterhouse, Jim Procter, Michele Clamp, James Cuff, Steve Searle,\n David Martin & Geoff Barton."
716 + "\nDevelopment managed by The Barton Group, University of Dundee, Scotland, UK.\n"
717 + "\nFor help, see the FAQ at www.jalview.org and/or join the jalview-discuss@jalview.org mailing list\n"
718 + "\nIf you use Jalview, please cite:"
719 + "\nWaterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
720 + "\nJalview Version 2 - a multiple sequence alignment editor and analysis workbench"
721 + "\nBioinformatics doi: 10.1093/bioinformatics/btp033");
722 JOptionPane.showInternalMessageDialog(Desktop.desktop,
724 message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
733 public void documentationMenuItem_actionPerformed(ActionEvent e)
737 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
738 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
739 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
741 javax.help.HelpBroker hb = hs.createHelpBroker();
742 hb.setCurrentID("home");
743 hb.setDisplayed(true);
744 } catch (Exception ex)
749 public void closeAll_actionPerformed(ActionEvent e)
751 JInternalFrame[] frames = desktop.getAllFrames();
752 for (int i = 0; i < frames.length; i++)
756 frames[i].setClosed(true);
757 } catch (java.beans.PropertyVetoException ex)
761 System.out.println("ALL CLOSED");
762 if (v_client != null)
764 // TODO clear binding to vamsas document objects on close_all
769 public void raiseRelated_actionPerformed(ActionEvent e)
771 reorderAssociatedWindows(false, false);
774 public void minimizeAssociated_actionPerformed(ActionEvent e)
776 reorderAssociatedWindows(true, false);
779 void closeAssociatedWindows()
781 reorderAssociatedWindows(false, true);
787 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
790 protected void garbageCollect_actionPerformed(ActionEvent e)
792 // We simply collect the garbage
793 jalview.bin.Cache.log.debug("Collecting garbage...");
795 jalview.bin.Cache.log.debug("Finished garbage collection.");
802 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
805 protected void showMemusage_actionPerformed(ActionEvent e)
807 desktop.showMemoryUsage(showMemusage.isSelected());
814 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
817 protected void showConsole_actionPerformed(ActionEvent e)
819 showConsole(showConsole.isSelected());
822 Console jconsole = null;
825 * control whether the java console is visible or not
829 void showConsole(boolean selected)
831 showConsole.setSelected(selected);
832 // TODO: decide if we should update properties file
833 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
835 jconsole.setVisible(selected);
838 void reorderAssociatedWindows(boolean minimize, boolean close)
840 JInternalFrame[] frames = desktop.getAllFrames();
841 if (frames == null || frames.length < 1)
846 AlignViewport source = null, target = null;
847 if (frames[0] instanceof AlignFrame)
849 source = ((AlignFrame) frames[0]).getCurrentView();
851 else if (frames[0] instanceof TreePanel)
853 source = ((TreePanel) frames[0]).getViewPort();
855 else if (frames[0] instanceof PCAPanel)
857 source = ((PCAPanel) frames[0]).av;
859 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
861 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
866 for (int i = 0; i < frames.length; i++)
869 if (frames[i] == null)
873 if (frames[i] instanceof AlignFrame)
875 target = ((AlignFrame) frames[i]).getCurrentView();
877 else if (frames[i] instanceof TreePanel)
879 target = ((TreePanel) frames[i]).getViewPort();
881 else if (frames[i] instanceof PCAPanel)
883 target = ((PCAPanel) frames[i]).av;
885 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
887 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
890 if (source == target)
896 frames[i].setClosed(true);
900 frames[i].setIcon(minimize);
907 } catch (java.beans.PropertyVetoException ex)
921 protected void preferences_actionPerformed(ActionEvent e)
932 public void saveState_actionPerformed(ActionEvent e)
934 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
935 .getProperty("LAST_DIRECTORY"), new String[]
936 { "jar" }, new String[]
937 { "Jalview Project" }, "Jalview Project");
939 chooser.setFileView(new JalviewFileView());
940 chooser.setDialogTitle("Save State");
942 int value = chooser.showSaveDialog(this);
944 if (value == JalviewFileChooser.APPROVE_OPTION)
946 java.io.File choice = chooser.getSelectedFile();
947 JProgressBar progpanel = addProgressPanel("Saving jalview project "
949 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
950 // TODO catch and handle errors for savestate
951 new Jalview2XML().SaveState(choice);
952 removeProgressPanel(progpanel);
963 public void loadState_actionPerformed(ActionEvent e)
965 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
966 .getProperty("LAST_DIRECTORY"), new String[]
967 { "jar" }, new String[]
968 { "Jalview Project" }, "Jalview Project");
969 chooser.setFileView(new JalviewFileView());
970 chooser.setDialogTitle("Restore state");
972 int value = chooser.showOpenDialog(this);
974 if (value == JalviewFileChooser.APPROVE_OPTION)
976 String choice = chooser.getSelectedFile().getAbsolutePath();
977 setProgressBar("loading jalview project "
978 + chooser.getSelectedFile().getName(), choice.hashCode());
979 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
980 .getSelectedFile().getParent());
981 new Jalview2XML().LoadJalviewAlign(choice);
982 setProgressBar(null, choice.hashCode());
986 public void inputSequence_actionPerformed(ActionEvent e)
988 new SequenceFetcher(this);
991 JPanel progressPanel;
993 public void startLoading(final String fileName)
995 if (fileLoadingCount == 0)
997 addProgressPanel("Loading File: " + fileName + " ");
1003 private JProgressBar addProgressPanel(String string)
1005 if (progressPanel == null)
1007 progressPanel = new JPanel(new BorderLayout());
1008 totalProgressCount = 0;
1010 JProgressBar progressBar = new JProgressBar();
1011 progressBar.setIndeterminate(true);
1013 progressPanel.add(new JLabel(string), BorderLayout.WEST);
1015 progressPanel.add(progressBar, BorderLayout.CENTER);
1017 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1018 totalProgressCount++;
1023 int totalProgressCount = 0;
1025 private void removeProgressPanel(JProgressBar progbar)
1027 if (progressPanel != null)
1029 progressPanel.remove(progbar);
1030 if (--totalProgressCount < 1)
1032 this.getContentPane().remove(progressPanel);
1033 progressPanel = null;
1039 public void stopLoading()
1042 if (fileLoadingCount < 1)
1044 if (progressPanel != null)
1046 this.getContentPane().remove(progressPanel);
1047 progressPanel = null;
1049 fileLoadingCount = 0;
1054 public static int getViewCount(String viewId)
1056 AlignViewport[] aps = getViewports(viewId);
1057 return (aps == null) ? 0 : aps.length;
1063 * @return all AlignmentPanels concerning the viewId sequence set
1065 public static AlignmentPanel[] getAlignmentPanels(String viewId)
1068 if (Desktop.desktop == null)
1070 // no frames created and in headless mode
1071 // TODO: verify that frames are recoverable when in headless mode
1074 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1075 ArrayList aps = new ArrayList();
1076 for (int t = 0; t < frames.length; t++)
1078 if (frames[t] instanceof AlignFrame)
1080 AlignFrame af = (AlignFrame) frames[t];
1081 for (int a = 0; a < af.alignPanels.size(); a++)
1084 .equals(((AlignmentPanel) af.alignPanels.elementAt(a)).av
1085 .getSequenceSetId()))
1087 aps.add(af.alignPanels.elementAt(a));
1092 if (aps.size() == 0)
1096 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1097 for (int t = 0; t < vap.length; t++)
1099 vap[t] = (AlignmentPanel) aps.get(t);
1105 * get all the viewports on an alignment.
1107 * @param sequenceSetId
1108 * unique alignment id
1109 * @return all viewports on the alignment bound to sequenceSetId
1111 public static AlignViewport[] getViewports(String sequenceSetId)
1113 Vector viewp = new Vector();
1114 if (desktop != null)
1116 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1118 for (int t = 0; t < frames.length; t++)
1120 if (frames[t] instanceof AlignFrame)
1122 AlignFrame afr = ((AlignFrame) frames[t]);
1123 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1125 if (afr.alignPanels != null)
1127 for (int a = 0; a < afr.alignPanels.size(); a++)
1129 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1130 .elementAt(a)).av.getSequenceSetId()))
1132 viewp.addElement(((AlignmentPanel) afr.alignPanels
1139 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1144 if (viewp.size() > 0)
1146 AlignViewport[] vp = new AlignViewport[viewp.size()];
1154 public void explodeViews(AlignFrame af)
1156 int size = af.alignPanels.size();
1162 for (int i = 0; i < size; i++)
1164 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1165 AlignFrame newaf = new AlignFrame(ap);
1166 if (ap.av.explodedPosition != null
1167 && !ap.av.explodedPosition.equals(af.getBounds()))
1169 newaf.setBounds(ap.av.explodedPosition);
1172 ap.av.gatherViewsHere = false;
1174 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1175 AlignFrame.DEFAULT_HEIGHT);
1178 af.alignPanels.clear();
1179 af.closeMenuItem_actionPerformed(true);
1183 public void gatherViews(AlignFrame source)
1185 source.viewport.gatherViewsHere = true;
1186 source.viewport.explodedPosition = source.getBounds();
1187 JInternalFrame[] frames = desktop.getAllFrames();
1188 String viewId = source.viewport.sequenceSetID;
1190 for (int t = 0; t < frames.length; t++)
1192 if (frames[t] instanceof AlignFrame && frames[t] != source)
1194 AlignFrame af = (AlignFrame) frames[t];
1195 boolean gatherThis = false;
1196 for (int a = 0; a < af.alignPanels.size(); a++)
1198 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1199 if (viewId.equals(ap.av.getSequenceSetId()))
1202 ap.av.gatherViewsHere = false;
1203 ap.av.explodedPosition = af.getBounds();
1204 source.addAlignmentPanel(ap, false);
1210 af.alignPanels.clear();
1211 af.closeMenuItem_actionPerformed(true);
1218 jalview.gui.VamsasApplication v_client = null;
1220 public void vamsasImport_actionPerformed(ActionEvent e)
1222 if (v_client == null)
1224 // Load and try to start a session.
1225 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
1226 .getProperty("LAST_DIRECTORY"));
1228 chooser.setFileView(new JalviewFileView());
1229 chooser.setDialogTitle("Open a saved VAMSAS session");
1231 .setToolTipText("select a vamsas session to be opened as a new vamsas session.");
1233 int value = chooser.showOpenDialog(this);
1235 if (value == JalviewFileChooser.APPROVE_OPTION)
1237 String fle = chooser.getSelectedFile().toString();
1238 if (!vamsasImport(chooser.getSelectedFile()))
1240 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1241 "Couldn't import '" + fle + "' as a new vamsas session.",
1242 "Vamsas Document Import Failed",
1243 JOptionPane.ERROR_MESSAGE);
1249 jalview.bin.Cache.log
1250 .error("Implementation error - load session from a running session is not supported.");
1255 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1258 * @return true if import was a success and a session was started.
1260 public boolean vamsasImport(URL url)
1262 // TODO: create progress bar
1263 if (v_client != null)
1266 jalview.bin.Cache.log
1267 .error("Implementation error - load session from a running session is not supported.");
1273 // copy the URL content to a temporary local file
1274 // TODO: be a bit cleverer here with nio (?!)
1275 File file = File.createTempFile("vdocfromurl", ".vdj");
1276 FileOutputStream fos = new FileOutputStream(file);
1277 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1278 byte[] buffer = new byte[2048];
1280 while ((ln = bis.read(buffer)) > -1)
1282 fos.write(buffer, 0, ln);
1286 v_client = new jalview.gui.VamsasApplication(this, file, url
1288 } catch (Exception ex)
1290 jalview.bin.Cache.log.error(
1291 "Failed to create new vamsas session from contents of URL "
1295 setupVamsasConnectedGui();
1296 v_client.initial_update(); // TODO: thread ?
1297 return v_client.inSession();
1301 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1304 * @return true if import was a success and a session was started.
1306 public boolean vamsasImport(File file)
1308 if (v_client != null)
1311 jalview.bin.Cache.log
1312 .error("Implementation error - load session from a running session is not supported.");
1316 setProgressBar("Importing VAMSAS session from " + file.getName(), file
1320 v_client = new jalview.gui.VamsasApplication(this, file, null);
1321 } catch (Exception ex)
1323 setProgressBar("Importing VAMSAS session from " + file.getName(),
1325 jalview.bin.Cache.log.error(
1326 "New vamsas session from existing session file failed:", ex);
1329 setupVamsasConnectedGui();
1330 v_client.initial_update(); // TODO: thread ?
1331 setProgressBar("Importing VAMSAS session from " + file.getName(), file
1333 return v_client.inSession();
1336 public boolean joinVamsasSession(String mysesid)
1338 if (v_client != null)
1341 "Trying to join a vamsas session when another is already connected.");
1343 if (mysesid == null)
1345 throw new Error("Invalid vamsas session id.");
1347 v_client = new VamsasApplication(this, mysesid);
1348 setupVamsasConnectedGui();
1349 v_client.initial_update();
1350 return (v_client.inSession());
1353 public void vamsasStart_actionPerformed(ActionEvent e)
1355 if (v_client == null)
1358 // we just start a default session for moment.
1360 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1361 * getProperty("LAST_DIRECTORY"));
1363 * chooser.setFileView(new JalviewFileView());
1364 * chooser.setDialogTitle("Load Vamsas file");
1365 * chooser.setToolTipText("Import");
1367 * int value = chooser.showOpenDialog(this);
1369 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1370 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1372 v_client = new VamsasApplication(this);
1373 setupVamsasConnectedGui();
1374 v_client.initial_update(); // TODO: thread ?
1378 // store current data in session.
1379 v_client.push_update(); // TODO: thread
1383 protected void setupVamsasConnectedGui()
1385 vamsasStart.setText("Session Update");
1386 vamsasSave.setVisible(true);
1387 vamsasStop.setVisible(true);
1388 vamsasImport.setVisible(false); // Document import to existing session is
1389 // not possible for vamsas-client-1.0.
1392 protected void setupVamsasDisconnectedGui()
1394 vamsasSave.setVisible(false);
1395 vamsasStop.setVisible(false);
1396 vamsasImport.setVisible(true);
1397 vamsasStart.setText("New Vamsas Session");
1400 public void vamsasStop_actionPerformed(ActionEvent e)
1402 if (v_client != null)
1404 v_client.end_session();
1406 setupVamsasDisconnectedGui();
1410 protected void buildVamsasStMenu()
1412 if (v_client == null)
1414 String[] sess = null;
1417 sess = VamsasApplication.getSessionList();
1418 } catch (Exception e)
1420 jalview.bin.Cache.log.warn(
1421 "Problem getting current sessions list.", e);
1426 jalview.bin.Cache.log.debug("Got current sessions list: "
1427 + sess.length + " entries.");
1428 VamsasStMenu.removeAll();
1429 for (int i = 0; i < sess.length; i++)
1431 JMenuItem sessit = new JMenuItem();
1432 sessit.setText(sess[i]);
1433 sessit.setToolTipText("Connect to session " + sess[i]);
1434 final Desktop dsktp = this;
1435 final String mysesid = sess[i];
1436 sessit.addActionListener(new ActionListener()
1439 public void actionPerformed(ActionEvent e)
1441 if (dsktp.v_client == null)
1443 Thread rthr = new Thread(new Runnable()
1448 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1449 dsktp.setupVamsasConnectedGui();
1450 dsktp.v_client.initial_update();
1458 VamsasStMenu.add(sessit);
1460 // don't show an empty menu.
1461 VamsasStMenu.setVisible(sess.length > 0);
1466 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1467 VamsasStMenu.removeAll();
1468 VamsasStMenu.setVisible(false);
1473 // Not interested in the content. Just hide ourselves.
1474 VamsasStMenu.setVisible(false);
1478 public void vamsasSave_actionPerformed(ActionEvent e)
1480 if (v_client != null)
1482 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
1483 .getProperty("LAST_DIRECTORY"), new String[]
1484 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1486 { "Vamsas Document" }, "Vamsas Document");
1488 chooser.setFileView(new JalviewFileView());
1489 chooser.setDialogTitle("Save Vamsas Document Archive");
1491 int value = chooser.showSaveDialog(this);
1493 if (value == JalviewFileChooser.APPROVE_OPTION)
1495 java.io.File choice = chooser.getSelectedFile();
1496 JProgressBar progpanel = addProgressPanel("Saving VAMSAS Document to "
1497 + choice.getName());
1498 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1499 String warnmsg = null;
1500 String warnttl = null;
1503 v_client.vclient.storeDocument(choice);
1506 warnttl = "Serious Problem saving Vamsas Document";
1507 warnmsg = ex.toString();
1508 jalview.bin.Cache.log.error("Error Whilst saving document to "
1511 } catch (Exception ex)
1513 warnttl = "Problem saving Vamsas Document.";
1514 warnmsg = ex.toString();
1515 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
1519 removeProgressPanel(progpanel);
1520 if (warnmsg != null)
1522 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1524 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
1530 JProgressBar vamUpdate = null;
1533 * hide vamsas user gui bits when a vamsas document event is being handled.
1536 * true to hide gui, false to reveal gui
1538 public void setVamsasUpdate(boolean b)
1540 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
1541 + (b ? "in progress" : "finished"));
1543 if (vamUpdate != null)
1545 this.removeProgressPanel(vamUpdate);
1549 vamUpdate = this.addProgressPanel("Updating vamsas session");
1551 vamsasStart.setVisible(!b);
1552 vamsasStop.setVisible(!b);
1553 vamsasSave.setVisible(!b);
1556 public JInternalFrame[] getAllFrames()
1558 return desktop.getAllFrames();
1562 * Checks the given url to see if it gives a response indicating that the user
1563 * should be informed of a new questionnaire.
1567 public void checkForQuestionnaire(String url)
1569 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
1570 // javax.swing.SwingUtilities.invokeLater(jvq);
1571 new Thread(jvq).start();
1575 * Proxy class for JDesktopPane which optionally displays the current memory
1576 * usage and highlights the desktop area with a red bar if free memory runs
1581 public class MyDesktopPane extends JDesktopPane implements Runnable
1584 boolean showMemoryUsage = false;
1588 java.text.NumberFormat df;
1590 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
1593 public MyDesktopPane(boolean showMemoryUsage)
1595 showMemoryUsage(showMemoryUsage);
1598 public void showMemoryUsage(boolean showMemoryUsage)
1600 this.showMemoryUsage = showMemoryUsage;
1601 if (showMemoryUsage)
1603 Thread worker = new Thread(this);
1608 public boolean isShowMemoryUsage()
1610 return showMemoryUsage;
1615 df = java.text.NumberFormat.getNumberInstance();
1616 df.setMaximumFractionDigits(2);
1617 runtime = Runtime.getRuntime();
1619 while (showMemoryUsage)
1623 maxMemory = runtime.maxMemory() / 1048576f;
1624 allocatedMemory = runtime.totalMemory() / 1048576f;
1625 freeMemory = runtime.freeMemory() / 1048576f;
1626 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
1628 percentUsage = (totalFreeMemory / maxMemory) * 100;
1630 // if (percentUsage < 20)
1632 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
1634 // instance.set.setBorder(border1);
1637 // sleep after showing usage
1639 } catch (Exception ex)
1641 ex.printStackTrace();
1646 public void paintComponent(Graphics g)
1648 if (showMemoryUsage && g != null)
1650 if (percentUsage < 20)
1651 g.setColor(Color.red);
1653 g.drawString("Total Free Memory: " + df.format(totalFreeMemory)
1654 + "MB; Max Memory: " + df.format(maxMemory) + "MB; "
1655 + df.format(percentUsage) + "%", 10, getHeight()
1656 - g.getFontMetrics().getHeight());
1662 protected JMenuItem groovyShell;
1664 public void doGroovyCheck()
1666 if (jalview.bin.Cache.groovyJarsPresent())
1668 groovyShell = new JMenuItem();
1669 groovyShell.setText("Groovy Console...");
1670 groovyShell.addActionListener(new ActionListener()
1672 public void actionPerformed(ActionEvent e)
1674 groovyShell_actionPerformed(e);
1677 toolsMenu.add(groovyShell);
1678 groovyShell.setVisible(true);
1683 * Accessor method to quickly get all the AlignmentFrames loaded.
1685 public static AlignFrame[] getAlignframes()
1687 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1693 Vector avp = new Vector();
1697 for (int i = frames.length - 1; i > -1; i--)
1699 if (frames[i] instanceof AlignFrame)
1701 AlignFrame af = (AlignFrame) frames[i];
1705 } catch (Exception ex)
1707 ex.printStackTrace();
1709 if (avp.size() == 0)
1713 AlignFrame afs[] = new AlignFrame[avp.size()];
1714 for (int i = 0, j = avp.size(); i < j; i++)
1716 afs[i] = (AlignFrame) avp.elementAt(i);
1723 * Add Groovy Support to Jalview
1725 public void groovyShell_actionPerformed(ActionEvent e)
1727 // use reflection to avoid creating compilation dependency.
1728 if (!jalview.bin.Cache.groovyJarsPresent())
1731 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
1735 Class gcClass = Desktop.class.getClassLoader().loadClass(
1736 "groovy.ui.Console");
1737 Constructor gccons = gcClass.getConstructor(null);
1738 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
1740 { String.class, Object.class });
1741 java.lang.reflect.Method run = gcClass.getMethod("run", null);
1742 Object gc = gccons.newInstance(null);
1743 setvar.invoke(gc, new Object[]
1744 { "Jalview", this });
1745 run.invoke(gc, null);
1746 } catch (Exception ex)
1748 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
1750 .showInternalMessageDialog(
1753 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
1754 "Jalview Groovy Support Failed",
1755 JOptionPane.ERROR_MESSAGE);
1760 * Progress bars managed by the IProgressIndicator method.
1762 private Hashtable progressBars, progressBarHandlers;
1767 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
1769 public void setProgressBar(String message, long id)
1771 if (progressBars == null)
1773 progressBars = new Hashtable();
1774 progressBarHandlers = new Hashtable();
1777 if (progressBars.get(new Long(id)) != null)
1779 JProgressBar progressPanel = (JProgressBar) progressBars
1780 .remove(new Long(id));
1781 if (progressBarHandlers.contains(new Long(id)))
1783 progressBarHandlers.remove(new Long(id));
1785 removeProgressPanel(progressPanel);
1789 progressBars.put(new Long(id), addProgressPanel(message));
1796 * @see jalview.gui.IProgressIndicator#registerHandler(long,
1797 * jalview.gui.IProgressIndicatorHandler)
1799 public void registerHandler(final long id,
1800 final IProgressIndicatorHandler handler)
1802 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
1805 "call setProgressBar before registering the progress bar's handler.");
1807 progressBarHandlers.put(new Long(id), handler);
1808 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
1809 if (handler.canCancel())
1811 JButton cancel = new JButton("Cancel");
1812 final IProgressIndicator us = this;
1813 cancel.addActionListener(new ActionListener()
1816 public void actionPerformed(ActionEvent e)
1818 handler.cancelActivity(id);
1819 us.setProgressBar("Cancelled "
1820 + ((JLabel) progressPanel.getComponent(0)).getText(), id);
1823 progressPanel.add(cancel, BorderLayout.EAST);
1828 * This will return the first AlignFrame viewing AlignViewport av. It will
1829 * break if there are more than one AlignFrames viewing a particular av. This
1832 * @return alignFrame for av
1834 public static AlignFrame getAlignFrameFor(AlignViewport av)
1836 if (desktop != null)
1838 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
1839 for (int panel = 0; aps != null && panel < aps.length; panel++)
1841 if (aps[panel] != null && aps[panel].av == av)
1843 return aps[panel].alignFrame;
1850 public VamsasApplication getVamsasApplication()