2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
3 * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
20 import jalview.bin.Cache;
24 import java.awt.datatransfer.*;
25 import java.awt.dnd.*;
26 import java.awt.event.*;
27 import java.io.BufferedInputStream;
28 import java.io.BufferedOutputStream;
30 import java.io.FileOutputStream;
31 import java.io.InputStream;
32 import java.lang.reflect.Constructor;
34 import java.net.URLConnection;
35 import java.nio.channels.ReadableByteChannel;
39 import javax.swing.event.MenuEvent;
40 import javax.swing.event.MenuListener;
48 public class Desktop extends jalview.jbgui.GDesktop implements
49 DropTargetListener, ClipboardOwner, IProgressIndicator
52 public static Desktop instance;
54 // Need to decide if the Memory Usage is to be included in
55 // Next release or not.
56 public static MyDesktopPane desktop;
58 // public static JDesktopPane desktop;
60 static int openFrameCount = 0;
62 static final int xOffset = 30;
64 static final int yOffset = 30;
66 public static jalview.ws.Discoverer discoverer;
68 public static Object[] jalviewClipboard;
70 public static boolean internalCopy = false;
72 static int fileLoadingCount = 0;
75 * Creates a new Desktop object.
80 * A note to implementors. It is ESSENTIAL that any activities that might
81 * block are spawned off as threads rather than waited for during this
85 doVamsasClientCheck();
88 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
89 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
90 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
92 boolean showjconsole = jalview.bin.Cache.getDefault(
93 "SHOW_JAVA_CONSOLE", false);
94 desktop = new MyDesktopPane(selmemusage);
95 showMemusage.setSelected(selmemusage);
96 desktop.setBackground(Color.white);
97 getContentPane().setLayout(new BorderLayout());
98 getContentPane().add(desktop, BorderLayout.CENTER);
99 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
101 // This line prevents Windows Look&Feel resizing all new windows to maximum
102 // if previous window was maximised
103 desktop.setDesktopManager(new DefaultDesktopManager());
105 Rectangle dims = getLastKnownDimensions("");
112 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
113 setBounds((int) (screenSize.width - 900) / 2,
114 (int) (screenSize.height - 650) / 2, 900, 650);
116 jconsole = new Console(this);
117 // immediately output essential build information
118 System.out.println("Jalview Desktop "
119 + jalview.bin.Cache.getProperty("VERSION") + "\n"
121 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
122 + "Java version: " + System.getProperty("java.version") + "\n"
123 + 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
160 // Thread off a new instance of the file chooser - this reduces the time it
161 // takes to open it later on.
162 new Thread(new Runnable()
166 Cache.log.debug("Filechooser init thread started.");
167 JalviewFileChooser chooser = new JalviewFileChooser(
168 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
169 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
170 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
171 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
172 Cache.log.debug("Filechooser init thread finished.");
178 * recover the last known dimensions for a jalview window
181 * - empty string is desktop, all other windows have unique prefix
182 * @return null or last known dimensions scaled to current geometry (if last
183 * window geom was known)
185 Rectangle getLastKnownDimensions(String windowName)
187 // TODO: lock aspect ratio for scaling desktop Bug #0058199
188 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
189 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
190 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
191 String width = jalview.bin.Cache.getProperty(windowName
193 String height = jalview.bin.Cache.getProperty(windowName
195 if ((x != null) && (y != null) && (width != null) && (height != null))
197 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
198 .parseInt(width), ih = Integer.parseInt(height);
199 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
201 // attempt #1 - try to cope with change in screen geometry - this
202 // version doesn't preserve original jv aspect ratio.
203 // take ratio of current screen size vs original screen size.
204 double sw = ((1f * screenSize.width) / (1f * Integer
205 .parseInt(jalview.bin.Cache
206 .getProperty("SCREENGEOMETRY_WIDTH"))));
207 double sh = ((1f * screenSize.height) / (1f * Integer
208 .parseInt(jalview.bin.Cache
209 .getProperty("SCREENGEOMETRY_HEIGHT"))));
210 // rescale the bounds depending upon the current screen geometry.
211 ix = (int) (ix * sw);
212 iw = (int) (iw * sw);
213 iy = (int) (iy * sh);
214 ih = (int) (ih * sh);
215 jalview.bin.Cache.log.debug("Got last known dimensions for "
216 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
219 // return dimensions for new instance
220 return new Rectangle(ix, iy, iw, ih);
225 private void doVamsasClientCheck()
227 if (jalview.bin.Cache.vamsasJarsPresent())
229 setupVamsasDisconnectedGui();
230 VamsasMenu.setVisible(true);
231 final Desktop us = this;
232 VamsasMenu.addMenuListener(new MenuListener()
234 // this listener remembers when the menu was first selected, and
235 // doesn't rebuild the session list until it has been cleared and
237 boolean refresh = true;
239 public void menuCanceled(MenuEvent e)
244 public void menuDeselected(MenuEvent e)
249 public void menuSelected(MenuEvent e)
253 us.buildVamsasStMenu();
258 vamsasStart.setVisible(true);
262 void showPasteMenu(int x, int y)
264 JPopupMenu popup = new JPopupMenu();
265 JMenuItem item = new JMenuItem("Paste To New Window");
266 item.addActionListener(new ActionListener()
268 public void actionPerformed(ActionEvent evt)
275 popup.show(this, x, y);
282 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
283 Transferable contents = c.getContents(this);
285 if (contents != null)
287 String file = (String) contents
288 .getTransferData(DataFlavor.stringFlavor);
290 String format = new IdentifyFile().Identify(file,
291 FormatAdapter.PASTE);
293 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
296 } catch (Exception ex)
299 .println("Unable to paste alignment from system clipboard:\n"
305 * Adds and opens the given frame to the desktop
316 public static synchronized void addInternalFrame(
317 final JInternalFrame frame, String title, int w, int h)
319 addInternalFrame(frame, title, w, h, true);
336 public static synchronized void addInternalFrame(
337 final JInternalFrame frame, String title, int w, int h,
341 // TODO: allow callers to determine X and Y position of frame (eg. via
343 // TODO: consider fixing method to update entries in the window submenu with
344 // the current window title
346 frame.setTitle(title);
347 if (frame.getWidth() < 1 || frame.getHeight() < 1)
351 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
352 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
353 // IF JALVIEW IS RUNNING HEADLESS
354 // ///////////////////////////////////////////////
355 if (System.getProperty("java.awt.headless") != null
356 && System.getProperty("java.awt.headless").equals("true"))
363 frame.setVisible(true);
364 frame.setClosable(true);
365 frame.setResizable(resizable);
366 frame.setMaximizable(resizable);
367 frame.setIconifiable(resizable);
368 frame.setFrameIcon(null);
370 if (frame.getX() < 1 && frame.getY() < 1)
372 frame.setLocation(xOffset * openFrameCount, yOffset
373 * ((openFrameCount - 1) % 10) + yOffset);
376 final JMenuItem menuItem = new JMenuItem(title);
378 .addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
380 public void internalFrameActivated(
381 javax.swing.event.InternalFrameEvent evt)
383 JInternalFrame itf = desktop.getSelectedFrame();
391 public void internalFrameClosed(
392 javax.swing.event.InternalFrameEvent evt)
394 PaintRefresher.RemoveComponent(frame);
396 windowMenu.remove(menuItem);
397 JInternalFrame itf = desktop.getSelectedFrame();
406 menuItem.addActionListener(new ActionListener()
408 public void actionPerformed(ActionEvent e)
412 frame.setSelected(true);
413 frame.setIcon(false);
414 } catch (java.beans.PropertyVetoException ex)
421 windowMenu.add(menuItem);
427 frame.setSelected(true);
428 frame.requestFocus();
429 } catch (java.beans.PropertyVetoException ve)
434 public void lostOwnership(Clipboard clipboard, Transferable contents)
438 Desktop.jalviewClipboard = null;
441 internalCopy = false;
444 public void dragEnter(DropTargetDragEvent evt)
448 public void dragExit(DropTargetEvent evt)
452 public void dragOver(DropTargetDragEvent evt)
456 public void dropActionChanged(DropTargetDragEvent evt)
466 public void drop(DropTargetDropEvent evt)
468 Transferable t = evt.getTransferable();
469 java.util.List files = null;
470 java.util.List protocols = null;
474 DataFlavor uriListFlavor = new DataFlavor(
475 "text/uri-list;class=java.lang.String");
476 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
478 // Works on Windows and MacOSX
479 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
480 files = (java.util.List) t
481 .getTransferData(DataFlavor.javaFileListFlavor);
483 else if (t.isDataFlavorSupported(uriListFlavor))
485 // This is used by Unix drag system
486 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
487 String data = (String) t.getTransferData(uriListFlavor);
488 files = new java.util.ArrayList(1);
489 protocols = new java.util.ArrayList(1);
490 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
491 data, "\r\n"); st.hasMoreTokens();)
493 String s = st.nextToken();
494 if (s.startsWith("#"))
496 // the line is a comment (as per the RFC 2483)
499 java.net.URI uri = new java.net.URI(s);
500 if (uri.getScheme().toLowerCase().startsWith("http"))
502 protocols.add(FormatAdapter.URL);
503 files.add(uri.toString());
507 // otherwise preserve old behaviour: catch all for file objects
508 java.io.File file = new java.io.File(uri);
509 protocols.add(FormatAdapter.FILE);
510 files.add(file.toString());
514 } catch (Exception e)
522 for (int i = 0; i < files.size(); i++)
524 String file = files.get(i).toString();
525 String protocol = (protocols == null) ? FormatAdapter.FILE
526 : (String) protocols.get(i);
527 String format = null;
529 if (file.endsWith(".jar"))
536 format = new IdentifyFile().Identify(file, protocol);
539 new FileLoader().LoadFile(file, protocol, format);
542 } catch (Exception ex)
554 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
556 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
557 .getProperty("LAST_DIRECTORY"),
558 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
559 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
560 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
562 chooser.setFileView(new JalviewFileView());
563 chooser.setDialogTitle("Open local file");
564 chooser.setToolTipText("Open");
566 int value = chooser.showOpenDialog(this);
568 if (value == JalviewFileChooser.APPROVE_OPTION)
570 String choice = chooser.getSelectedFile().getPath();
571 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
572 .getSelectedFile().getParent());
574 String format = null;
575 if (chooser.getSelectedFormat().equals("Jalview"))
581 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
584 if (viewport != null)
586 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
591 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
602 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
604 // This construct allows us to have a wider textfield
606 JLabel label = new JLabel("Enter URL of Input File");
607 final JComboBox history = new JComboBox();
609 JPanel panel = new JPanel(new GridLayout(2, 1));
612 history.setPreferredSize(new Dimension(400, 20));
613 history.setEditable(true);
614 history.addItem("http://www.");
616 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
620 if (historyItems != null)
622 st = new StringTokenizer(historyItems, "\t");
624 while (st.hasMoreTokens())
626 history.addItem(st.nextElement());
630 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
631 "Input Alignment From URL", JOptionPane.OK_CANCEL_OPTION);
633 if (reply != JOptionPane.OK_OPTION)
638 String url = history.getSelectedItem().toString();
640 if (url.toLowerCase().endsWith(".jar"))
642 if (viewport != null)
644 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
649 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
654 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
656 if (format.equals("URL NOT FOUND"))
658 JOptionPane.showInternalMessageDialog(Desktop.desktop,
659 "Couldn't locate " + url, "URL not found",
660 JOptionPane.WARNING_MESSAGE);
665 if (viewport != null)
667 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
671 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
682 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
684 CutAndPasteTransfer cap = new CutAndPasteTransfer();
685 cap.setForInput(viewport);
686 Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
694 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
696 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
697 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
699 storeLastKnownDimensions("", new Rectangle(getBounds().x,
700 getBounds().y, getWidth(), getHeight()));
702 if (jconsole != null)
704 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
705 jconsole.stopConsole();
710 private void storeLastKnownDimensions(String string, Rectangle jc)
712 jalview.bin.Cache.log.debug("Storing last known dimensions for "
713 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
714 + " height:" + jc.height);
716 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
717 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
718 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
719 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
728 public void aboutMenuItem_actionPerformed(ActionEvent e)
730 StringBuffer message = new StringBuffer("Jalview version "
731 + jalview.bin.Cache.getProperty("VERSION") + "; last updated: "
732 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
734 if (!jalview.bin.Cache.getProperty("LATEST_VERSION").equals(
735 jalview.bin.Cache.getProperty("VERSION")))
738 .append("\n\n!! Jalview version "
739 + jalview.bin.Cache.getProperty("LATEST_VERSION")
740 + " is available for download from http://www.jalview.org !!\n");
743 // TODO: update this text for each release or centrally store it for lite
746 .append("\nAuthors: Andrew Waterhouse, Jim Procter, Michele Clamp, James Cuff, Steve Searle,\n David Martin & Geoff Barton."
747 + "\nDevelopment managed by The Barton Group, University of Dundee, Scotland, UK.\n"
748 + "\nFor help, see the FAQ at www.jalview.org and/or join the jalview-discuss@jalview.org mailing list\n"
749 + "\nIf you use Jalview, please cite:"
750 + "\nWaterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
751 + "\nJalview Version 2 - a multiple sequence alignment editor and analysis workbench"
752 + "\nBioinformatics doi: 10.1093/bioinformatics/btp033");
753 JOptionPane.showInternalMessageDialog(Desktop.desktop,
755 message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
764 public void documentationMenuItem_actionPerformed(ActionEvent e)
768 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
769 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
770 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
772 javax.help.HelpBroker hb = hs.createHelpBroker();
773 hb.setCurrentID("home");
774 hb.setDisplayed(true);
775 } catch (Exception ex)
780 public void closeAll_actionPerformed(ActionEvent e)
782 JInternalFrame[] frames = desktop.getAllFrames();
783 for (int i = 0; i < frames.length; i++)
787 frames[i].setClosed(true);
788 } catch (java.beans.PropertyVetoException ex)
792 System.out.println("ALL CLOSED");
793 if (v_client != null)
795 // TODO clear binding to vamsas document objects on close_all
800 public void raiseRelated_actionPerformed(ActionEvent e)
802 reorderAssociatedWindows(false, false);
805 public void minimizeAssociated_actionPerformed(ActionEvent e)
807 reorderAssociatedWindows(true, false);
810 void closeAssociatedWindows()
812 reorderAssociatedWindows(false, true);
818 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
821 protected void garbageCollect_actionPerformed(ActionEvent e)
823 // We simply collect the garbage
824 jalview.bin.Cache.log.debug("Collecting garbage...");
826 jalview.bin.Cache.log.debug("Finished garbage collection.");
833 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
836 protected void showMemusage_actionPerformed(ActionEvent e)
838 desktop.showMemoryUsage(showMemusage.isSelected());
845 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
848 protected void showConsole_actionPerformed(ActionEvent e)
850 showConsole(showConsole.isSelected());
853 Console jconsole = null;
856 * control whether the java console is visible or not
860 void showConsole(boolean selected)
862 showConsole.setSelected(selected);
863 // TODO: decide if we should update properties file
864 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
866 jconsole.setVisible(selected);
869 void reorderAssociatedWindows(boolean minimize, boolean close)
871 JInternalFrame[] frames = desktop.getAllFrames();
872 if (frames == null || frames.length < 1)
877 AlignViewport source = null, target = null;
878 if (frames[0] instanceof AlignFrame)
880 source = ((AlignFrame) frames[0]).getCurrentView();
882 else if (frames[0] instanceof TreePanel)
884 source = ((TreePanel) frames[0]).getViewPort();
886 else if (frames[0] instanceof PCAPanel)
888 source = ((PCAPanel) frames[0]).av;
890 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
892 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
897 for (int i = 0; i < frames.length; i++)
900 if (frames[i] == null)
904 if (frames[i] instanceof AlignFrame)
906 target = ((AlignFrame) frames[i]).getCurrentView();
908 else if (frames[i] instanceof TreePanel)
910 target = ((TreePanel) frames[i]).getViewPort();
912 else if (frames[i] instanceof PCAPanel)
914 target = ((PCAPanel) frames[i]).av;
916 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
918 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
921 if (source == target)
927 frames[i].setClosed(true);
931 frames[i].setIcon(minimize);
938 } catch (java.beans.PropertyVetoException ex)
952 protected void preferences_actionPerformed(ActionEvent e)
963 public void saveState_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");
970 chooser.setFileView(new JalviewFileView());
971 chooser.setDialogTitle("Save State");
973 int value = chooser.showSaveDialog(this);
975 if (value == JalviewFileChooser.APPROVE_OPTION)
977 java.io.File choice = chooser.getSelectedFile();
978 JProgressBar progpanel = addProgressPanel("Saving jalview project "
980 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
981 // TODO catch and handle errors for savestate
982 new Jalview2XML().SaveState(choice);
983 removeProgressPanel(progpanel);
994 public void loadState_actionPerformed(ActionEvent e)
996 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
997 .getProperty("LAST_DIRECTORY"), new String[]
998 { "jar" }, new String[]
999 { "Jalview Project" }, "Jalview Project");
1000 chooser.setFileView(new JalviewFileView());
1001 chooser.setDialogTitle("Restore state");
1003 int value = chooser.showOpenDialog(this);
1005 if (value == JalviewFileChooser.APPROVE_OPTION)
1007 String choice = chooser.getSelectedFile().getAbsolutePath();
1008 setProgressBar("loading jalview project "
1009 + chooser.getSelectedFile().getName(), choice.hashCode());
1010 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1011 .getSelectedFile().getParent());
1012 new Jalview2XML().LoadJalviewAlign(choice);
1013 setProgressBar(null, choice.hashCode());
1017 public void inputSequence_actionPerformed(ActionEvent e)
1019 new SequenceFetcher(this);
1022 JPanel progressPanel;
1024 public void startLoading(final String fileName)
1026 if (fileLoadingCount == 0)
1028 addProgressPanel("Loading File: " + fileName + " ");
1034 private JProgressBar addProgressPanel(String string)
1036 if (progressPanel == null)
1038 progressPanel = new JPanel(new BorderLayout());
1039 totalProgressCount = 0;
1041 JProgressBar progressBar = new JProgressBar();
1042 progressBar.setIndeterminate(true);
1044 progressPanel.add(new JLabel(string), BorderLayout.WEST);
1046 progressPanel.add(progressBar, BorderLayout.CENTER);
1048 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1049 totalProgressCount++;
1054 int totalProgressCount = 0;
1056 private void removeProgressPanel(JProgressBar progbar)
1058 if (progressPanel != null)
1060 progressPanel.remove(progbar);
1061 if (--totalProgressCount < 1)
1063 this.getContentPane().remove(progressPanel);
1064 progressPanel = null;
1070 public void stopLoading()
1073 if (fileLoadingCount < 1)
1075 if (progressPanel != null)
1077 this.getContentPane().remove(progressPanel);
1078 progressPanel = null;
1080 fileLoadingCount = 0;
1085 public static int getViewCount(String viewId)
1087 AlignViewport[] aps = getViewports(viewId);
1088 return (aps == null) ? 0 : aps.length;
1094 * @return all AlignmentPanels concerning the viewId sequence set
1096 public static AlignmentPanel[] getAlignmentPanels(String viewId)
1099 if (Desktop.desktop == null)
1101 // no frames created and in headless mode
1102 // TODO: verify that frames are recoverable when in headless mode
1105 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1106 ArrayList aps = new ArrayList();
1107 for (int t = 0; t < frames.length; t++)
1109 if (frames[t] instanceof AlignFrame)
1111 AlignFrame af = (AlignFrame) frames[t];
1112 for (int a = 0; a < af.alignPanels.size(); a++)
1115 .equals(((AlignmentPanel) af.alignPanels.elementAt(a)).av
1116 .getSequenceSetId()))
1118 aps.add(af.alignPanels.elementAt(a));
1123 if (aps.size() == 0)
1127 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1128 for (int t = 0; t < vap.length; t++)
1130 vap[t] = (AlignmentPanel) aps.get(t);
1136 * get all the viewports on an alignment.
1138 * @param sequenceSetId
1139 * unique alignment id
1140 * @return all viewports on the alignment bound to sequenceSetId
1142 public static AlignViewport[] getViewports(String sequenceSetId)
1144 Vector viewp = new Vector();
1145 if (desktop != null)
1147 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1149 for (int t = 0; t < frames.length; t++)
1151 if (frames[t] instanceof AlignFrame)
1153 AlignFrame afr = ((AlignFrame) frames[t]);
1154 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1156 if (afr.alignPanels != null)
1158 for (int a = 0; a < afr.alignPanels.size(); a++)
1160 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1161 .elementAt(a)).av.getSequenceSetId()))
1163 viewp.addElement(((AlignmentPanel) afr.alignPanels
1170 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1175 if (viewp.size() > 0)
1177 AlignViewport[] vp = new AlignViewport[viewp.size()];
1185 public void explodeViews(AlignFrame af)
1187 int size = af.alignPanels.size();
1193 for (int i = 0; i < size; i++)
1195 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1196 AlignFrame newaf = new AlignFrame(ap);
1197 if (ap.av.explodedPosition != null
1198 && !ap.av.explodedPosition.equals(af.getBounds()))
1200 newaf.setBounds(ap.av.explodedPosition);
1203 ap.av.gatherViewsHere = false;
1205 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1206 AlignFrame.DEFAULT_HEIGHT);
1209 af.alignPanels.clear();
1210 af.closeMenuItem_actionPerformed(true);
1214 public void gatherViews(AlignFrame source)
1216 source.viewport.gatherViewsHere = true;
1217 source.viewport.explodedPosition = source.getBounds();
1218 JInternalFrame[] frames = desktop.getAllFrames();
1219 String viewId = source.viewport.sequenceSetID;
1221 for (int t = 0; t < frames.length; t++)
1223 if (frames[t] instanceof AlignFrame && frames[t] != source)
1225 AlignFrame af = (AlignFrame) frames[t];
1226 boolean gatherThis = false;
1227 for (int a = 0; a < af.alignPanels.size(); a++)
1229 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1230 if (viewId.equals(ap.av.getSequenceSetId()))
1233 ap.av.gatherViewsHere = false;
1234 ap.av.explodedPosition = af.getBounds();
1235 source.addAlignmentPanel(ap, false);
1241 af.alignPanels.clear();
1242 af.closeMenuItem_actionPerformed(true);
1249 jalview.gui.VamsasApplication v_client = null;
1251 public void vamsasImport_actionPerformed(ActionEvent e)
1253 if (v_client == null)
1255 // Load and try to start a session.
1256 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
1257 .getProperty("LAST_DIRECTORY"));
1259 chooser.setFileView(new JalviewFileView());
1260 chooser.setDialogTitle("Open a saved VAMSAS session");
1262 .setToolTipText("select a vamsas session to be opened as a new vamsas session.");
1264 int value = chooser.showOpenDialog(this);
1266 if (value == JalviewFileChooser.APPROVE_OPTION)
1268 String fle = chooser.getSelectedFile().toString();
1269 if (!vamsasImport(chooser.getSelectedFile()))
1271 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1272 "Couldn't import '" + fle + "' as a new vamsas session.",
1273 "Vamsas Document Import Failed",
1274 JOptionPane.ERROR_MESSAGE);
1280 jalview.bin.Cache.log
1281 .error("Implementation error - load session from a running session is not supported.");
1286 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1289 * @return true if import was a success and a session was started.
1291 public boolean vamsasImport(URL url)
1293 // TODO: create progress bar
1294 if (v_client != null)
1297 jalview.bin.Cache.log
1298 .error("Implementation error - load session from a running session is not supported.");
1304 // copy the URL content to a temporary local file
1305 // TODO: be a bit cleverer here with nio (?!)
1306 File file = File.createTempFile("vdocfromurl", ".vdj");
1307 FileOutputStream fos = new FileOutputStream(file);
1308 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1309 byte[] buffer = new byte[2048];
1311 while ((ln = bis.read(buffer)) > -1)
1313 fos.write(buffer, 0, ln);
1317 v_client = new jalview.gui.VamsasApplication(this, file, url
1319 } catch (Exception ex)
1321 jalview.bin.Cache.log.error(
1322 "Failed to create new vamsas session from contents of URL "
1326 setupVamsasConnectedGui();
1327 v_client.initial_update(); // TODO: thread ?
1328 return v_client.inSession();
1332 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1335 * @return true if import was a success and a session was started.
1337 public boolean vamsasImport(File file)
1339 if (v_client != null)
1342 jalview.bin.Cache.log
1343 .error("Implementation error - load session from a running session is not supported.");
1347 setProgressBar("Importing VAMSAS session from " + file.getName(), file
1351 v_client = new jalview.gui.VamsasApplication(this, file, null);
1352 } catch (Exception ex)
1354 setProgressBar("Importing VAMSAS session from " + file.getName(),
1356 jalview.bin.Cache.log.error(
1357 "New vamsas session from existing session file failed:", ex);
1360 setupVamsasConnectedGui();
1361 v_client.initial_update(); // TODO: thread ?
1362 setProgressBar("Importing VAMSAS session from " + file.getName(), file
1364 return v_client.inSession();
1367 public boolean joinVamsasSession(String mysesid)
1369 if (v_client != null)
1372 "Trying to join a vamsas session when another is already connected.");
1374 if (mysesid == null)
1376 throw new Error("Invalid vamsas session id.");
1378 v_client = new VamsasApplication(this, mysesid);
1379 setupVamsasConnectedGui();
1380 v_client.initial_update();
1381 return (v_client.inSession());
1384 public void vamsasStart_actionPerformed(ActionEvent e)
1386 if (v_client == null)
1389 // we just start a default session for moment.
1391 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1392 * getProperty("LAST_DIRECTORY"));
1394 * chooser.setFileView(new JalviewFileView());
1395 * chooser.setDialogTitle("Load Vamsas file");
1396 * chooser.setToolTipText("Import");
1398 * int value = chooser.showOpenDialog(this);
1400 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1401 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1403 v_client = new VamsasApplication(this);
1404 setupVamsasConnectedGui();
1405 v_client.initial_update(); // TODO: thread ?
1409 // store current data in session.
1410 v_client.push_update(); // TODO: thread
1414 protected void setupVamsasConnectedGui()
1416 vamsasStart.setText("Session Update");
1417 vamsasSave.setVisible(true);
1418 vamsasStop.setVisible(true);
1419 vamsasImport.setVisible(false); // Document import to existing session is
1420 // not possible for vamsas-client-1.0.
1423 protected void setupVamsasDisconnectedGui()
1425 vamsasSave.setVisible(false);
1426 vamsasStop.setVisible(false);
1427 vamsasImport.setVisible(true);
1428 vamsasStart.setText("New Vamsas Session");
1431 public void vamsasStop_actionPerformed(ActionEvent e)
1433 if (v_client != null)
1435 v_client.end_session();
1437 setupVamsasDisconnectedGui();
1441 protected void buildVamsasStMenu()
1443 if (v_client == null)
1445 String[] sess = null;
1448 sess = VamsasApplication.getSessionList();
1449 } catch (Exception e)
1451 jalview.bin.Cache.log.warn(
1452 "Problem getting current sessions list.", e);
1457 jalview.bin.Cache.log.debug("Got current sessions list: "
1458 + sess.length + " entries.");
1459 VamsasStMenu.removeAll();
1460 for (int i = 0; i < sess.length; i++)
1462 JMenuItem sessit = new JMenuItem();
1463 sessit.setText(sess[i]);
1464 sessit.setToolTipText("Connect to session " + sess[i]);
1465 final Desktop dsktp = this;
1466 final String mysesid = sess[i];
1467 sessit.addActionListener(new ActionListener()
1470 public void actionPerformed(ActionEvent e)
1472 if (dsktp.v_client == null)
1474 Thread rthr = new Thread(new Runnable()
1479 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1480 dsktp.setupVamsasConnectedGui();
1481 dsktp.v_client.initial_update();
1489 VamsasStMenu.add(sessit);
1491 // don't show an empty menu.
1492 VamsasStMenu.setVisible(sess.length > 0);
1497 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1498 VamsasStMenu.removeAll();
1499 VamsasStMenu.setVisible(false);
1504 // Not interested in the content. Just hide ourselves.
1505 VamsasStMenu.setVisible(false);
1509 public void vamsasSave_actionPerformed(ActionEvent e)
1511 if (v_client != null)
1513 JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache
1514 .getProperty("LAST_DIRECTORY"), new String[]
1515 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1517 { "Vamsas Document" }, "Vamsas Document");
1519 chooser.setFileView(new JalviewFileView());
1520 chooser.setDialogTitle("Save Vamsas Document Archive");
1522 int value = chooser.showSaveDialog(this);
1524 if (value == JalviewFileChooser.APPROVE_OPTION)
1526 java.io.File choice = chooser.getSelectedFile();
1527 JProgressBar progpanel = addProgressPanel("Saving VAMSAS Document to "
1528 + choice.getName());
1529 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1530 String warnmsg = null;
1531 String warnttl = null;
1534 v_client.vclient.storeDocument(choice);
1537 warnttl = "Serious Problem saving Vamsas Document";
1538 warnmsg = ex.toString();
1539 jalview.bin.Cache.log.error("Error Whilst saving document to "
1542 } catch (Exception ex)
1544 warnttl = "Problem saving Vamsas Document.";
1545 warnmsg = ex.toString();
1546 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
1550 removeProgressPanel(progpanel);
1551 if (warnmsg != null)
1553 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1555 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
1561 JProgressBar vamUpdate = null;
1564 * hide vamsas user gui bits when a vamsas document event is being handled.
1567 * true to hide gui, false to reveal gui
1569 public void setVamsasUpdate(boolean b)
1571 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
1572 + (b ? "in progress" : "finished"));
1574 if (vamUpdate != null)
1576 this.removeProgressPanel(vamUpdate);
1580 vamUpdate = this.addProgressPanel("Updating vamsas session");
1582 vamsasStart.setVisible(!b);
1583 vamsasStop.setVisible(!b);
1584 vamsasSave.setVisible(!b);
1587 public JInternalFrame[] getAllFrames()
1589 return desktop.getAllFrames();
1593 * Checks the given url to see if it gives a response indicating that the user
1594 * should be informed of a new questionnaire.
1598 public void checkForQuestionnaire(String url)
1600 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
1601 // javax.swing.SwingUtilities.invokeLater(jvq);
1602 new Thread(jvq).start();
1606 * Proxy class for JDesktopPane which optionally displays the current memory
1607 * usage and highlights the desktop area with a red bar if free memory runs
1612 public class MyDesktopPane extends JDesktopPane implements Runnable
1615 boolean showMemoryUsage = false;
1619 java.text.NumberFormat df;
1621 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
1624 public MyDesktopPane(boolean showMemoryUsage)
1626 showMemoryUsage(showMemoryUsage);
1629 public void showMemoryUsage(boolean showMemoryUsage)
1631 this.showMemoryUsage = showMemoryUsage;
1632 if (showMemoryUsage)
1634 Thread worker = new Thread(this);
1639 public boolean isShowMemoryUsage()
1641 return showMemoryUsage;
1646 df = java.text.NumberFormat.getNumberInstance();
1647 df.setMaximumFractionDigits(2);
1648 runtime = Runtime.getRuntime();
1650 while (showMemoryUsage)
1654 maxMemory = runtime.maxMemory() / 1048576f;
1655 allocatedMemory = runtime.totalMemory() / 1048576f;
1656 freeMemory = runtime.freeMemory() / 1048576f;
1657 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
1659 percentUsage = (totalFreeMemory / maxMemory) * 100;
1661 // if (percentUsage < 20)
1663 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
1665 // instance.set.setBorder(border1);
1668 // sleep after showing usage
1670 } catch (Exception ex)
1672 ex.printStackTrace();
1677 public void paintComponent(Graphics g)
1679 if (showMemoryUsage && g != null)
1681 if (percentUsage < 20)
1682 g.setColor(Color.red);
1683 FontMetrics fm = g.getFontMetrics();
1686 g.drawString("Total Free Memory: " + df.format(totalFreeMemory)
1687 + "MB; Max Memory: " + df.format(maxMemory) + "MB; "
1688 + df.format(percentUsage) + "%", 10, getHeight()
1696 protected JMenuItem groovyShell;
1698 public void doGroovyCheck()
1700 if (jalview.bin.Cache.groovyJarsPresent())
1702 groovyShell = new JMenuItem();
1703 groovyShell.setText("Groovy Console...");
1704 groovyShell.addActionListener(new ActionListener()
1706 public void actionPerformed(ActionEvent e)
1708 groovyShell_actionPerformed(e);
1711 toolsMenu.add(groovyShell);
1712 groovyShell.setVisible(true);
1717 * Accessor method to quickly get all the AlignmentFrames loaded.
1719 public static AlignFrame[] getAlignframes()
1721 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1727 Vector avp = new Vector();
1731 for (int i = frames.length - 1; i > -1; i--)
1733 if (frames[i] instanceof AlignFrame)
1735 AlignFrame af = (AlignFrame) frames[i];
1739 } catch (Exception ex)
1741 ex.printStackTrace();
1743 if (avp.size() == 0)
1747 AlignFrame afs[] = new AlignFrame[avp.size()];
1748 for (int i = 0, j = avp.size(); i < j; i++)
1750 afs[i] = (AlignFrame) avp.elementAt(i);
1757 * Add Groovy Support to Jalview
1759 public void groovyShell_actionPerformed(ActionEvent e)
1761 // use reflection to avoid creating compilation dependency.
1762 if (!jalview.bin.Cache.groovyJarsPresent())
1765 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
1769 Class gcClass = Desktop.class.getClassLoader().loadClass(
1770 "groovy.ui.Console");
1771 Constructor gccons = gcClass.getConstructor(null);
1772 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
1774 { String.class, Object.class });
1775 java.lang.reflect.Method run = gcClass.getMethod("run", null);
1776 Object gc = gccons.newInstance(null);
1777 setvar.invoke(gc, new Object[]
1778 { "Jalview", this });
1779 run.invoke(gc, null);
1780 } catch (Exception ex)
1782 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
1784 .showInternalMessageDialog(
1787 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
1788 "Jalview Groovy Support Failed",
1789 JOptionPane.ERROR_MESSAGE);
1794 * Progress bars managed by the IProgressIndicator method.
1796 private Hashtable progressBars, progressBarHandlers;
1801 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
1803 public void setProgressBar(String message, long id)
1805 if (progressBars == null)
1807 progressBars = new Hashtable();
1808 progressBarHandlers = new Hashtable();
1811 if (progressBars.get(new Long(id)) != null)
1813 JProgressBar progressPanel = (JProgressBar) progressBars
1814 .remove(new Long(id));
1815 if (progressBarHandlers.contains(new Long(id)))
1817 progressBarHandlers.remove(new Long(id));
1819 removeProgressPanel(progressPanel);
1823 progressBars.put(new Long(id), addProgressPanel(message));
1830 * @see jalview.gui.IProgressIndicator#registerHandler(long,
1831 * jalview.gui.IProgressIndicatorHandler)
1833 public void registerHandler(final long id,
1834 final IProgressIndicatorHandler handler)
1836 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
1839 "call setProgressBar before registering the progress bar's handler.");
1841 progressBarHandlers.put(new Long(id), handler);
1842 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
1843 if (handler.canCancel())
1845 JButton cancel = new JButton("Cancel");
1846 final IProgressIndicator us = this;
1847 cancel.addActionListener(new ActionListener()
1850 public void actionPerformed(ActionEvent e)
1852 handler.cancelActivity(id);
1853 us.setProgressBar("Cancelled "
1854 + ((JLabel) progressPanel.getComponent(0)).getText(), id);
1857 progressPanel.add(cancel, BorderLayout.EAST);
1862 * This will return the first AlignFrame viewing AlignViewport av. It will
1863 * break if there are more than one AlignFrames viewing a particular av. This
1866 * @return alignFrame for av
1868 public static AlignFrame getAlignFrameFor(AlignViewport av)
1870 if (desktop != null)
1872 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
1873 for (int panel = 0; aps != null && panel < aps.length; panel++)
1875 if (aps[panel] != null && aps[panel].av == av)
1877 return aps[panel].alignFrame;
1884 public VamsasApplication getVamsasApplication()
1890 public void startServiceDiscovery()
1893 new Thread(jalview.ws.jws2.Jws2Discoverer.getDiscoverer()).start();