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 // TODO: lock aspect ratio for scaling desktop Bug #0058199
163 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
164 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
165 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
166 String width = jalview.bin.Cache.getProperty(windowName
168 String height = jalview.bin.Cache.getProperty(windowName
170 if ((x != null) && (y != null) && (width != null) && (height != null))
172 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
173 .parseInt(width), ih = Integer.parseInt(height);
174 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
176 // attempt #1 - try to cope with change in screen geometry - this
177 // version doesn't preserve original jv aspect ratio.
178 // take ratio of current screen size vs original screen size.
179 double sw = ( (1f*screenSize.width)
180 / (1f*Integer.parseInt(jalview.bin.Cache
181 .getProperty("SCREENGEOMETRY_WIDTH"))))
183 double sh = ( (1f*screenSize.height)
184 / (1f*Integer.parseInt(jalview.bin.Cache
185 .getProperty("SCREENGEOMETRY_HEIGHT"))));
186 // rescale the bounds depending upon the current screen geometry.
187 ix = (int) (ix * sw);
188 iw = (int) (iw * sw);
189 iy = (int) (iy * sh);
190 ih = (int) (ih * sh);
191 jalview.bin.Cache.log.debug("Got last known dimensions for "+windowName+": x:"+ix + " y:"+iy + " width:"+iw+" height:"+ih);
193 // return dimensions for new instance
194 return new Rectangle(ix, iy, iw, ih);
199 private void doVamsasClientCheck()
201 if (jalview.bin.Cache.vamsasJarsPresent())
203 setupVamsasDisconnectedGui();
204 VamsasMenu.setVisible(true);
205 final Desktop us = this;
206 VamsasMenu.addMenuListener(new MenuListener()
208 // this listener remembers when the menu was first selected, and
209 // doesn't rebuild the session list until it has been cleared and
211 boolean refresh = true;
213 public void menuCanceled(MenuEvent e)
218 public void menuDeselected(MenuEvent e)
223 public void menuSelected(MenuEvent e)
227 us.buildVamsasStMenu();
232 vamsasStart.setVisible(true);
236 void showPasteMenu(int x, int y)
238 JPopupMenu popup = new JPopupMenu();
239 JMenuItem item = new JMenuItem("Paste To New Window");
240 item.addActionListener(new ActionListener()
242 public void actionPerformed(ActionEvent evt)
249 popup.show(this, x, y);
256 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
257 Transferable contents = c.getContents(this);
259 if (contents != null)
261 String file = (String) contents
262 .getTransferData(DataFlavor.stringFlavor);
264 String format = new IdentifyFile().Identify(file,
265 FormatAdapter.PASTE);
267 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
270 } catch (Exception ex)
273 .println("Unable to paste alignment from system clipboard:\n"
290 public static synchronized void addInternalFrame(
291 final JInternalFrame frame, String title, int w, int h)
293 addInternalFrame(frame, title, w, h, true);
310 public static synchronized void addInternalFrame(
311 final JInternalFrame frame, String title, int w, int h,
315 // TODO: consider fixing method to update entries in the window submenu with
316 // the current window title
318 frame.setTitle(title);
319 if (frame.getWidth() < 1 || frame.getHeight() < 1)
323 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
324 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
325 // IF JALVIEW IS RUNNING HEADLESS
326 // ///////////////////////////////////////////////
327 if (System.getProperty("java.awt.headless") != null
328 && System.getProperty("java.awt.headless").equals("true"))
335 frame.setVisible(true);
336 frame.setClosable(true);
337 frame.setResizable(resizable);
338 frame.setMaximizable(resizable);
339 frame.setIconifiable(resizable);
340 frame.setFrameIcon(null);
342 if (frame.getX() < 1 && frame.getY() < 1)
344 frame.setLocation(xOffset * openFrameCount, yOffset
345 * ((openFrameCount - 1) % 10) + yOffset);
348 final JMenuItem menuItem = new JMenuItem(title);
350 .addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
352 public void internalFrameActivated(
353 javax.swing.event.InternalFrameEvent evt)
355 JInternalFrame itf = desktop.getSelectedFrame();
363 public void internalFrameClosed(
364 javax.swing.event.InternalFrameEvent evt)
366 PaintRefresher.RemoveComponent(frame);
368 windowMenu.remove(menuItem);
369 JInternalFrame itf = desktop.getSelectedFrame();
378 menuItem.addActionListener(new ActionListener()
380 public void actionPerformed(ActionEvent e)
384 frame.setSelected(true);
385 frame.setIcon(false);
386 } catch (java.beans.PropertyVetoException ex)
393 windowMenu.add(menuItem);
399 frame.setSelected(true);
400 frame.requestFocus();
401 } catch (java.beans.PropertyVetoException ve)
406 public void lostOwnership(Clipboard clipboard, Transferable contents)
410 Desktop.jalviewClipboard = null;
413 internalCopy = false;
416 public void dragEnter(DropTargetDragEvent evt)
420 public void dragExit(DropTargetEvent evt)
424 public void dragOver(DropTargetDragEvent evt)
428 public void dropActionChanged(DropTargetDragEvent evt)
438 public void drop(DropTargetDropEvent evt)
440 Transferable t = evt.getTransferable();
441 java.util.List files = null;
442 java.util.List protocols = null;
446 DataFlavor uriListFlavor = new DataFlavor(
447 "text/uri-list;class=java.lang.String");
448 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
450 // Works on Windows and MacOSX
451 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
452 files = (java.util.List) t
453 .getTransferData(DataFlavor.javaFileListFlavor);
455 else if (t.isDataFlavorSupported(uriListFlavor))
457 // This is used by Unix drag system
458 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
459 String data = (String) t.getTransferData(uriListFlavor);
460 files = new java.util.ArrayList(1);
461 protocols = new java.util.ArrayList(1);
462 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
463 data, "\r\n"); st.hasMoreTokens();)
465 String s = st.nextToken();
466 if (s.startsWith("#"))
468 // the line is a comment (as per the RFC 2483)
471 java.net.URI uri = new java.net.URI(s);
472 if (uri.getScheme().toLowerCase().startsWith("http"))
474 protocols.add(FormatAdapter.URL);
475 files.add(uri.toString());
479 // otherwise preserve old behaviour: catch all for file objects
480 java.io.File file = new java.io.File(uri);
481 protocols.add(FormatAdapter.FILE);
482 files.add(file.toString());
486 } catch (Exception e)
494 for (int i = 0; i < files.size(); i++)
496 String file = files.get(i).toString();
497 String protocol = (protocols == null) ? FormatAdapter.FILE
498 : (String) protocols.get(i);
499 String format = null;
501 if (file.endsWith(".jar"))
508 format = new IdentifyFile().Identify(file, protocol);
511 new FileLoader().LoadFile(file, protocol, format);
514 } catch (Exception ex)
526 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
528 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
529 .getProperty("LAST_DIRECTORY"),
530 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
531 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
532 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
534 chooser.setFileView(new JalviewFileView());
535 chooser.setDialogTitle("Open local file");
536 chooser.setToolTipText("Open");
538 int value = chooser.showOpenDialog(this);
540 if (value == JalviewFileChooser.APPROVE_OPTION)
542 String choice = chooser.getSelectedFile().getPath();
543 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
544 .getSelectedFile().getParent());
546 String format = null;
547 if (chooser.getSelectedFormat().equals("Jalview"))
553 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
556 if (viewport != null)
558 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
563 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
574 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
576 // This construct allows us to have a wider textfield
578 JLabel label = new JLabel("Enter URL of Input File");
579 final JComboBox history = new JComboBox();
581 JPanel panel = new JPanel(new GridLayout(2, 1));
584 history.setPreferredSize(new Dimension(400, 20));
585 history.setEditable(true);
586 history.addItem("http://www.");
588 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
592 if (historyItems != null)
594 st = new StringTokenizer(historyItems, "\t");
596 while (st.hasMoreTokens())
598 history.addItem(st.nextElement());
602 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
603 "Input Alignment From URL", JOptionPane.OK_CANCEL_OPTION);
605 if (reply != JOptionPane.OK_OPTION)
610 String url = history.getSelectedItem().toString();
612 if (url.toLowerCase().endsWith(".jar"))
614 if (viewport != null)
616 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
621 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
626 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
628 if (format.equals("URL NOT FOUND"))
630 JOptionPane.showInternalMessageDialog(Desktop.desktop,
631 "Couldn't locate " + url, "URL not found",
632 JOptionPane.WARNING_MESSAGE);
637 if (viewport != null)
639 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
643 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
654 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
656 CutAndPasteTransfer cap = new CutAndPasteTransfer();
657 cap.setForInput(viewport);
658 Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
666 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
668 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
669 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
671 storeLastKnownDimensions("",new Rectangle(getBounds().x,getBounds().y, getWidth(), getHeight()));
673 if (jconsole != null)
675 storeLastKnownDimensions("JAVA_CONSOLE_",jconsole.getBounds());
676 jconsole.stopConsole();
681 private void storeLastKnownDimensions(String string, Rectangle jc)
683 jalview.bin.Cache.log.debug("Storing last known dimensions for "+string+": x:"+jc.x + " y:"+jc.y + " width:"+jc.width+" height:"+jc.height);
685 jalview.bin.Cache.setProperty(string+"SCREEN_X",jc.x + "");
686 jalview.bin.Cache.setProperty(string+"SCREEN_Y", jc.y + "");
687 jalview.bin.Cache.setProperty(string+"SCREEN_WIDTH", jc.width + "");
688 jalview.bin.Cache.setProperty(string+"SCREEN_HEIGHT", jc.height
698 public void aboutMenuItem_actionPerformed(ActionEvent e)
700 StringBuffer message = new StringBuffer("Jalview version "
701 + jalview.bin.Cache.getProperty("VERSION") + "; last updated: "
702 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
704 if (!jalview.bin.Cache.getProperty("LATEST_VERSION").equals(
705 jalview.bin.Cache.getProperty("VERSION")))
708 .append("\n\n!! Jalview version "
709 + jalview.bin.Cache.getProperty("LATEST_VERSION")
710 + " is available for download from http://www.jalview.org !!\n");
713 // TODO: update this text for each release or centrally store it for lite
716 .append("\nAuthors: Andrew Waterhouse, Jim Procter, Michele Clamp, James Cuff, Steve Searle,\n David Martin & Geoff Barton."
717 + "\nDevelopment managed by The Barton Group, University of Dundee, Scotland, UK.\n"
718 + "\nFor help, see the FAQ at www.jalview.org and/or join the jalview-discuss@jalview.org mailing list\n"
719 + "\nIf you use Jalview, please cite:"
720 + "\nWaterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
721 + "\nJalview Version 2 - a multiple sequence alignment editor and analysis workbench"
722 + "\nBioinformatics doi: 10.1093/bioinformatics/btp033");
723 JOptionPane.showInternalMessageDialog(Desktop.desktop,
725 message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
734 public void documentationMenuItem_actionPerformed(ActionEvent e)
738 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
739 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
740 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
742 javax.help.HelpBroker hb = hs.createHelpBroker();
743 hb.setCurrentID("home");
744 hb.setDisplayed(true);
745 } catch (Exception ex)
750 public void closeAll_actionPerformed(ActionEvent e)
752 JInternalFrame[] frames = desktop.getAllFrames();
753 for (int i = 0; i < frames.length; i++)
757 frames[i].setClosed(true);
758 } catch (java.beans.PropertyVetoException ex)
762 System.out.println("ALL CLOSED");
763 if (v_client != null)
765 // TODO clear binding to vamsas document objects on close_all
770 public void raiseRelated_actionPerformed(ActionEvent e)
772 reorderAssociatedWindows(false, false);
775 public void minimizeAssociated_actionPerformed(ActionEvent e)
777 reorderAssociatedWindows(true, false);
780 void closeAssociatedWindows()
782 reorderAssociatedWindows(false, true);
788 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
791 protected void garbageCollect_actionPerformed(ActionEvent e)
793 // We simply collect the garbage
794 jalview.bin.Cache.log.debug("Collecting garbage...");
796 jalview.bin.Cache.log.debug("Finished garbage collection.");
803 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
806 protected void showMemusage_actionPerformed(ActionEvent e)
808 desktop.showMemoryUsage(showMemusage.isSelected());
815 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
818 protected void showConsole_actionPerformed(ActionEvent e)
820 showConsole(showConsole.isSelected());
823 Console jconsole = null;
826 * control whether the java console is visible or not
830 void showConsole(boolean selected)
832 showConsole.setSelected(selected);
833 // TODO: decide if we should update properties file
834 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
836 jconsole.setVisible(selected);
839 void reorderAssociatedWindows(boolean minimize, boolean close)
841 JInternalFrame[] frames = desktop.getAllFrames();
842 if (frames == null || frames.length < 1)
847 AlignViewport source = null, target = null;
848 if (frames[0] instanceof AlignFrame)
850 source = ((AlignFrame) frames[0]).getCurrentView();
852 else if (frames[0] instanceof TreePanel)
854 source = ((TreePanel) frames[0]).getViewPort();
856 else if (frames[0] instanceof PCAPanel)
858 source = ((PCAPanel) frames[0]).av;
860 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
862 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
867 for (int i = 0; i < frames.length; i++)
870 if (frames[i] == null)
874 if (frames[i] instanceof AlignFrame)
876 target = ((AlignFrame) frames[i]).getCurrentView();
878 else if (frames[i] instanceof TreePanel)
880 target = ((TreePanel) frames[i]).getViewPort();
882 else if (frames[i] instanceof PCAPanel)
884 target = ((PCAPanel) frames[i]).av;
886 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
888 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
891 if (source == target)
897 frames[i].setClosed(true);
901 frames[i].setIcon(minimize);
908 } catch (java.beans.PropertyVetoException ex)
922 protected void preferences_actionPerformed(ActionEvent e)
933 public void saveState_actionPerformed(ActionEvent e)
935 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
936 .getProperty("LAST_DIRECTORY"), new String[]
937 { "jar" }, new String[]
938 { "Jalview Project" }, "Jalview Project");
940 chooser.setFileView(new JalviewFileView());
941 chooser.setDialogTitle("Save State");
943 int value = chooser.showSaveDialog(this);
945 if (value == JalviewFileChooser.APPROVE_OPTION)
947 java.io.File choice = chooser.getSelectedFile();
948 JProgressBar progpanel = addProgressPanel("Saving jalview project "
950 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
951 // TODO catch and handle errors for savestate
952 new Jalview2XML().SaveState(choice);
953 removeProgressPanel(progpanel);
964 public void loadState_actionPerformed(ActionEvent e)
966 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
967 .getProperty("LAST_DIRECTORY"), new String[]
968 { "jar" }, new String[]
969 { "Jalview Project" }, "Jalview Project");
970 chooser.setFileView(new JalviewFileView());
971 chooser.setDialogTitle("Restore state");
973 int value = chooser.showOpenDialog(this);
975 if (value == JalviewFileChooser.APPROVE_OPTION)
977 String choice = chooser.getSelectedFile().getAbsolutePath();
978 setProgressBar("loading jalview project "
979 + chooser.getSelectedFile().getName(), choice.hashCode());
980 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
981 .getSelectedFile().getParent());
982 new Jalview2XML().LoadJalviewAlign(choice);
983 setProgressBar(null, choice.hashCode());
987 public void inputSequence_actionPerformed(ActionEvent e)
989 new SequenceFetcher(this);
992 JPanel progressPanel;
994 public void startLoading(final String fileName)
996 if (fileLoadingCount == 0)
998 addProgressPanel("Loading File: " + fileName + " ");
1004 private JProgressBar addProgressPanel(String string)
1006 if (progressPanel == null)
1008 progressPanel = new JPanel(new BorderLayout());
1009 totalProgressCount = 0;
1011 JProgressBar progressBar = new JProgressBar();
1012 progressBar.setIndeterminate(true);
1014 progressPanel.add(new JLabel(string), BorderLayout.WEST);
1016 progressPanel.add(progressBar, BorderLayout.CENTER);
1018 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1019 totalProgressCount++;
1024 int totalProgressCount = 0;
1026 private void removeProgressPanel(JProgressBar progbar)
1028 if (progressPanel != null)
1030 progressPanel.remove(progbar);
1031 if (--totalProgressCount < 1)
1033 this.getContentPane().remove(progressPanel);
1034 progressPanel = null;
1040 public void stopLoading()
1043 if (fileLoadingCount < 1)
1045 if (progressPanel != null)
1047 this.getContentPane().remove(progressPanel);
1048 progressPanel = null;
1050 fileLoadingCount = 0;
1055 public static int getViewCount(String viewId)
1057 AlignViewport[] aps = getViewports(viewId);
1058 return (aps == null) ? 0 : aps.length;
1064 * @return all AlignmentPanels concerning the viewId sequence set
1066 public static AlignmentPanel[] getAlignmentPanels(String viewId)
1069 if (Desktop.desktop == null)
1071 // no frames created and in headless mode
1072 // TODO: verify that frames are recoverable when in headless mode
1075 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1076 ArrayList aps = new ArrayList();
1077 for (int t = 0; t < frames.length; t++)
1079 if (frames[t] instanceof AlignFrame)
1081 AlignFrame af = (AlignFrame) frames[t];
1082 for (int a = 0; a < af.alignPanels.size(); a++)
1085 .equals(((AlignmentPanel) af.alignPanels.elementAt(a)).av
1086 .getSequenceSetId()))
1088 aps.add(af.alignPanels.elementAt(a));
1093 if (aps.size() == 0)
1097 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1098 for (int t = 0; t < vap.length; t++)
1100 vap[t] = (AlignmentPanel) aps.get(t);
1106 * get all the viewports on an alignment.
1108 * @param sequenceSetId
1109 * unique alignment id
1110 * @return all viewports on the alignment bound to sequenceSetId
1112 public static AlignViewport[] getViewports(String sequenceSetId)
1114 Vector viewp = new Vector();
1115 if (desktop != null)
1117 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1119 for (int t = 0; t < frames.length; t++)
1121 if (frames[t] instanceof AlignFrame)
1123 AlignFrame afr = ((AlignFrame) frames[t]);
1124 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1126 if (afr.alignPanels != null)
1128 for (int a = 0; a < afr.alignPanels.size(); a++)
1130 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1131 .elementAt(a)).av.getSequenceSetId()))
1133 viewp.addElement(((AlignmentPanel) afr.alignPanels
1140 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1145 if (viewp.size() > 0)
1147 AlignViewport[] vp = new AlignViewport[viewp.size()];
1155 public void explodeViews(AlignFrame af)
1157 int size = af.alignPanels.size();
1163 for (int i = 0; i < size; i++)
1165 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1166 AlignFrame newaf = new AlignFrame(ap);
1167 if (ap.av.explodedPosition != null
1168 && !ap.av.explodedPosition.equals(af.getBounds()))
1170 newaf.setBounds(ap.av.explodedPosition);
1173 ap.av.gatherViewsHere = false;
1175 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1176 AlignFrame.DEFAULT_HEIGHT);
1179 af.alignPanels.clear();
1180 af.closeMenuItem_actionPerformed(true);
1184 public void gatherViews(AlignFrame source)
1186 source.viewport.gatherViewsHere = true;
1187 source.viewport.explodedPosition = source.getBounds();
1188 JInternalFrame[] frames = desktop.getAllFrames();
1189 String viewId = source.viewport.sequenceSetID;
1191 for (int t = 0; t < frames.length; t++)
1193 if (frames[t] instanceof AlignFrame && frames[t] != source)
1195 AlignFrame af = (AlignFrame) frames[t];
1196 boolean gatherThis = false;
1197 for (int a = 0; a < af.alignPanels.size(); a++)
1199 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1200 if (viewId.equals(ap.av.getSequenceSetId()))
1203 ap.av.gatherViewsHere = false;
1204 ap.av.explodedPosition = af.getBounds();
1205 source.addAlignmentPanel(ap, false);
1211 af.alignPanels.clear();
1212 af.closeMenuItem_actionPerformed(true);
1219 jalview.gui.VamsasApplication v_client = null;
1221 public void vamsasImport_actionPerformed(ActionEvent e)
1223 if (v_client == null)
1225 // Load and try to start a session.
1226 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
1227 .getProperty("LAST_DIRECTORY"));
1229 chooser.setFileView(new JalviewFileView());
1230 chooser.setDialogTitle("Open a saved VAMSAS session");
1232 .setToolTipText("select a vamsas session to be opened as a new vamsas session.");
1234 int value = chooser.showOpenDialog(this);
1236 if (value == JalviewFileChooser.APPROVE_OPTION)
1238 String fle = chooser.getSelectedFile().toString();
1239 if (!vamsasImport(chooser.getSelectedFile()))
1241 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1242 "Couldn't import '" + fle + "' as a new vamsas session.",
1243 "Vamsas Document Import Failed",
1244 JOptionPane.ERROR_MESSAGE);
1250 jalview.bin.Cache.log
1251 .error("Implementation error - load session from a running session is not supported.");
1256 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1259 * @return true if import was a success and a session was started.
1261 public boolean vamsasImport(URL url)
1263 // TODO: create progress bar
1264 if (v_client != null)
1267 jalview.bin.Cache.log
1268 .error("Implementation error - load session from a running session is not supported.");
1274 // copy the URL content to a temporary local file
1275 // TODO: be a bit cleverer here with nio (?!)
1276 File file = File.createTempFile("vdocfromurl", ".vdj");
1277 FileOutputStream fos = new FileOutputStream(file);
1278 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1279 byte[] buffer = new byte[2048];
1281 while ((ln = bis.read(buffer)) > -1)
1283 fos.write(buffer, 0, ln);
1287 v_client = new jalview.gui.VamsasApplication(this, file, url
1289 } catch (Exception ex)
1291 jalview.bin.Cache.log.error(
1292 "Failed to create new vamsas session from contents of URL "
1296 setupVamsasConnectedGui();
1297 v_client.initial_update(); // TODO: thread ?
1298 return v_client.inSession();
1302 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1305 * @return true if import was a success and a session was started.
1307 public boolean vamsasImport(File file)
1309 if (v_client != null)
1312 jalview.bin.Cache.log
1313 .error("Implementation error - load session from a running session is not supported.");
1317 setProgressBar("Importing VAMSAS session from " + file.getName(), file
1321 v_client = new jalview.gui.VamsasApplication(this, file, null);
1322 } catch (Exception ex)
1324 setProgressBar("Importing VAMSAS session from " + file.getName(),
1326 jalview.bin.Cache.log.error(
1327 "New vamsas session from existing session file failed:", ex);
1330 setupVamsasConnectedGui();
1331 v_client.initial_update(); // TODO: thread ?
1332 setProgressBar("Importing VAMSAS session from " + file.getName(), file
1334 return v_client.inSession();
1337 public boolean joinVamsasSession(String mysesid)
1339 if (v_client != null)
1342 "Trying to join a vamsas session when another is already connected.");
1344 if (mysesid == null)
1346 throw new Error("Invalid vamsas session id.");
1348 v_client = new VamsasApplication(this, mysesid);
1349 setupVamsasConnectedGui();
1350 v_client.initial_update();
1351 return (v_client.inSession());
1354 public void vamsasStart_actionPerformed(ActionEvent e)
1356 if (v_client == null)
1359 // we just start a default session for moment.
1361 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1362 * getProperty("LAST_DIRECTORY"));
1364 * chooser.setFileView(new JalviewFileView());
1365 * chooser.setDialogTitle("Load Vamsas file");
1366 * chooser.setToolTipText("Import");
1368 * int value = chooser.showOpenDialog(this);
1370 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1371 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1373 v_client = new VamsasApplication(this);
1374 setupVamsasConnectedGui();
1375 v_client.initial_update(); // TODO: thread ?
1379 // store current data in session.
1380 v_client.push_update(); // TODO: thread
1384 protected void setupVamsasConnectedGui()
1386 vamsasStart.setText("Session Update");
1387 vamsasSave.setVisible(true);
1388 vamsasStop.setVisible(true);
1389 vamsasImport.setVisible(false); // Document import to existing session is
1390 // not possible for vamsas-client-1.0.
1393 protected void setupVamsasDisconnectedGui()
1395 vamsasSave.setVisible(false);
1396 vamsasStop.setVisible(false);
1397 vamsasImport.setVisible(true);
1398 vamsasStart.setText("New Vamsas Session");
1401 public void vamsasStop_actionPerformed(ActionEvent e)
1403 if (v_client != null)
1405 v_client.end_session();
1407 setupVamsasDisconnectedGui();
1411 protected void buildVamsasStMenu()
1413 if (v_client == null)
1415 String[] sess = null;
1418 sess = VamsasApplication.getSessionList();
1419 } catch (Exception e)
1421 jalview.bin.Cache.log.warn(
1422 "Problem getting current sessions list.", e);
1427 jalview.bin.Cache.log.debug("Got current sessions list: "
1428 + sess.length + " entries.");
1429 VamsasStMenu.removeAll();
1430 for (int i = 0; i < sess.length; i++)
1432 JMenuItem sessit = new JMenuItem();
1433 sessit.setText(sess[i]);
1434 sessit.setToolTipText("Connect to session " + sess[i]);
1435 final Desktop dsktp = this;
1436 final String mysesid = sess[i];
1437 sessit.addActionListener(new ActionListener()
1440 public void actionPerformed(ActionEvent e)
1442 if (dsktp.v_client == null)
1444 Thread rthr = new Thread(new Runnable()
1449 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1450 dsktp.setupVamsasConnectedGui();
1451 dsktp.v_client.initial_update();
1459 VamsasStMenu.add(sessit);
1461 // don't show an empty menu.
1462 VamsasStMenu.setVisible(sess.length > 0);
1467 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1468 VamsasStMenu.removeAll();
1469 VamsasStMenu.setVisible(false);
1474 // Not interested in the content. Just hide ourselves.
1475 VamsasStMenu.setVisible(false);
1479 public void vamsasSave_actionPerformed(ActionEvent e)
1481 if (v_client != null)
1483 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
1484 .getProperty("LAST_DIRECTORY"), new String[]
1485 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1487 { "Vamsas Document" }, "Vamsas Document");
1489 chooser.setFileView(new JalviewFileView());
1490 chooser.setDialogTitle("Save Vamsas Document Archive");
1492 int value = chooser.showSaveDialog(this);
1494 if (value == JalviewFileChooser.APPROVE_OPTION)
1496 java.io.File choice = chooser.getSelectedFile();
1497 JProgressBar progpanel = addProgressPanel("Saving VAMSAS Document to "
1498 + choice.getName());
1499 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1500 String warnmsg = null;
1501 String warnttl = null;
1504 v_client.vclient.storeDocument(choice);
1507 warnttl = "Serious Problem saving Vamsas Document";
1508 warnmsg = ex.toString();
1509 jalview.bin.Cache.log.error("Error Whilst saving document to "
1512 } catch (Exception ex)
1514 warnttl = "Problem saving Vamsas Document.";
1515 warnmsg = ex.toString();
1516 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
1520 removeProgressPanel(progpanel);
1521 if (warnmsg != null)
1523 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1525 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
1531 JProgressBar vamUpdate = null;
1534 * hide vamsas user gui bits when a vamsas document event is being handled.
1537 * true to hide gui, false to reveal gui
1539 public void setVamsasUpdate(boolean b)
1541 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
1542 + (b ? "in progress" : "finished"));
1544 if (vamUpdate != null)
1546 this.removeProgressPanel(vamUpdate);
1550 vamUpdate = this.addProgressPanel("Updating vamsas session");
1552 vamsasStart.setVisible(!b);
1553 vamsasStop.setVisible(!b);
1554 vamsasSave.setVisible(!b);
1557 public JInternalFrame[] getAllFrames()
1559 return desktop.getAllFrames();
1563 * Checks the given url to see if it gives a response indicating that the user
1564 * should be informed of a new questionnaire.
1568 public void checkForQuestionnaire(String url)
1570 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
1571 // javax.swing.SwingUtilities.invokeLater(jvq);
1572 new Thread(jvq).start();
1576 * Proxy class for JDesktopPane which optionally displays the current memory
1577 * usage and highlights the desktop area with a red bar if free memory runs
1582 public class MyDesktopPane extends JDesktopPane implements Runnable
1585 boolean showMemoryUsage = false;
1589 java.text.NumberFormat df;
1591 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
1594 public MyDesktopPane(boolean showMemoryUsage)
1596 showMemoryUsage(showMemoryUsage);
1599 public void showMemoryUsage(boolean showMemoryUsage)
1601 this.showMemoryUsage = showMemoryUsage;
1602 if (showMemoryUsage)
1604 Thread worker = new Thread(this);
1609 public boolean isShowMemoryUsage()
1611 return showMemoryUsage;
1616 df = java.text.NumberFormat.getNumberInstance();
1617 df.setMaximumFractionDigits(2);
1618 runtime = Runtime.getRuntime();
1620 while (showMemoryUsage)
1624 maxMemory = runtime.maxMemory() / 1048576f;
1625 allocatedMemory = runtime.totalMemory() / 1048576f;
1626 freeMemory = runtime.freeMemory() / 1048576f;
1627 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
1629 percentUsage = (totalFreeMemory / maxMemory) * 100;
1631 // if (percentUsage < 20)
1633 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
1635 // instance.set.setBorder(border1);
1638 // sleep after showing usage
1640 } catch (Exception ex)
1642 ex.printStackTrace();
1647 public void paintComponent(Graphics g)
1649 if (showMemoryUsage && g != null)
1651 if (percentUsage < 20)
1652 g.setColor(Color.red);
1654 g.drawString("Total Free Memory: " + df.format(totalFreeMemory)
1655 + "MB; Max Memory: " + df.format(maxMemory) + "MB; "
1656 + df.format(percentUsage) + "%", 10, getHeight()
1657 - g.getFontMetrics().getHeight());
1663 protected JMenuItem groovyShell;
1665 public void doGroovyCheck()
1667 if (jalview.bin.Cache.groovyJarsPresent())
1669 groovyShell = new JMenuItem();
1670 groovyShell.setText("Groovy Console...");
1671 groovyShell.addActionListener(new ActionListener()
1673 public void actionPerformed(ActionEvent e)
1675 groovyShell_actionPerformed(e);
1678 toolsMenu.add(groovyShell);
1679 groovyShell.setVisible(true);
1684 * Accessor method to quickly get all the AlignmentFrames loaded.
1686 public static AlignFrame[] getAlignframes()
1688 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1694 Vector avp = new Vector();
1698 for (int i = frames.length - 1; i > -1; i--)
1700 if (frames[i] instanceof AlignFrame)
1702 AlignFrame af = (AlignFrame) frames[i];
1706 } catch (Exception ex)
1708 ex.printStackTrace();
1710 if (avp.size() == 0)
1714 AlignFrame afs[] = new AlignFrame[avp.size()];
1715 for (int i = 0, j = avp.size(); i < j; i++)
1717 afs[i] = (AlignFrame) avp.elementAt(i);
1724 * Add Groovy Support to Jalview
1726 public void groovyShell_actionPerformed(ActionEvent e)
1728 // use reflection to avoid creating compilation dependency.
1729 if (!jalview.bin.Cache.groovyJarsPresent())
1732 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
1736 Class gcClass = Desktop.class.getClassLoader().loadClass(
1737 "groovy.ui.Console");
1738 Constructor gccons = gcClass.getConstructor(null);
1739 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
1741 { String.class, Object.class });
1742 java.lang.reflect.Method run = gcClass.getMethod("run", null);
1743 Object gc = gccons.newInstance(null);
1744 setvar.invoke(gc, new Object[]
1745 { "Jalview", this });
1746 run.invoke(gc, null);
1747 } catch (Exception ex)
1749 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
1751 .showInternalMessageDialog(
1754 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
1755 "Jalview Groovy Support Failed",
1756 JOptionPane.ERROR_MESSAGE);
1761 * Progress bars managed by the IProgressIndicator method.
1763 private Hashtable progressBars, progressBarHandlers;
1768 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
1770 public void setProgressBar(String message, long id)
1772 if (progressBars == null)
1774 progressBars = new Hashtable();
1775 progressBarHandlers = new Hashtable();
1778 if (progressBars.get(new Long(id)) != null)
1780 JProgressBar progressPanel = (JProgressBar) progressBars
1781 .remove(new Long(id));
1782 if (progressBarHandlers.contains(new Long(id)))
1784 progressBarHandlers.remove(new Long(id));
1786 removeProgressPanel(progressPanel);
1790 progressBars.put(new Long(id), addProgressPanel(message));
1797 * @see jalview.gui.IProgressIndicator#registerHandler(long,
1798 * jalview.gui.IProgressIndicatorHandler)
1800 public void registerHandler(final long id,
1801 final IProgressIndicatorHandler handler)
1803 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
1806 "call setProgressBar before registering the progress bar's handler.");
1808 progressBarHandlers.put(new Long(id), handler);
1809 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
1810 if (handler.canCancel())
1812 JButton cancel = new JButton("Cancel");
1813 final IProgressIndicator us = this;
1814 cancel.addActionListener(new ActionListener()
1817 public void actionPerformed(ActionEvent e)
1819 handler.cancelActivity(id);
1820 us.setProgressBar("Cancelled "
1821 + ((JLabel) progressPanel.getComponent(0)).getText(), id);
1824 progressPanel.add(cancel, BorderLayout.EAST);
1829 * This will return the first AlignFrame viewing AlignViewport av. It will
1830 * break if there are more than one AlignFrames viewing a particular av. This
1833 * @return alignFrame for av
1835 public static AlignFrame getAlignFrameFor(AlignViewport av)
1837 if (desktop != null)
1839 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
1840 for (int panel = 0; aps != null && panel < aps.length; panel++)
1842 if (aps[panel] != null && aps[panel].av == av)
1844 return aps[panel].alignFrame;
1851 public VamsasApplication getVamsasApplication()