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 // immediately output essential build information
119 System.out.println("Jalview Desktop "+jalview.bin.Cache.getProperty("VERSION")+"\n"
121 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")+"\n"
122 + "Java version: " + System.getProperty("java.version")
123 + "\n"+System.getProperty("os.arch") + " "
124 + System.getProperty("os.name") + " "
125 + System.getProperty("os.version"));
127 showConsole(showjconsole);
129 this.addWindowListener(new WindowAdapter()
131 public void windowClosing(WindowEvent evt)
137 this.addMouseListener(new MouseAdapter()
139 public void mousePressed(MouseEvent evt)
141 if (SwingUtilities.isRightMouseButton(evt))
143 showPasteMenu(evt.getX(), evt.getY());
148 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
149 // Spawn a thread that shows the splashscreen
150 SwingUtilities.invokeLater(new Runnable()
158 discoverer = new jalview.ws.Discoverer(); // Only gets started if gui is
163 * recover the last known dimensions for a jalview window
165 * - empty string is desktop, all other windows have unique prefix
166 * @return null or last known dimensions scaled to current geometry (if last
167 * window geom was known)
169 Rectangle getLastKnownDimensions(String windowName)
171 // TODO: lock aspect ratio for scaling desktop Bug #0058199
172 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
173 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
174 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
175 String width = jalview.bin.Cache.getProperty(windowName
177 String height = jalview.bin.Cache.getProperty(windowName
179 if ((x != null) && (y != null) && (width != null) && (height != null))
181 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
182 .parseInt(width), ih = Integer.parseInt(height);
183 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
185 // attempt #1 - try to cope with change in screen geometry - this
186 // version doesn't preserve original jv aspect ratio.
187 // take ratio of current screen size vs original screen size.
188 double sw = ( (1f*screenSize.width)
189 / (1f*Integer.parseInt(jalview.bin.Cache
190 .getProperty("SCREENGEOMETRY_WIDTH"))))
192 double sh = ( (1f*screenSize.height)
193 / (1f*Integer.parseInt(jalview.bin.Cache
194 .getProperty("SCREENGEOMETRY_HEIGHT"))));
195 // rescale the bounds depending upon the current screen geometry.
196 ix = (int) (ix * sw);
197 iw = (int) (iw * sw);
198 iy = (int) (iy * sh);
199 ih = (int) (ih * sh);
200 jalview.bin.Cache.log.debug("Got last known dimensions for "+windowName+": x:"+ix + " y:"+iy + " width:"+iw+" height:"+ih);
202 // return dimensions for new instance
203 return new Rectangle(ix, iy, iw, ih);
208 private void doVamsasClientCheck()
210 if (jalview.bin.Cache.vamsasJarsPresent())
212 setupVamsasDisconnectedGui();
213 VamsasMenu.setVisible(true);
214 final Desktop us = this;
215 VamsasMenu.addMenuListener(new MenuListener()
217 // this listener remembers when the menu was first selected, and
218 // doesn't rebuild the session list until it has been cleared and
220 boolean refresh = true;
222 public void menuCanceled(MenuEvent e)
227 public void menuDeselected(MenuEvent e)
232 public void menuSelected(MenuEvent e)
236 us.buildVamsasStMenu();
241 vamsasStart.setVisible(true);
245 void showPasteMenu(int x, int y)
247 JPopupMenu popup = new JPopupMenu();
248 JMenuItem item = new JMenuItem("Paste To New Window");
249 item.addActionListener(new ActionListener()
251 public void actionPerformed(ActionEvent evt)
258 popup.show(this, x, y);
265 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
266 Transferable contents = c.getContents(this);
268 if (contents != null)
270 String file = (String) contents
271 .getTransferData(DataFlavor.stringFlavor);
273 String format = new IdentifyFile().Identify(file,
274 FormatAdapter.PASTE);
276 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
279 } catch (Exception ex)
282 .println("Unable to paste alignment from system clipboard:\n"
299 public static synchronized void addInternalFrame(
300 final JInternalFrame frame, String title, int w, int h)
302 addInternalFrame(frame, title, w, h, true);
319 public static synchronized void addInternalFrame(
320 final JInternalFrame frame, String title, int w, int h,
324 // TODO: consider fixing method to update entries in the window submenu with
325 // the current window title
327 frame.setTitle(title);
328 if (frame.getWidth() < 1 || frame.getHeight() < 1)
332 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
333 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
334 // IF JALVIEW IS RUNNING HEADLESS
335 // ///////////////////////////////////////////////
336 if (System.getProperty("java.awt.headless") != null
337 && System.getProperty("java.awt.headless").equals("true"))
344 frame.setVisible(true);
345 frame.setClosable(true);
346 frame.setResizable(resizable);
347 frame.setMaximizable(resizable);
348 frame.setIconifiable(resizable);
349 frame.setFrameIcon(null);
351 if (frame.getX() < 1 && frame.getY() < 1)
353 frame.setLocation(xOffset * openFrameCount, yOffset
354 * ((openFrameCount - 1) % 10) + yOffset);
357 final JMenuItem menuItem = new JMenuItem(title);
359 .addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
361 public void internalFrameActivated(
362 javax.swing.event.InternalFrameEvent evt)
364 JInternalFrame itf = desktop.getSelectedFrame();
372 public void internalFrameClosed(
373 javax.swing.event.InternalFrameEvent evt)
375 PaintRefresher.RemoveComponent(frame);
377 windowMenu.remove(menuItem);
378 JInternalFrame itf = desktop.getSelectedFrame();
387 menuItem.addActionListener(new ActionListener()
389 public void actionPerformed(ActionEvent e)
393 frame.setSelected(true);
394 frame.setIcon(false);
395 } catch (java.beans.PropertyVetoException ex)
402 windowMenu.add(menuItem);
408 frame.setSelected(true);
409 frame.requestFocus();
410 } catch (java.beans.PropertyVetoException ve)
415 public void lostOwnership(Clipboard clipboard, Transferable contents)
419 Desktop.jalviewClipboard = null;
422 internalCopy = false;
425 public void dragEnter(DropTargetDragEvent evt)
429 public void dragExit(DropTargetEvent evt)
433 public void dragOver(DropTargetDragEvent evt)
437 public void dropActionChanged(DropTargetDragEvent evt)
447 public void drop(DropTargetDropEvent evt)
449 Transferable t = evt.getTransferable();
450 java.util.List files = null;
451 java.util.List protocols = null;
455 DataFlavor uriListFlavor = new DataFlavor(
456 "text/uri-list;class=java.lang.String");
457 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
459 // Works on Windows and MacOSX
460 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
461 files = (java.util.List) t
462 .getTransferData(DataFlavor.javaFileListFlavor);
464 else if (t.isDataFlavorSupported(uriListFlavor))
466 // This is used by Unix drag system
467 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
468 String data = (String) t.getTransferData(uriListFlavor);
469 files = new java.util.ArrayList(1);
470 protocols = new java.util.ArrayList(1);
471 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
472 data, "\r\n"); st.hasMoreTokens();)
474 String s = st.nextToken();
475 if (s.startsWith("#"))
477 // the line is a comment (as per the RFC 2483)
480 java.net.URI uri = new java.net.URI(s);
481 if (uri.getScheme().toLowerCase().startsWith("http"))
483 protocols.add(FormatAdapter.URL);
484 files.add(uri.toString());
488 // otherwise preserve old behaviour: catch all for file objects
489 java.io.File file = new java.io.File(uri);
490 protocols.add(FormatAdapter.FILE);
491 files.add(file.toString());
495 } catch (Exception e)
503 for (int i = 0; i < files.size(); i++)
505 String file = files.get(i).toString();
506 String protocol = (protocols == null) ? FormatAdapter.FILE
507 : (String) protocols.get(i);
508 String format = null;
510 if (file.endsWith(".jar"))
517 format = new IdentifyFile().Identify(file, protocol);
520 new FileLoader().LoadFile(file, protocol, format);
523 } catch (Exception ex)
535 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
537 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
538 .getProperty("LAST_DIRECTORY"),
539 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
540 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
541 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
543 chooser.setFileView(new JalviewFileView());
544 chooser.setDialogTitle("Open local file");
545 chooser.setToolTipText("Open");
547 int value = chooser.showOpenDialog(this);
549 if (value == JalviewFileChooser.APPROVE_OPTION)
551 String choice = chooser.getSelectedFile().getPath();
552 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
553 .getSelectedFile().getParent());
555 String format = null;
556 if (chooser.getSelectedFormat().equals("Jalview"))
562 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
565 if (viewport != null)
567 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
572 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
583 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
585 // This construct allows us to have a wider textfield
587 JLabel label = new JLabel("Enter URL of Input File");
588 final JComboBox history = new JComboBox();
590 JPanel panel = new JPanel(new GridLayout(2, 1));
593 history.setPreferredSize(new Dimension(400, 20));
594 history.setEditable(true);
595 history.addItem("http://www.");
597 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
601 if (historyItems != null)
603 st = new StringTokenizer(historyItems, "\t");
605 while (st.hasMoreTokens())
607 history.addItem(st.nextElement());
611 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
612 "Input Alignment From URL", JOptionPane.OK_CANCEL_OPTION);
614 if (reply != JOptionPane.OK_OPTION)
619 String url = history.getSelectedItem().toString();
621 if (url.toLowerCase().endsWith(".jar"))
623 if (viewport != null)
625 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
630 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
635 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
637 if (format.equals("URL NOT FOUND"))
639 JOptionPane.showInternalMessageDialog(Desktop.desktop,
640 "Couldn't locate " + url, "URL not found",
641 JOptionPane.WARNING_MESSAGE);
646 if (viewport != null)
648 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
652 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
663 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
665 CutAndPasteTransfer cap = new CutAndPasteTransfer();
666 cap.setForInput(viewport);
667 Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
675 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
677 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
678 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
680 storeLastKnownDimensions("",new Rectangle(getBounds().x,getBounds().y, getWidth(), getHeight()));
682 if (jconsole != null)
684 storeLastKnownDimensions("JAVA_CONSOLE_",jconsole.getBounds());
685 jconsole.stopConsole();
690 private void storeLastKnownDimensions(String string, Rectangle jc)
692 jalview.bin.Cache.log.debug("Storing last known dimensions for "+string+": x:"+jc.x + " y:"+jc.y + " width:"+jc.width+" height:"+jc.height);
694 jalview.bin.Cache.setProperty(string+"SCREEN_X",jc.x + "");
695 jalview.bin.Cache.setProperty(string+"SCREEN_Y", jc.y + "");
696 jalview.bin.Cache.setProperty(string+"SCREEN_WIDTH", jc.width + "");
697 jalview.bin.Cache.setProperty(string+"SCREEN_HEIGHT", jc.height
707 public void aboutMenuItem_actionPerformed(ActionEvent e)
709 StringBuffer message = new StringBuffer("Jalview version "
710 + jalview.bin.Cache.getProperty("VERSION") + "; last updated: "
711 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
713 if (!jalview.bin.Cache.getProperty("LATEST_VERSION").equals(
714 jalview.bin.Cache.getProperty("VERSION")))
717 .append("\n\n!! Jalview version "
718 + jalview.bin.Cache.getProperty("LATEST_VERSION")
719 + " is available for download from http://www.jalview.org !!\n");
722 // TODO: update this text for each release or centrally store it for lite
725 .append("\nAuthors: Andrew Waterhouse, Jim Procter, Michele Clamp, James Cuff, Steve Searle,\n David Martin & Geoff Barton."
726 + "\nDevelopment managed by The Barton Group, University of Dundee, Scotland, UK.\n"
727 + "\nFor help, see the FAQ at www.jalview.org and/or join the jalview-discuss@jalview.org mailing list\n"
728 + "\nIf you use Jalview, please cite:"
729 + "\nWaterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
730 + "\nJalview Version 2 - a multiple sequence alignment editor and analysis workbench"
731 + "\nBioinformatics doi: 10.1093/bioinformatics/btp033");
732 JOptionPane.showInternalMessageDialog(Desktop.desktop,
734 message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
743 public void documentationMenuItem_actionPerformed(ActionEvent e)
747 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
748 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
749 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
751 javax.help.HelpBroker hb = hs.createHelpBroker();
752 hb.setCurrentID("home");
753 hb.setDisplayed(true);
754 } catch (Exception ex)
759 public void closeAll_actionPerformed(ActionEvent e)
761 JInternalFrame[] frames = desktop.getAllFrames();
762 for (int i = 0; i < frames.length; i++)
766 frames[i].setClosed(true);
767 } catch (java.beans.PropertyVetoException ex)
771 System.out.println("ALL CLOSED");
772 if (v_client != null)
774 // TODO clear binding to vamsas document objects on close_all
779 public void raiseRelated_actionPerformed(ActionEvent e)
781 reorderAssociatedWindows(false, false);
784 public void minimizeAssociated_actionPerformed(ActionEvent e)
786 reorderAssociatedWindows(true, false);
789 void closeAssociatedWindows()
791 reorderAssociatedWindows(false, true);
797 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
800 protected void garbageCollect_actionPerformed(ActionEvent e)
802 // We simply collect the garbage
803 jalview.bin.Cache.log.debug("Collecting garbage...");
805 jalview.bin.Cache.log.debug("Finished garbage collection.");
812 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
815 protected void showMemusage_actionPerformed(ActionEvent e)
817 desktop.showMemoryUsage(showMemusage.isSelected());
824 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
827 protected void showConsole_actionPerformed(ActionEvent e)
829 showConsole(showConsole.isSelected());
832 Console jconsole = null;
835 * control whether the java console is visible or not
839 void showConsole(boolean selected)
841 showConsole.setSelected(selected);
842 // TODO: decide if we should update properties file
843 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
845 jconsole.setVisible(selected);
848 void reorderAssociatedWindows(boolean minimize, boolean close)
850 JInternalFrame[] frames = desktop.getAllFrames();
851 if (frames == null || frames.length < 1)
856 AlignViewport source = null, target = null;
857 if (frames[0] instanceof AlignFrame)
859 source = ((AlignFrame) frames[0]).getCurrentView();
861 else if (frames[0] instanceof TreePanel)
863 source = ((TreePanel) frames[0]).getViewPort();
865 else if (frames[0] instanceof PCAPanel)
867 source = ((PCAPanel) frames[0]).av;
869 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
871 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
876 for (int i = 0; i < frames.length; i++)
879 if (frames[i] == null)
883 if (frames[i] instanceof AlignFrame)
885 target = ((AlignFrame) frames[i]).getCurrentView();
887 else if (frames[i] instanceof TreePanel)
889 target = ((TreePanel) frames[i]).getViewPort();
891 else if (frames[i] instanceof PCAPanel)
893 target = ((PCAPanel) frames[i]).av;
895 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
897 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
900 if (source == target)
906 frames[i].setClosed(true);
910 frames[i].setIcon(minimize);
917 } catch (java.beans.PropertyVetoException ex)
931 protected void preferences_actionPerformed(ActionEvent e)
942 public void saveState_actionPerformed(ActionEvent e)
944 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
945 .getProperty("LAST_DIRECTORY"), new String[]
946 { "jar" }, new String[]
947 { "Jalview Project" }, "Jalview Project");
949 chooser.setFileView(new JalviewFileView());
950 chooser.setDialogTitle("Save State");
952 int value = chooser.showSaveDialog(this);
954 if (value == JalviewFileChooser.APPROVE_OPTION)
956 java.io.File choice = chooser.getSelectedFile();
957 JProgressBar progpanel = addProgressPanel("Saving jalview project "
959 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
960 // TODO catch and handle errors for savestate
961 new Jalview2XML().SaveState(choice);
962 removeProgressPanel(progpanel);
973 public void loadState_actionPerformed(ActionEvent e)
975 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
976 .getProperty("LAST_DIRECTORY"), new String[]
977 { "jar" }, new String[]
978 { "Jalview Project" }, "Jalview Project");
979 chooser.setFileView(new JalviewFileView());
980 chooser.setDialogTitle("Restore state");
982 int value = chooser.showOpenDialog(this);
984 if (value == JalviewFileChooser.APPROVE_OPTION)
986 String choice = chooser.getSelectedFile().getAbsolutePath();
987 setProgressBar("loading jalview project "
988 + chooser.getSelectedFile().getName(), choice.hashCode());
989 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
990 .getSelectedFile().getParent());
991 new Jalview2XML().LoadJalviewAlign(choice);
992 setProgressBar(null, choice.hashCode());
996 public void inputSequence_actionPerformed(ActionEvent e)
998 new SequenceFetcher(this);
1001 JPanel progressPanel;
1003 public void startLoading(final String fileName)
1005 if (fileLoadingCount == 0)
1007 addProgressPanel("Loading File: " + fileName + " ");
1013 private JProgressBar addProgressPanel(String string)
1015 if (progressPanel == null)
1017 progressPanel = new JPanel(new BorderLayout());
1018 totalProgressCount = 0;
1020 JProgressBar progressBar = new JProgressBar();
1021 progressBar.setIndeterminate(true);
1023 progressPanel.add(new JLabel(string), BorderLayout.WEST);
1025 progressPanel.add(progressBar, BorderLayout.CENTER);
1027 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1028 totalProgressCount++;
1033 int totalProgressCount = 0;
1035 private void removeProgressPanel(JProgressBar progbar)
1037 if (progressPanel != null)
1039 progressPanel.remove(progbar);
1040 if (--totalProgressCount < 1)
1042 this.getContentPane().remove(progressPanel);
1043 progressPanel = null;
1049 public void stopLoading()
1052 if (fileLoadingCount < 1)
1054 if (progressPanel != null)
1056 this.getContentPane().remove(progressPanel);
1057 progressPanel = null;
1059 fileLoadingCount = 0;
1064 public static int getViewCount(String viewId)
1066 AlignViewport[] aps = getViewports(viewId);
1067 return (aps == null) ? 0 : aps.length;
1073 * @return all AlignmentPanels concerning the viewId sequence set
1075 public static AlignmentPanel[] getAlignmentPanels(String viewId)
1078 if (Desktop.desktop == null)
1080 // no frames created and in headless mode
1081 // TODO: verify that frames are recoverable when in headless mode
1084 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1085 ArrayList aps = new ArrayList();
1086 for (int t = 0; t < frames.length; t++)
1088 if (frames[t] instanceof AlignFrame)
1090 AlignFrame af = (AlignFrame) frames[t];
1091 for (int a = 0; a < af.alignPanels.size(); a++)
1094 .equals(((AlignmentPanel) af.alignPanels.elementAt(a)).av
1095 .getSequenceSetId()))
1097 aps.add(af.alignPanels.elementAt(a));
1102 if (aps.size() == 0)
1106 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1107 for (int t = 0; t < vap.length; t++)
1109 vap[t] = (AlignmentPanel) aps.get(t);
1115 * get all the viewports on an alignment.
1117 * @param sequenceSetId
1118 * unique alignment id
1119 * @return all viewports on the alignment bound to sequenceSetId
1121 public static AlignViewport[] getViewports(String sequenceSetId)
1123 Vector viewp = new Vector();
1124 if (desktop != null)
1126 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1128 for (int t = 0; t < frames.length; t++)
1130 if (frames[t] instanceof AlignFrame)
1132 AlignFrame afr = ((AlignFrame) frames[t]);
1133 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1135 if (afr.alignPanels != null)
1137 for (int a = 0; a < afr.alignPanels.size(); a++)
1139 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1140 .elementAt(a)).av.getSequenceSetId()))
1142 viewp.addElement(((AlignmentPanel) afr.alignPanels
1149 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1154 if (viewp.size() > 0)
1156 AlignViewport[] vp = new AlignViewport[viewp.size()];
1164 public void explodeViews(AlignFrame af)
1166 int size = af.alignPanels.size();
1172 for (int i = 0; i < size; i++)
1174 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1175 AlignFrame newaf = new AlignFrame(ap);
1176 if (ap.av.explodedPosition != null
1177 && !ap.av.explodedPosition.equals(af.getBounds()))
1179 newaf.setBounds(ap.av.explodedPosition);
1182 ap.av.gatherViewsHere = false;
1184 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1185 AlignFrame.DEFAULT_HEIGHT);
1188 af.alignPanels.clear();
1189 af.closeMenuItem_actionPerformed(true);
1193 public void gatherViews(AlignFrame source)
1195 source.viewport.gatherViewsHere = true;
1196 source.viewport.explodedPosition = source.getBounds();
1197 JInternalFrame[] frames = desktop.getAllFrames();
1198 String viewId = source.viewport.sequenceSetID;
1200 for (int t = 0; t < frames.length; t++)
1202 if (frames[t] instanceof AlignFrame && frames[t] != source)
1204 AlignFrame af = (AlignFrame) frames[t];
1205 boolean gatherThis = false;
1206 for (int a = 0; a < af.alignPanels.size(); a++)
1208 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1209 if (viewId.equals(ap.av.getSequenceSetId()))
1212 ap.av.gatherViewsHere = false;
1213 ap.av.explodedPosition = af.getBounds();
1214 source.addAlignmentPanel(ap, false);
1220 af.alignPanels.clear();
1221 af.closeMenuItem_actionPerformed(true);
1228 jalview.gui.VamsasApplication v_client = null;
1230 public void vamsasImport_actionPerformed(ActionEvent e)
1232 if (v_client == null)
1234 // Load and try to start a session.
1235 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
1236 .getProperty("LAST_DIRECTORY"));
1238 chooser.setFileView(new JalviewFileView());
1239 chooser.setDialogTitle("Open a saved VAMSAS session");
1241 .setToolTipText("select a vamsas session to be opened as a new vamsas session.");
1243 int value = chooser.showOpenDialog(this);
1245 if (value == JalviewFileChooser.APPROVE_OPTION)
1247 String fle = chooser.getSelectedFile().toString();
1248 if (!vamsasImport(chooser.getSelectedFile()))
1250 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1251 "Couldn't import '" + fle + "' as a new vamsas session.",
1252 "Vamsas Document Import Failed",
1253 JOptionPane.ERROR_MESSAGE);
1259 jalview.bin.Cache.log
1260 .error("Implementation error - load session from a running session is not supported.");
1265 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1268 * @return true if import was a success and a session was started.
1270 public boolean vamsasImport(URL url)
1272 // TODO: create progress bar
1273 if (v_client != null)
1276 jalview.bin.Cache.log
1277 .error("Implementation error - load session from a running session is not supported.");
1283 // copy the URL content to a temporary local file
1284 // TODO: be a bit cleverer here with nio (?!)
1285 File file = File.createTempFile("vdocfromurl", ".vdj");
1286 FileOutputStream fos = new FileOutputStream(file);
1287 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1288 byte[] buffer = new byte[2048];
1290 while ((ln = bis.read(buffer)) > -1)
1292 fos.write(buffer, 0, ln);
1296 v_client = new jalview.gui.VamsasApplication(this, file, url
1298 } catch (Exception ex)
1300 jalview.bin.Cache.log.error(
1301 "Failed to create new vamsas session from contents of URL "
1305 setupVamsasConnectedGui();
1306 v_client.initial_update(); // TODO: thread ?
1307 return v_client.inSession();
1311 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1314 * @return true if import was a success and a session was started.
1316 public boolean vamsasImport(File file)
1318 if (v_client != null)
1321 jalview.bin.Cache.log
1322 .error("Implementation error - load session from a running session is not supported.");
1326 setProgressBar("Importing VAMSAS session from " + file.getName(), file
1330 v_client = new jalview.gui.VamsasApplication(this, file, null);
1331 } catch (Exception ex)
1333 setProgressBar("Importing VAMSAS session from " + file.getName(),
1335 jalview.bin.Cache.log.error(
1336 "New vamsas session from existing session file failed:", ex);
1339 setupVamsasConnectedGui();
1340 v_client.initial_update(); // TODO: thread ?
1341 setProgressBar("Importing VAMSAS session from " + file.getName(), file
1343 return v_client.inSession();
1346 public boolean joinVamsasSession(String mysesid)
1348 if (v_client != null)
1351 "Trying to join a vamsas session when another is already connected.");
1353 if (mysesid == null)
1355 throw new Error("Invalid vamsas session id.");
1357 v_client = new VamsasApplication(this, mysesid);
1358 setupVamsasConnectedGui();
1359 v_client.initial_update();
1360 return (v_client.inSession());
1363 public void vamsasStart_actionPerformed(ActionEvent e)
1365 if (v_client == null)
1368 // we just start a default session for moment.
1370 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1371 * getProperty("LAST_DIRECTORY"));
1373 * chooser.setFileView(new JalviewFileView());
1374 * chooser.setDialogTitle("Load Vamsas file");
1375 * chooser.setToolTipText("Import");
1377 * int value = chooser.showOpenDialog(this);
1379 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1380 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1382 v_client = new VamsasApplication(this);
1383 setupVamsasConnectedGui();
1384 v_client.initial_update(); // TODO: thread ?
1388 // store current data in session.
1389 v_client.push_update(); // TODO: thread
1393 protected void setupVamsasConnectedGui()
1395 vamsasStart.setText("Session Update");
1396 vamsasSave.setVisible(true);
1397 vamsasStop.setVisible(true);
1398 vamsasImport.setVisible(false); // Document import to existing session is
1399 // not possible for vamsas-client-1.0.
1402 protected void setupVamsasDisconnectedGui()
1404 vamsasSave.setVisible(false);
1405 vamsasStop.setVisible(false);
1406 vamsasImport.setVisible(true);
1407 vamsasStart.setText("New Vamsas Session");
1410 public void vamsasStop_actionPerformed(ActionEvent e)
1412 if (v_client != null)
1414 v_client.end_session();
1416 setupVamsasDisconnectedGui();
1420 protected void buildVamsasStMenu()
1422 if (v_client == null)
1424 String[] sess = null;
1427 sess = VamsasApplication.getSessionList();
1428 } catch (Exception e)
1430 jalview.bin.Cache.log.warn(
1431 "Problem getting current sessions list.", e);
1436 jalview.bin.Cache.log.debug("Got current sessions list: "
1437 + sess.length + " entries.");
1438 VamsasStMenu.removeAll();
1439 for (int i = 0; i < sess.length; i++)
1441 JMenuItem sessit = new JMenuItem();
1442 sessit.setText(sess[i]);
1443 sessit.setToolTipText("Connect to session " + sess[i]);
1444 final Desktop dsktp = this;
1445 final String mysesid = sess[i];
1446 sessit.addActionListener(new ActionListener()
1449 public void actionPerformed(ActionEvent e)
1451 if (dsktp.v_client == null)
1453 Thread rthr = new Thread(new Runnable()
1458 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1459 dsktp.setupVamsasConnectedGui();
1460 dsktp.v_client.initial_update();
1468 VamsasStMenu.add(sessit);
1470 // don't show an empty menu.
1471 VamsasStMenu.setVisible(sess.length > 0);
1476 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1477 VamsasStMenu.removeAll();
1478 VamsasStMenu.setVisible(false);
1483 // Not interested in the content. Just hide ourselves.
1484 VamsasStMenu.setVisible(false);
1488 public void vamsasSave_actionPerformed(ActionEvent e)
1490 if (v_client != null)
1492 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
1493 .getProperty("LAST_DIRECTORY"), new String[]
1494 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1496 { "Vamsas Document" }, "Vamsas Document");
1498 chooser.setFileView(new JalviewFileView());
1499 chooser.setDialogTitle("Save Vamsas Document Archive");
1501 int value = chooser.showSaveDialog(this);
1503 if (value == JalviewFileChooser.APPROVE_OPTION)
1505 java.io.File choice = chooser.getSelectedFile();
1506 JProgressBar progpanel = addProgressPanel("Saving VAMSAS Document to "
1507 + choice.getName());
1508 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1509 String warnmsg = null;
1510 String warnttl = null;
1513 v_client.vclient.storeDocument(choice);
1516 warnttl = "Serious Problem saving Vamsas Document";
1517 warnmsg = ex.toString();
1518 jalview.bin.Cache.log.error("Error Whilst saving document to "
1521 } catch (Exception ex)
1523 warnttl = "Problem saving Vamsas Document.";
1524 warnmsg = ex.toString();
1525 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
1529 removeProgressPanel(progpanel);
1530 if (warnmsg != null)
1532 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1534 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
1540 JProgressBar vamUpdate = null;
1543 * hide vamsas user gui bits when a vamsas document event is being handled.
1546 * true to hide gui, false to reveal gui
1548 public void setVamsasUpdate(boolean b)
1550 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
1551 + (b ? "in progress" : "finished"));
1553 if (vamUpdate != null)
1555 this.removeProgressPanel(vamUpdate);
1559 vamUpdate = this.addProgressPanel("Updating vamsas session");
1561 vamsasStart.setVisible(!b);
1562 vamsasStop.setVisible(!b);
1563 vamsasSave.setVisible(!b);
1566 public JInternalFrame[] getAllFrames()
1568 return desktop.getAllFrames();
1572 * Checks the given url to see if it gives a response indicating that the user
1573 * should be informed of a new questionnaire.
1577 public void checkForQuestionnaire(String url)
1579 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
1580 // javax.swing.SwingUtilities.invokeLater(jvq);
1581 new Thread(jvq).start();
1585 * Proxy class for JDesktopPane which optionally displays the current memory
1586 * usage and highlights the desktop area with a red bar if free memory runs
1591 public class MyDesktopPane extends JDesktopPane implements Runnable
1594 boolean showMemoryUsage = false;
1598 java.text.NumberFormat df;
1600 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
1603 public MyDesktopPane(boolean showMemoryUsage)
1605 showMemoryUsage(showMemoryUsage);
1608 public void showMemoryUsage(boolean showMemoryUsage)
1610 this.showMemoryUsage = showMemoryUsage;
1611 if (showMemoryUsage)
1613 Thread worker = new Thread(this);
1618 public boolean isShowMemoryUsage()
1620 return showMemoryUsage;
1625 df = java.text.NumberFormat.getNumberInstance();
1626 df.setMaximumFractionDigits(2);
1627 runtime = Runtime.getRuntime();
1629 while (showMemoryUsage)
1633 maxMemory = runtime.maxMemory() / 1048576f;
1634 allocatedMemory = runtime.totalMemory() / 1048576f;
1635 freeMemory = runtime.freeMemory() / 1048576f;
1636 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
1638 percentUsage = (totalFreeMemory / maxMemory) * 100;
1640 // if (percentUsage < 20)
1642 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
1644 // instance.set.setBorder(border1);
1647 // sleep after showing usage
1649 } catch (Exception ex)
1651 ex.printStackTrace();
1656 public void paintComponent(Graphics g)
1658 if (showMemoryUsage && g != null)
1660 if (percentUsage < 20)
1661 g.setColor(Color.red);
1662 FontMetrics fm = g.getFontMetrics();
1664 { g.drawString("Total Free Memory: " + df.format(totalFreeMemory)
1665 + "MB; Max Memory: " + df.format(maxMemory) + "MB; "
1666 + df.format(percentUsage) + "%", 10, getHeight()
1674 protected JMenuItem groovyShell;
1676 public void doGroovyCheck()
1678 if (jalview.bin.Cache.groovyJarsPresent())
1680 groovyShell = new JMenuItem();
1681 groovyShell.setText("Groovy Console...");
1682 groovyShell.addActionListener(new ActionListener()
1684 public void actionPerformed(ActionEvent e)
1686 groovyShell_actionPerformed(e);
1689 toolsMenu.add(groovyShell);
1690 groovyShell.setVisible(true);
1695 * Accessor method to quickly get all the AlignmentFrames loaded.
1697 public static AlignFrame[] getAlignframes()
1699 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1705 Vector avp = new Vector();
1709 for (int i = frames.length - 1; i > -1; i--)
1711 if (frames[i] instanceof AlignFrame)
1713 AlignFrame af = (AlignFrame) frames[i];
1717 } catch (Exception ex)
1719 ex.printStackTrace();
1721 if (avp.size() == 0)
1725 AlignFrame afs[] = new AlignFrame[avp.size()];
1726 for (int i = 0, j = avp.size(); i < j; i++)
1728 afs[i] = (AlignFrame) avp.elementAt(i);
1735 * Add Groovy Support to Jalview
1737 public void groovyShell_actionPerformed(ActionEvent e)
1739 // use reflection to avoid creating compilation dependency.
1740 if (!jalview.bin.Cache.groovyJarsPresent())
1743 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
1747 Class gcClass = Desktop.class.getClassLoader().loadClass(
1748 "groovy.ui.Console");
1749 Constructor gccons = gcClass.getConstructor(null);
1750 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
1752 { String.class, Object.class });
1753 java.lang.reflect.Method run = gcClass.getMethod("run", null);
1754 Object gc = gccons.newInstance(null);
1755 setvar.invoke(gc, new Object[]
1756 { "Jalview", this });
1757 run.invoke(gc, null);
1758 } catch (Exception ex)
1760 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
1762 .showInternalMessageDialog(
1765 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
1766 "Jalview Groovy Support Failed",
1767 JOptionPane.ERROR_MESSAGE);
1772 * Progress bars managed by the IProgressIndicator method.
1774 private Hashtable progressBars, progressBarHandlers;
1779 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
1781 public void setProgressBar(String message, long id)
1783 if (progressBars == null)
1785 progressBars = new Hashtable();
1786 progressBarHandlers = new Hashtable();
1789 if (progressBars.get(new Long(id)) != null)
1791 JProgressBar progressPanel = (JProgressBar) progressBars
1792 .remove(new Long(id));
1793 if (progressBarHandlers.contains(new Long(id)))
1795 progressBarHandlers.remove(new Long(id));
1797 removeProgressPanel(progressPanel);
1801 progressBars.put(new Long(id), addProgressPanel(message));
1808 * @see jalview.gui.IProgressIndicator#registerHandler(long,
1809 * jalview.gui.IProgressIndicatorHandler)
1811 public void registerHandler(final long id,
1812 final IProgressIndicatorHandler handler)
1814 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
1817 "call setProgressBar before registering the progress bar's handler.");
1819 progressBarHandlers.put(new Long(id), handler);
1820 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
1821 if (handler.canCancel())
1823 JButton cancel = new JButton("Cancel");
1824 final IProgressIndicator us = this;
1825 cancel.addActionListener(new ActionListener()
1828 public void actionPerformed(ActionEvent e)
1830 handler.cancelActivity(id);
1831 us.setProgressBar("Cancelled "
1832 + ((JLabel) progressPanel.getComponent(0)).getText(), id);
1835 progressPanel.add(cancel, BorderLayout.EAST);
1840 * This will return the first AlignFrame viewing AlignViewport av. It will
1841 * break if there are more than one AlignFrames viewing a particular av. This
1844 * @return alignFrame for av
1846 public static AlignFrame getAlignFrameFor(AlignViewport av)
1848 if (desktop != null)
1850 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
1851 for (int panel = 0; aps != null && panel < aps.length; panel++)
1853 if (aps[panel] != null && aps[panel].av == av)
1855 return aps[panel].alignFrame;
1862 public VamsasApplication getVamsasApplication()