2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, 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;
21 import jalview.io.FileLoader;
22 import jalview.io.FormatAdapter;
23 import jalview.io.IdentifyFile;
24 import jalview.io.JalviewFileChooser;
25 import jalview.io.JalviewFileView;
26 import jalview.ws.params.ParamManager;
28 import java.awt.BorderLayout;
29 import java.awt.Color;
30 import java.awt.Dimension;
31 import java.awt.FontMetrics;
32 import java.awt.Graphics;
33 import java.awt.GridLayout;
34 import java.awt.Point;
35 import java.awt.Rectangle;
36 import java.awt.Toolkit;
37 import java.awt.datatransfer.Clipboard;
38 import java.awt.datatransfer.ClipboardOwner;
39 import java.awt.datatransfer.DataFlavor;
40 import java.awt.datatransfer.Transferable;
41 import java.awt.dnd.DnDConstants;
42 import java.awt.dnd.DropTargetDragEvent;
43 import java.awt.dnd.DropTargetDropEvent;
44 import java.awt.dnd.DropTargetEvent;
45 import java.awt.dnd.DropTargetListener;
46 import java.awt.event.ActionEvent;
47 import java.awt.event.ActionListener;
48 import java.awt.event.FocusEvent;
49 import java.awt.event.FocusListener;
50 import java.awt.event.MouseAdapter;
51 import java.awt.event.MouseEvent;
52 import java.awt.event.MouseListener;
53 import java.awt.event.WindowAdapter;
54 import java.awt.event.WindowEvent;
55 import java.beans.PropertyChangeEvent;
56 import java.beans.PropertyChangeListener;
57 import java.beans.PropertyVetoException;
58 import java.io.BufferedInputStream;
60 import java.io.FileOutputStream;
61 import java.lang.reflect.Constructor;
63 import java.util.ArrayList;
64 import java.util.Hashtable;
65 import java.util.StringTokenizer;
66 import java.util.Vector;
68 import javax.swing.DefaultDesktopManager;
69 import javax.swing.DesktopManager;
70 import javax.swing.JButton;
71 import javax.swing.JComboBox;
72 import javax.swing.JComponent;
73 import javax.swing.JDesktopPane;
74 import javax.swing.JFrame;
75 import javax.swing.JInternalFrame;
76 import javax.swing.JLabel;
77 import javax.swing.JMenuItem;
78 import javax.swing.JOptionPane;
79 import javax.swing.JPanel;
80 import javax.swing.JPopupMenu;
81 import javax.swing.JProgressBar;
82 import javax.swing.SwingUtilities;
83 import javax.swing.event.HyperlinkEvent;
84 import javax.swing.event.MenuEvent;
85 import javax.swing.event.MenuListener;
86 import javax.swing.event.HyperlinkEvent.EventType;
93 * @version $Revision: 1.155 $
95 public class Desktop extends jalview.jbgui.GDesktop implements
96 DropTargetListener, ClipboardOwner, IProgressIndicator, jalview.api.StructureSelectionManagerProvider
99 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
102 * news reader - null if it was never started.
104 private BlogReader jvnews=null;
108 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
110 public void addJalviewPropertyChangeListener(
111 PropertyChangeListener listener)
113 changeSupport.addJalviewPropertyChangeListener(listener);
117 * @param propertyName
119 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
120 * java.beans.PropertyChangeListener)
122 public void addJalviewPropertyChangeListener(String propertyName,
123 PropertyChangeListener listener)
125 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
129 * @param propertyName
131 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
132 * java.beans.PropertyChangeListener)
134 public void removeJalviewPropertyChangeListener(String propertyName,
135 PropertyChangeListener listener)
137 changeSupport.removeJalviewPropertyChangeListener(propertyName,
141 /** Singleton Desktop instance */
142 public static Desktop instance;
144 public static MyDesktopPane desktop;
146 static int openFrameCount = 0;
148 static final int xOffset = 30;
150 static final int yOffset = 30;
152 public static jalview.ws.jws1.Discoverer discoverer;
154 public static Object[] jalviewClipboard;
156 public static boolean internalCopy = false;
158 static int fileLoadingCount = 0;
160 class MyDesktopManager implements DesktopManager
163 private DesktopManager delegate;
165 public MyDesktopManager(DesktopManager delegate)
167 this.delegate = delegate;
170 public void activateFrame(JInternalFrame f)
174 delegate.activateFrame(f);
175 } catch (NullPointerException npe)
177 Point p = getMousePosition();
178 instance.showPasteMenu(p.x, p.y);
182 public void beginDraggingFrame(JComponent f)
184 delegate.beginDraggingFrame(f);
187 public void beginResizingFrame(JComponent f, int direction)
189 delegate.beginResizingFrame(f, direction);
192 public void closeFrame(JInternalFrame f)
194 delegate.closeFrame(f);
197 public void deactivateFrame(JInternalFrame f)
199 delegate.deactivateFrame(f);
202 public void deiconifyFrame(JInternalFrame f)
204 delegate.deiconifyFrame(f);
207 public void dragFrame(JComponent f, int newX, int newY)
213 delegate.dragFrame(f, newX, newY);
216 public void endDraggingFrame(JComponent f)
218 delegate.endDraggingFrame(f);
221 public void endResizingFrame(JComponent f)
223 delegate.endResizingFrame(f);
226 public void iconifyFrame(JInternalFrame f)
228 delegate.iconifyFrame(f);
231 public void maximizeFrame(JInternalFrame f)
233 delegate.maximizeFrame(f);
236 public void minimizeFrame(JInternalFrame f)
238 delegate.minimizeFrame(f);
241 public void openFrame(JInternalFrame f)
243 delegate.openFrame(f);
246 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
249 Rectangle b=desktop.getBounds();
254 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
257 public void setBoundsForFrame(JComponent f, int newX, int newY,
258 int newWidth, int newHeight)
260 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
263 // All other methods, simply delegate
268 * Creates a new Desktop object.
273 * A note to implementors. It is ESSENTIAL that any activities that might
274 * block are spawned off as threads rather than waited for during this
278 doVamsasClientCheck();
281 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
282 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
283 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
285 boolean showjconsole = jalview.bin.Cache.getDefault(
286 "SHOW_JAVA_CONSOLE", false);
287 desktop = new MyDesktopPane(selmemusage);
288 showMemusage.setSelected(selmemusage);
289 desktop.setBackground(Color.white);
290 getContentPane().setLayout(new BorderLayout());
291 // alternate config - have scrollbars - see notes in JAL-153
292 //JScrollPane sp = new JScrollPane();
293 //sp.getViewport().setView(desktop);
294 //getContentPane().add(sp, BorderLayout.CENTER);
295 getContentPane().add(desktop, BorderLayout.CENTER);
296 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
299 // This line prevents Windows Look&Feel resizing all new windows to maximum
300 // if previous window was maximised
301 desktop.setDesktopManager(new MyDesktopManager(
302 new DefaultDesktopManager()));
304 Rectangle dims = getLastKnownDimensions("");
311 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
312 setBounds((int) (screenSize.width - 900) / 2,
313 (int) (screenSize.height - 650) / 2, 900, 650);
315 jconsole = new Console(this, showjconsole);
316 // add essential build information
317 jconsole.setHeader("Jalview Desktop "
318 + jalview.bin.Cache.getProperty("VERSION") + "\n"
320 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
321 + "Java version: " + System.getProperty("java.version") + "\n"
322 + System.getProperty("os.arch") + " "
323 + System.getProperty("os.name") + " "
324 + System.getProperty("os.version"));
326 showConsole(showjconsole);
328 showNews.setVisible(false);
329 final Desktop me = this;
330 // Thread off the news reader, in case there are connection problems.
331 new Thread( new Runnable() {
335 Cache.log.debug("Starting news thread.");
337 jvnews = new BlogReader(me);
338 showNews.setVisible(true);
339 Cache.log.debug("Completed news thread.");
343 this.addWindowListener(new WindowAdapter()
345 public void windowClosing(WindowEvent evt)
352 this.addMouseListener(ma=new MouseAdapter()
354 public void mousePressed(MouseEvent evt)
356 if (SwingUtilities.isRightMouseButton(evt))
358 showPasteMenu(evt.getX(), evt.getY());
362 desktop.addMouseListener(ma);
364 this.addFocusListener(new FocusListener()
368 public void focusLost(FocusEvent e)
370 // TODO Auto-generated method stub
375 public void focusGained(FocusEvent e)
377 Cache.log.debug("Relaying windows after focus gain");
378 // make sure that we sort windows properly after we gain focus
379 instance.relayerWindows();
382 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
383 // Spawn a thread that shows the splashscreen
384 SwingUtilities.invokeLater(new Runnable()
393 // Thread off a new instance of the file chooser - this reduces the time it
394 // takes to open it later on.
395 new Thread(new Runnable()
399 Cache.log.debug("Filechooser init thread started.");
400 JalviewFileChooser chooser = new JalviewFileChooser(
401 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
402 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
403 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
404 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
405 Cache.log.debug("Filechooser init thread finished.");
408 // Add the service change listener
409 changeSupport.addJalviewPropertyChangeListener("services",
410 new PropertyChangeListener()
414 public void propertyChange(PropertyChangeEvent evt)
416 Cache.log.debug("Firing service changed event for "
417 + evt.getNewValue());
418 JalviewServicesChanged(evt);
424 protected void showNews_actionPerformed(ActionEvent e)
426 showNews(showNews.isSelected());
428 void showNews(boolean visible)
431 Cache.log.debug((visible?"Showing":"Hiding")+" news.");
432 showNews.setSelected(visible);
433 if (visible && !jvnews.isVisible())
435 new Thread(new Runnable() {
439 long instance=System.currentTimeMillis();
440 Desktop.instance.setProgressBar("Refreshing news", instance);
441 jvnews.refreshNews();
442 Desktop.instance.setProgressBar(null, instance);
451 * recover the last known dimensions for a jalview window
454 * - empty string is desktop, all other windows have unique prefix
455 * @return null or last known dimensions scaled to current geometry (if last
456 * window geom was known)
458 Rectangle getLastKnownDimensions(String windowName)
460 // TODO: lock aspect ratio for scaling desktop Bug #0058199
461 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
462 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
463 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
464 String width = jalview.bin.Cache.getProperty(windowName
466 String height = jalview.bin.Cache.getProperty(windowName
468 if ((x != null) && (y != null) && (width != null) && (height != null))
470 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
471 .parseInt(width), ih = Integer.parseInt(height);
472 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
474 // attempt #1 - try to cope with change in screen geometry - this
475 // version doesn't preserve original jv aspect ratio.
476 // take ratio of current screen size vs original screen size.
477 double sw = ((1f * screenSize.width) / (1f * Integer
478 .parseInt(jalview.bin.Cache
479 .getProperty("SCREENGEOMETRY_WIDTH"))));
480 double sh = ((1f * screenSize.height) / (1f * Integer
481 .parseInt(jalview.bin.Cache
482 .getProperty("SCREENGEOMETRY_HEIGHT"))));
483 // rescale the bounds depending upon the current screen geometry.
484 ix = (int) (ix * sw);
485 iw = (int) (iw * sw);
486 iy = (int) (iy * sh);
487 ih = (int) (ih * sh);
488 while (ix >= screenSize.width)
490 jalview.bin.Cache.log
491 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
492 ix -= screenSize.width;
494 while (iy >= screenSize.height)
496 jalview.bin.Cache.log
497 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
498 iy -= screenSize.height;
500 jalview.bin.Cache.log.debug("Got last known dimensions for "
501 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
504 // return dimensions for new instance
505 return new Rectangle(ix, iy, iw, ih);
510 private void doVamsasClientCheck()
512 if (jalview.bin.Cache.vamsasJarsPresent())
514 setupVamsasDisconnectedGui();
515 VamsasMenu.setVisible(true);
516 final Desktop us = this;
517 VamsasMenu.addMenuListener(new MenuListener()
519 // this listener remembers when the menu was first selected, and
520 // doesn't rebuild the session list until it has been cleared and
522 boolean refresh = true;
524 public void menuCanceled(MenuEvent e)
529 public void menuDeselected(MenuEvent e)
534 public void menuSelected(MenuEvent e)
538 us.buildVamsasStMenu();
543 vamsasStart.setVisible(true);
547 void showPasteMenu(int x, int y)
549 JPopupMenu popup = new JPopupMenu();
550 JMenuItem item = new JMenuItem("Paste To New Window");
551 item.addActionListener(new ActionListener()
553 public void actionPerformed(ActionEvent evt)
560 popup.show(this, x, y);
567 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
568 Transferable contents = c.getContents(this);
570 if (contents != null)
572 String file = (String) contents
573 .getTransferData(DataFlavor.stringFlavor);
575 String format = new IdentifyFile().Identify(file,
576 FormatAdapter.PASTE);
578 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
581 } catch (Exception ex)
584 .println("Unable to paste alignment from system clipboard:\n"
590 * Adds and opens the given frame to the desktop
601 public static synchronized void addInternalFrame(
602 final JInternalFrame frame, String title, int w, int h)
604 addInternalFrame(frame, title, w, h, true);
621 public static synchronized void addInternalFrame(
622 final JInternalFrame frame, String title, int w, int h,
626 // TODO: allow callers to determine X and Y position of frame (eg. via
628 // TODO: consider fixing method to update entries in the window submenu with
629 // the current window title
631 frame.setTitle(title);
632 if (frame.getWidth() < 1 || frame.getHeight() < 1)
636 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
637 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
638 // IF JALVIEW IS RUNNING HEADLESS
639 // ///////////////////////////////////////////////
640 if (System.getProperty("java.awt.headless") != null
641 && System.getProperty("java.awt.headless").equals("true"))
648 frame.setVisible(true);
649 frame.setClosable(true);
650 frame.setResizable(resizable);
651 frame.setMaximizable(resizable);
652 frame.setIconifiable(resizable);
653 frame.setFrameIcon(null);
655 if (frame.getX() < 1 && frame.getY() < 1)
657 frame.setLocation(xOffset * openFrameCount, yOffset
658 * ((openFrameCount - 1) % 10) + yOffset);
661 final JMenuItem menuItem = new JMenuItem(title);
662 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
664 public void internalFrameActivated(
665 javax.swing.event.InternalFrameEvent evt)
667 JInternalFrame itf = desktop.getSelectedFrame();
675 public void internalFrameClosed(
676 javax.swing.event.InternalFrameEvent evt)
678 PaintRefresher.RemoveComponent(frame);
680 windowMenu.remove(menuItem);
681 JInternalFrame itf = desktop.getSelectedFrame();
690 menuItem.addActionListener(new ActionListener()
692 public void actionPerformed(ActionEvent e)
696 frame.setSelected(true);
697 frame.setIcon(false);
698 } catch (java.beans.PropertyVetoException ex)
704 menuItem.addMouseListener(new MouseListener()
708 public void mouseReleased(MouseEvent e)
713 public void mousePressed(MouseEvent e)
718 public void mouseExited(MouseEvent e)
722 frame.setSelected(false);
723 } catch (PropertyVetoException e1)
729 public void mouseEntered(MouseEvent e)
733 frame.setSelected(true);
734 } catch (PropertyVetoException e1)
740 public void mouseClicked(MouseEvent e)
746 windowMenu.add(menuItem);
752 frame.setSelected(true);
753 frame.requestFocus();
754 } catch (java.beans.PropertyVetoException ve)
757 catch (java.lang.ClassCastException cex)
759 Cache.log.warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",cex);
763 public void lostOwnership(Clipboard clipboard, Transferable contents)
767 Desktop.jalviewClipboard = null;
770 internalCopy = false;
773 public void dragEnter(DropTargetDragEvent evt)
777 public void dragExit(DropTargetEvent evt)
781 public void dragOver(DropTargetDragEvent evt)
785 public void dropActionChanged(DropTargetDragEvent evt)
795 public void drop(DropTargetDropEvent evt)
797 Transferable t = evt.getTransferable();
798 java.util.List files = null;
799 java.util.List protocols = null;
803 DataFlavor uriListFlavor = new DataFlavor(
804 "text/uri-list;class=java.lang.String");
805 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
807 // Works on Windows and MacOSX
808 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
809 files = (java.util.List) t
810 .getTransferData(DataFlavor.javaFileListFlavor);
812 else if (t.isDataFlavorSupported(uriListFlavor))
814 // This is used by Unix drag system
815 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
816 String data = (String) t.getTransferData(uriListFlavor);
817 files = new java.util.ArrayList(1);
818 protocols = new java.util.ArrayList(1);
819 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
820 data, "\r\n"); st.hasMoreTokens();)
822 String s = st.nextToken();
823 if (s.startsWith("#"))
825 // the line is a comment (as per the RFC 2483)
828 java.net.URI uri = new java.net.URI(s);
829 if (uri.getScheme().toLowerCase().startsWith("http"))
831 protocols.add(FormatAdapter.URL);
832 files.add(uri.toString());
836 // otherwise preserve old behaviour: catch all for file objects
837 java.io.File file = new java.io.File(uri);
838 protocols.add(FormatAdapter.FILE);
839 files.add(file.toString());
843 } catch (Exception e)
851 for (int i = 0; i < files.size(); i++)
853 String file = files.get(i).toString();
854 String protocol = (protocols == null) ? FormatAdapter.FILE
855 : (String) protocols.get(i);
856 String format = null;
858 if (file.endsWith(".jar"))
865 format = new IdentifyFile().Identify(file, protocol);
868 new FileLoader().LoadFile(file, protocol, format);
871 } catch (Exception ex)
883 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
885 JalviewFileChooser chooser = new JalviewFileChooser(
886 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
887 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
888 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
889 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
891 chooser.setFileView(new JalviewFileView());
892 chooser.setDialogTitle("Open local file");
893 chooser.setToolTipText("Open");
895 int value = chooser.showOpenDialog(this);
897 if (value == JalviewFileChooser.APPROVE_OPTION)
899 String choice = chooser.getSelectedFile().getPath();
900 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
901 .getSelectedFile().getParent());
903 String format = null;
904 if (chooser.getSelectedFormat().equals("Jalview"))
910 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
913 if (viewport != null)
915 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
920 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
931 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
933 // This construct allows us to have a wider textfield
935 JLabel label = new JLabel("Enter URL of Input File");
936 final JComboBox history = new JComboBox();
938 JPanel panel = new JPanel(new GridLayout(2, 1));
941 history.setPreferredSize(new Dimension(400, 20));
942 history.setEditable(true);
943 history.addItem("http://www.");
945 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
949 if (historyItems != null)
951 st = new StringTokenizer(historyItems, "\t");
953 while (st.hasMoreTokens())
955 history.addItem(st.nextElement());
959 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
960 "Input Alignment From URL", JOptionPane.OK_CANCEL_OPTION);
962 if (reply != JOptionPane.OK_OPTION)
967 String url = history.getSelectedItem().toString();
969 if (url.toLowerCase().endsWith(".jar"))
971 if (viewport != null)
973 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
978 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
983 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
985 if (format.equals("URL NOT FOUND"))
987 JOptionPane.showInternalMessageDialog(Desktop.desktop,
988 "Couldn't locate " + url, "URL not found",
989 JOptionPane.WARNING_MESSAGE);
994 if (viewport != null)
996 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1000 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1011 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1013 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1014 cap.setForInput(viewport);
1015 Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
1023 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1025 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1026 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1028 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1029 getBounds().y, getWidth(), getHeight()));
1031 if (jconsole != null)
1033 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1034 jconsole.stopConsole();
1038 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1045 private void storeLastKnownDimensions(String string, Rectangle jc)
1047 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1048 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1049 + " height:" + jc.height);
1051 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1052 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1053 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1054 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1063 public void aboutMenuItem_actionPerformed(ActionEvent e)
1065 StringBuffer message = getAboutMessage(false);
1066 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1068 message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1071 public StringBuffer getAboutMessage(boolean shortv)
1073 StringBuffer message = new StringBuffer();
1074 message.append("<html>");
1077 message.append("<h1><strong>Version: "
1078 + jalview.bin.Cache.getProperty("VERSION")
1079 + "</strong></h1><br>");
1080 message.append("<strong>Last Updated: <em>"
1081 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1082 + "</em></strong>");
1088 message.append("<strong>Version "
1089 + jalview.bin.Cache.getProperty("VERSION")
1090 + "; last updated: "
1091 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1094 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1097 message.append("<br>...Checking latest version...</br>");
1099 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1100 .equals(jalview.bin.Cache.getProperty("VERSION")))
1102 boolean red = false;
1103 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1104 .indexOf("automated build") == -1)
1107 // Displayed when code version and jnlp version do not match and code
1108 // version is not a development build
1109 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1112 message.append("<br>!! Version "
1113 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1115 + " is available for download from "
1116 + jalview.bin.Cache.getDefault("www.jalview.org",
1117 "http://www.jalview.org") + " !!");
1120 message.append("</div>");
1123 message.append("<br>Authors: "
1127 "Jim Procter, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton")
1128 + "<br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1129 + "<br>For help, see the FAQ at <a href=\"http://www.jalview.org\">www.jalview.org</a> and/or join the jalview-discuss@jalview.org mailing list"
1130 + "<br>If you use Jalview, please cite:"
1131 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1132 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1133 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1144 public void documentationMenuItem_actionPerformed(ActionEvent e)
1148 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
1149 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
1150 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
1152 javax.help.HelpBroker hb = hs.createHelpBroker();
1153 hb.setCurrentID("home");
1154 hb.setDisplayed(true);
1155 } catch (Exception ex)
1160 public void closeAll_actionPerformed(ActionEvent e)
1162 JInternalFrame[] frames = desktop.getAllFrames();
1163 for (int i = 0; i < frames.length; i++)
1167 frames[i].setClosed(true);
1168 } catch (java.beans.PropertyVetoException ex)
1172 System.out.println("ALL CLOSED");
1173 if (v_client != null)
1175 // TODO clear binding to vamsas document objects on close_all
1180 public void raiseRelated_actionPerformed(ActionEvent e)
1182 reorderAssociatedWindows(false, false);
1185 public void minimizeAssociated_actionPerformed(ActionEvent e)
1187 reorderAssociatedWindows(true, false);
1190 void closeAssociatedWindows()
1192 reorderAssociatedWindows(false, true);
1198 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1201 protected void garbageCollect_actionPerformed(ActionEvent e)
1203 // We simply collect the garbage
1204 jalview.bin.Cache.log.debug("Collecting garbage...");
1206 jalview.bin.Cache.log.debug("Finished garbage collection.");
1213 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1216 protected void showMemusage_actionPerformed(ActionEvent e)
1218 desktop.showMemoryUsage(showMemusage.isSelected());
1225 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1228 protected void showConsole_actionPerformed(ActionEvent e)
1230 showConsole(showConsole.isSelected());
1233 Console jconsole = null;
1236 * control whether the java console is visible or not
1240 void showConsole(boolean selected)
1242 showConsole.setSelected(selected);
1243 // TODO: decide if we should update properties file
1244 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1246 jconsole.setVisible(selected);
1249 void reorderAssociatedWindows(boolean minimize, boolean close)
1251 JInternalFrame[] frames = desktop.getAllFrames();
1252 if (frames == null || frames.length < 1)
1257 AlignViewport source = null, target = null;
1258 if (frames[0] instanceof AlignFrame)
1260 source = ((AlignFrame) frames[0]).getCurrentView();
1262 else if (frames[0] instanceof TreePanel)
1264 source = ((TreePanel) frames[0]).getViewPort();
1266 else if (frames[0] instanceof PCAPanel)
1268 source = ((PCAPanel) frames[0]).av;
1270 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1272 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1277 for (int i = 0; i < frames.length; i++)
1280 if (frames[i] == null)
1284 if (frames[i] instanceof AlignFrame)
1286 target = ((AlignFrame) frames[i]).getCurrentView();
1288 else if (frames[i] instanceof TreePanel)
1290 target = ((TreePanel) frames[i]).getViewPort();
1292 else if (frames[i] instanceof PCAPanel)
1294 target = ((PCAPanel) frames[i]).av;
1296 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1298 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1301 if (source == target)
1307 frames[i].setClosed(true);
1311 frames[i].setIcon(minimize);
1314 frames[i].toFront();
1318 } catch (java.beans.PropertyVetoException ex)
1332 protected void preferences_actionPerformed(ActionEvent e)
1343 public void saveState_actionPerformed(ActionEvent e)
1345 JalviewFileChooser chooser = new JalviewFileChooser(
1346 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1347 { "jar" }, new String[]
1348 { "Jalview Project" }, "Jalview Project");
1350 chooser.setFileView(new JalviewFileView());
1351 chooser.setDialogTitle("Save State");
1353 int value = chooser.showSaveDialog(this);
1355 if (value == JalviewFileChooser.APPROVE_OPTION)
1357 final Desktop me = this;
1358 final java.io.File choice = chooser.getSelectedFile();
1359 new Thread(new Runnable()
1364 setProgressBar("Saving jalview project " + choice.getName(),
1366 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1367 // TODO catch and handle errors for savestate
1368 // TODO prevent user from messing with the Desktop whilst we're saving
1371 new Jalview2XML().SaveState(choice);
1372 } catch (OutOfMemoryError oom)
1375 "Whilst saving current state to " + choice.getName(), oom);
1376 } catch (Exception ex)
1379 .error("Problems whilst trying to save to "
1380 + choice.getName(), ex);
1381 JOptionPane.showMessageDialog(me,
1382 "Error whilst saving current state to " + choice.getName(),
1383 "Couldn't save project", JOptionPane.WARNING_MESSAGE);
1385 setProgressBar(null, choice.hashCode());
1397 public void loadState_actionPerformed(ActionEvent e)
1399 JalviewFileChooser chooser = new JalviewFileChooser(
1400 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1401 { "jar" }, new String[]
1402 { "Jalview Project" }, "Jalview Project");
1403 chooser.setFileView(new JalviewFileView());
1404 chooser.setDialogTitle("Restore state");
1406 int value = chooser.showOpenDialog(this);
1408 if (value == JalviewFileChooser.APPROVE_OPTION)
1410 final String choice = chooser.getSelectedFile().getAbsolutePath();
1411 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1412 .getSelectedFile().getParent());
1413 new Thread(new Runnable()
1417 setProgressBar("loading jalview project " + choice,
1421 new Jalview2XML().LoadJalviewAlign(choice);
1422 } catch (OutOfMemoryError oom)
1424 new OOMWarning("Whilst loading project from " + choice, oom);
1425 } catch (Exception ex)
1427 Cache.log.error("Problems whilst loading project from "
1429 JOptionPane.showMessageDialog(Desktop.desktop,
1430 "Error whilst loading project from " + choice,
1431 "Couldn't load project", JOptionPane.WARNING_MESSAGE);
1433 setProgressBar(null, choice.hashCode());
1439 public void inputSequence_actionPerformed(ActionEvent e)
1441 new SequenceFetcher(this);
1444 JPanel progressPanel;
1445 ArrayList<JPanel> fileLoadingPanels=new ArrayList<JPanel>();
1446 public void startLoading(final String fileName)
1448 if (fileLoadingCount == 0)
1450 fileLoadingPanels.add(addProgressPanel("Loading File: " + fileName + " "));
1455 private JPanel addProgressPanel(String string)
1457 if (progressPanel == null)
1459 progressPanel = new JPanel(new GridLayout(1,1));
1460 totalProgressCount = 0;
1461 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1463 JPanel thisprogress=new JPanel(new BorderLayout(10,5));
1464 JProgressBar progressBar = new JProgressBar();
1465 progressBar.setIndeterminate(true);
1467 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1469 thisprogress.add(progressBar, BorderLayout.CENTER);
1470 progressPanel.add(thisprogress);
1471 ((GridLayout)progressPanel.getLayout()).setRows(((GridLayout)progressPanel.getLayout()).getRows()+1);
1472 ++totalProgressCount;
1473 instance.validate();
1474 return thisprogress;
1477 int totalProgressCount = 0;
1479 private void removeProgressPanel(JPanel progbar)
1481 if (progressPanel != null)
1483 progressPanel.remove(progbar);
1484 GridLayout gl = (GridLayout) progressPanel.getLayout();
1485 gl.setRows(gl.getRows()-1);
1486 if (--totalProgressCount < 1)
1488 this.getContentPane().remove(progressPanel);
1489 progressPanel = null;
1495 public void stopLoading()
1498 if (fileLoadingCount < 1)
1500 for (JPanel flp : fileLoadingPanels)
1502 removeProgressPanel(flp);
1504 fileLoadingPanels.clear();
1505 fileLoadingCount = 0;
1510 public static int getViewCount(String alignmentId)
1512 AlignViewport[] aps = getViewports(alignmentId);
1513 return (aps == null) ? 0 : aps.length;
1518 * @param alignmentId
1519 * @return all AlignmentPanels concerning the alignmentId sequence set
1521 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1524 if (Desktop.desktop == null)
1526 // no frames created and in headless mode
1527 // TODO: verify that frames are recoverable when in headless mode
1530 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1531 ArrayList aps = new ArrayList();
1532 for (int t = 0; t < frames.length; t++)
1534 if (frames[t] instanceof AlignFrame)
1536 AlignFrame af = (AlignFrame) frames[t];
1537 for (int a = 0; a < af.alignPanels.size(); a++)
1540 .equals(((AlignmentPanel) af.alignPanels.elementAt(a)).av
1541 .getSequenceSetId()))
1543 aps.add(af.alignPanels.elementAt(a));
1548 if (aps.size() == 0)
1552 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1553 for (int t = 0; t < vap.length; t++)
1555 vap[t] = (AlignmentPanel) aps.get(t);
1561 * get all the viewports on an alignment.
1563 * @param sequenceSetId
1564 * unique alignment id
1565 * @return all viewports on the alignment bound to sequenceSetId
1567 public static AlignViewport[] getViewports(String sequenceSetId)
1569 Vector viewp = new Vector();
1570 if (desktop != null)
1572 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1574 for (int t = 0; t < frames.length; t++)
1576 if (frames[t] instanceof AlignFrame)
1578 AlignFrame afr = ((AlignFrame) frames[t]);
1579 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1581 if (afr.alignPanels != null)
1583 for (int a = 0; a < afr.alignPanels.size(); a++)
1585 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1586 .elementAt(a)).av.getSequenceSetId()))
1588 viewp.addElement(((AlignmentPanel) afr.alignPanels
1595 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1600 if (viewp.size() > 0)
1602 AlignViewport[] vp = new AlignViewport[viewp.size()];
1610 public void explodeViews(AlignFrame af)
1612 int size = af.alignPanels.size();
1618 for (int i = 0; i < size; i++)
1620 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1621 AlignFrame newaf = new AlignFrame(ap);
1622 if (ap.av.explodedPosition != null
1623 && !ap.av.explodedPosition.equals(af.getBounds()))
1625 newaf.setBounds(ap.av.explodedPosition);
1628 ap.av.gatherViewsHere = false;
1630 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1631 AlignFrame.DEFAULT_HEIGHT);
1634 af.alignPanels.clear();
1635 af.closeMenuItem_actionPerformed(true);
1639 public void gatherViews(AlignFrame source)
1641 source.viewport.gatherViewsHere = true;
1642 source.viewport.explodedPosition = source.getBounds();
1643 JInternalFrame[] frames = desktop.getAllFrames();
1644 String viewId = source.viewport.getSequenceSetId();
1646 for (int t = 0; t < frames.length; t++)
1648 if (frames[t] instanceof AlignFrame && frames[t] != source)
1650 AlignFrame af = (AlignFrame) frames[t];
1651 boolean gatherThis = false;
1652 for (int a = 0; a < af.alignPanels.size(); a++)
1654 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1655 if (viewId.equals(ap.av.getSequenceSetId()))
1658 ap.av.gatherViewsHere = false;
1659 ap.av.explodedPosition = af.getBounds();
1660 source.addAlignmentPanel(ap, false);
1666 af.alignPanels.clear();
1667 af.closeMenuItem_actionPerformed(true);
1674 jalview.gui.VamsasApplication v_client = null;
1676 public void vamsasImport_actionPerformed(ActionEvent e)
1678 if (v_client == null)
1680 // Load and try to start a session.
1681 JalviewFileChooser chooser = new JalviewFileChooser(
1682 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1684 chooser.setFileView(new JalviewFileView());
1685 chooser.setDialogTitle("Open a saved VAMSAS session");
1686 chooser.setToolTipText("select a vamsas session to be opened as a new vamsas session.");
1688 int value = chooser.showOpenDialog(this);
1690 if (value == JalviewFileChooser.APPROVE_OPTION)
1692 String fle = chooser.getSelectedFile().toString();
1693 if (!vamsasImport(chooser.getSelectedFile()))
1695 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1696 "Couldn't import '" + fle + "' as a new vamsas session.",
1697 "Vamsas Document Import Failed",
1698 JOptionPane.ERROR_MESSAGE);
1704 jalview.bin.Cache.log
1705 .error("Implementation error - load session from a running session is not supported.");
1710 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1713 * @return true if import was a success and a session was started.
1715 public boolean vamsasImport(URL url)
1717 // TODO: create progress bar
1718 if (v_client != null)
1721 jalview.bin.Cache.log
1722 .error("Implementation error - load session from a running session is not supported.");
1728 // copy the URL content to a temporary local file
1729 // TODO: be a bit cleverer here with nio (?!)
1730 File file = File.createTempFile("vdocfromurl", ".vdj");
1731 FileOutputStream fos = new FileOutputStream(file);
1732 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1733 byte[] buffer = new byte[2048];
1735 while ((ln = bis.read(buffer)) > -1)
1737 fos.write(buffer, 0, ln);
1741 v_client = new jalview.gui.VamsasApplication(this, file,
1742 url.toExternalForm());
1743 } catch (Exception ex)
1745 jalview.bin.Cache.log.error(
1746 "Failed to create new vamsas session from contents of URL "
1750 setupVamsasConnectedGui();
1751 v_client.initial_update(); // TODO: thread ?
1752 return v_client.inSession();
1756 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1759 * @return true if import was a success and a session was started.
1761 public boolean vamsasImport(File file)
1763 if (v_client != null)
1766 jalview.bin.Cache.log
1767 .error("Implementation error - load session from a running session is not supported.");
1771 setProgressBar("Importing VAMSAS session from " + file.getName(),
1775 v_client = new jalview.gui.VamsasApplication(this, file, null);
1776 } catch (Exception ex)
1778 setProgressBar("Importing VAMSAS session from " + file.getName(),
1780 jalview.bin.Cache.log.error(
1781 "New vamsas session from existing session file failed:", ex);
1784 setupVamsasConnectedGui();
1785 v_client.initial_update(); // TODO: thread ?
1786 setProgressBar("Importing VAMSAS session from " + file.getName(),
1788 return v_client.inSession();
1791 public boolean joinVamsasSession(String mysesid)
1793 if (v_client != null)
1796 "Trying to join a vamsas session when another is already connected.");
1798 if (mysesid == null)
1800 throw new Error("Invalid vamsas session id.");
1802 v_client = new VamsasApplication(this, mysesid);
1803 setupVamsasConnectedGui();
1804 v_client.initial_update();
1805 return (v_client.inSession());
1808 public void vamsasStart_actionPerformed(ActionEvent e)
1810 if (v_client == null)
1813 // we just start a default session for moment.
1815 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1816 * getProperty("LAST_DIRECTORY"));
1818 * chooser.setFileView(new JalviewFileView());
1819 * chooser.setDialogTitle("Load Vamsas file");
1820 * chooser.setToolTipText("Import");
1822 * int value = chooser.showOpenDialog(this);
1824 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1825 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1827 v_client = new VamsasApplication(this);
1828 setupVamsasConnectedGui();
1829 v_client.initial_update(); // TODO: thread ?
1833 // store current data in session.
1834 v_client.push_update(); // TODO: thread
1838 protected void setupVamsasConnectedGui()
1840 vamsasStart.setText("Session Update");
1841 vamsasSave.setVisible(true);
1842 vamsasStop.setVisible(true);
1843 vamsasImport.setVisible(false); // Document import to existing session is
1844 // not possible for vamsas-client-1.0.
1847 protected void setupVamsasDisconnectedGui()
1849 vamsasSave.setVisible(false);
1850 vamsasStop.setVisible(false);
1851 vamsasImport.setVisible(true);
1852 vamsasStart.setText("New Vamsas Session");
1855 public void vamsasStop_actionPerformed(ActionEvent e)
1857 if (v_client != null)
1859 v_client.end_session();
1861 setupVamsasDisconnectedGui();
1865 protected void buildVamsasStMenu()
1867 if (v_client == null)
1869 String[] sess = null;
1872 sess = VamsasApplication.getSessionList();
1873 } catch (Exception e)
1875 jalview.bin.Cache.log.warn(
1876 "Problem getting current sessions list.", e);
1881 jalview.bin.Cache.log.debug("Got current sessions list: "
1882 + sess.length + " entries.");
1883 VamsasStMenu.removeAll();
1884 for (int i = 0; i < sess.length; i++)
1886 JMenuItem sessit = new JMenuItem();
1887 sessit.setText(sess[i]);
1888 sessit.setToolTipText("Connect to session " + sess[i]);
1889 final Desktop dsktp = this;
1890 final String mysesid = sess[i];
1891 sessit.addActionListener(new ActionListener()
1894 public void actionPerformed(ActionEvent e)
1896 if (dsktp.v_client == null)
1898 Thread rthr = new Thread(new Runnable()
1903 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1904 dsktp.setupVamsasConnectedGui();
1905 dsktp.v_client.initial_update();
1913 VamsasStMenu.add(sessit);
1915 // don't show an empty menu.
1916 VamsasStMenu.setVisible(sess.length > 0);
1921 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1922 VamsasStMenu.removeAll();
1923 VamsasStMenu.setVisible(false);
1928 // Not interested in the content. Just hide ourselves.
1929 VamsasStMenu.setVisible(false);
1933 public void vamsasSave_actionPerformed(ActionEvent e)
1935 if (v_client != null)
1937 JalviewFileChooser chooser = new JalviewFileChooser(
1938 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1939 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1941 { "Vamsas Document" }, "Vamsas Document");
1943 chooser.setFileView(new JalviewFileView());
1944 chooser.setDialogTitle("Save Vamsas Document Archive");
1946 int value = chooser.showSaveDialog(this);
1948 if (value == JalviewFileChooser.APPROVE_OPTION)
1950 java.io.File choice = chooser.getSelectedFile();
1951 JPanel progpanel = addProgressPanel("Saving VAMSAS Document to "
1952 + choice.getName());
1953 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1954 String warnmsg = null;
1955 String warnttl = null;
1958 v_client.vclient.storeDocument(choice);
1961 warnttl = "Serious Problem saving Vamsas Document";
1962 warnmsg = ex.toString();
1963 jalview.bin.Cache.log.error("Error Whilst saving document to "
1966 } catch (Exception ex)
1968 warnttl = "Problem saving Vamsas Document.";
1969 warnmsg = ex.toString();
1970 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
1974 removeProgressPanel(progpanel);
1975 if (warnmsg != null)
1977 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1979 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
1985 JPanel vamUpdate = null;
1988 * hide vamsas user gui bits when a vamsas document event is being handled.
1991 * true to hide gui, false to reveal gui
1993 public void setVamsasUpdate(boolean b)
1995 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
1996 + (b ? "in progress" : "finished"));
1998 if (vamUpdate != null)
2000 this.removeProgressPanel(vamUpdate);
2004 vamUpdate = this.addProgressPanel("Updating vamsas session");
2006 vamsasStart.setVisible(!b);
2007 vamsasStop.setVisible(!b);
2008 vamsasSave.setVisible(!b);
2011 public JInternalFrame[] getAllFrames()
2013 return desktop.getAllFrames();
2017 * Checks the given url to see if it gives a response indicating that the user
2018 * should be informed of a new questionnaire.
2022 public void checkForQuestionnaire(String url)
2024 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2025 // javax.swing.SwingUtilities.invokeLater(jvq);
2026 new Thread(jvq).start();
2030 * Proxy class for JDesktopPane which optionally displays the current memory
2031 * usage and highlights the desktop area with a red bar if free memory runs
2036 public class MyDesktopPane extends JDesktopPane implements Runnable
2039 boolean showMemoryUsage = false;
2043 java.text.NumberFormat df;
2045 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2048 public MyDesktopPane(boolean showMemoryUsage)
2050 showMemoryUsage(showMemoryUsage);
2053 public void showMemoryUsage(boolean showMemoryUsage)
2055 this.showMemoryUsage = showMemoryUsage;
2056 if (showMemoryUsage)
2058 Thread worker = new Thread(this);
2063 public boolean isShowMemoryUsage()
2065 return showMemoryUsage;
2070 df = java.text.NumberFormat.getNumberInstance();
2071 df.setMaximumFractionDigits(2);
2072 runtime = Runtime.getRuntime();
2074 while (showMemoryUsage)
2078 maxMemory = runtime.maxMemory() / 1048576f;
2079 allocatedMemory = runtime.totalMemory() / 1048576f;
2080 freeMemory = runtime.freeMemory() / 1048576f;
2081 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2083 percentUsage = (totalFreeMemory / maxMemory) * 100;
2085 // if (percentUsage < 20)
2087 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2089 // instance.set.setBorder(border1);
2092 // sleep after showing usage
2094 } catch (Exception ex)
2096 ex.printStackTrace();
2101 public void paintComponent(Graphics g)
2103 if (showMemoryUsage && g != null && df != null)
2105 if (percentUsage < 20)
2106 g.setColor(Color.red);
2107 FontMetrics fm = g.getFontMetrics();
2111 "Total Free Memory: " + df.format(totalFreeMemory)
2112 + "MB; Max Memory: " + df.format(maxMemory)
2113 + "MB; " + df.format(percentUsage) + "%", 10,
2114 getHeight() - fm.getHeight());
2121 * fixes stacking order after a modal dialog to ensure windows that should be on top actually are
2123 public void relayerWindows()
2128 protected JMenuItem groovyShell;
2130 public void doGroovyCheck()
2132 if (jalview.bin.Cache.groovyJarsPresent())
2134 groovyShell = new JMenuItem();
2135 groovyShell.setText("Groovy Console...");
2136 groovyShell.addActionListener(new ActionListener()
2138 public void actionPerformed(ActionEvent e)
2140 groovyShell_actionPerformed(e);
2143 toolsMenu.add(groovyShell);
2144 groovyShell.setVisible(true);
2149 * Accessor method to quickly get all the AlignmentFrames loaded.
2151 public static AlignFrame[] getAlignframes()
2153 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2159 Vector avp = new Vector();
2163 for (int i = frames.length - 1; i > -1; i--)
2165 if (frames[i] instanceof AlignFrame)
2167 AlignFrame af = (AlignFrame) frames[i];
2171 } catch (Exception ex)
2173 ex.printStackTrace();
2175 if (avp.size() == 0)
2179 AlignFrame afs[] = new AlignFrame[avp.size()];
2180 for (int i = 0, j = avp.size(); i < j; i++)
2182 afs[i] = (AlignFrame) avp.elementAt(i);
2187 public AppJmol[] getJmols()
2189 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2195 Vector avp = new Vector();
2199 for (int i = frames.length - 1; i > -1; i--)
2201 if (frames[i] instanceof AppJmol)
2203 AppJmol af = (AppJmol) frames[i];
2207 } catch (Exception ex)
2209 ex.printStackTrace();
2211 if (avp.size() == 0)
2215 AppJmol afs[] = new AppJmol[avp.size()];
2216 for (int i = 0, j = avp.size(); i < j; i++)
2218 afs[i] = (AppJmol) avp.elementAt(i);
2225 * Add Groovy Support to Jalview
2227 public void groovyShell_actionPerformed(ActionEvent e)
2229 // use reflection to avoid creating compilation dependency.
2230 if (!jalview.bin.Cache.groovyJarsPresent())
2233 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
2237 Class gcClass = Desktop.class.getClassLoader().loadClass(
2238 "groovy.ui.Console");
2239 Constructor gccons = gcClass.getConstructor(null);
2240 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2242 { String.class, Object.class });
2243 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2244 Object gc = gccons.newInstance(null);
2245 setvar.invoke(gc, new Object[]
2246 { "Jalview", this });
2247 run.invoke(gc, null);
2248 } catch (Exception ex)
2250 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2252 .showInternalMessageDialog(
2255 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
2256 "Jalview Groovy Support Failed",
2257 JOptionPane.ERROR_MESSAGE);
2262 * Progress bars managed by the IProgressIndicator method.
2264 private Hashtable<Long,JPanel> progressBars;
2265 private Hashtable<Long,IProgressIndicatorHandler> progressBarHandlers;
2270 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2272 public void setProgressBar(String message, long id)
2274 if (progressBars == null)
2276 progressBars = new Hashtable<Long,JPanel>();
2277 progressBarHandlers = new Hashtable<Long,IProgressIndicatorHandler>();
2280 if (progressBars.get(new Long(id)) != null)
2282 JPanel progressPanel = progressBars
2283 .remove(new Long(id));
2284 if (progressBarHandlers.contains(new Long(id)))
2286 progressBarHandlers.remove(new Long(id));
2288 removeProgressPanel(progressPanel);
2292 progressBars.put(new Long(id), addProgressPanel(message));
2299 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2300 * jalview.gui.IProgressIndicatorHandler)
2302 public void registerHandler(final long id,
2303 final IProgressIndicatorHandler handler)
2305 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2308 "call setProgressBar before registering the progress bar's handler.");
2310 progressBarHandlers.put(new Long(id), handler);
2311 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
2312 if (handler.canCancel())
2314 JButton cancel = new JButton("Cancel");
2315 final IProgressIndicator us = this;
2316 cancel.addActionListener(new ActionListener()
2319 public void actionPerformed(ActionEvent e)
2321 handler.cancelActivity(id);
2324 + ((JLabel) progressPanel.getComponent(0))
2328 progressPanel.add(cancel, BorderLayout.EAST);
2334 * @return true if any progress bars are still active
2337 public boolean operationInProgress()
2339 if (progressBars != null && progressBars.size() > 0)
2347 * This will return the first AlignFrame viewing AlignViewport av. It will
2348 * break if there are more than one AlignFrames viewing a particular av. This
2351 * @return alignFrame for av
2353 public static AlignFrame getAlignFrameFor(AlignViewport av)
2355 if (desktop != null)
2357 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2358 for (int panel = 0; aps != null && panel < aps.length; panel++)
2360 if (aps[panel] != null && aps[panel].av == av)
2362 return aps[panel].alignFrame;
2369 public VamsasApplication getVamsasApplication()
2376 * flag set if jalview GUI is being operated programmatically
2378 private boolean inBatchMode = false;
2381 * check if jalview GUI is being operated programmatically
2383 * @return inBatchMode
2385 public boolean isInBatchMode()
2391 * set flag if jalview GUI is being operated programmatically
2393 * @param inBatchMode
2395 public void setInBatchMode(boolean inBatchMode)
2397 this.inBatchMode = inBatchMode;
2400 public void startServiceDiscovery()
2402 startServiceDiscovery(false);
2405 public void startServiceDiscovery(boolean blocking)
2407 boolean alive = true;
2408 Thread t0 = null, t1 = null, t2 = null;
2410 // todo: changesupport handlers need to be transferred
2411 if (discoverer == null)
2413 discoverer = new jalview.ws.jws1.Discoverer();
2414 // register PCS handler for desktop.
2415 discoverer.addPropertyChangeListener(changeSupport);
2417 // JAL-940 - disabled JWS1 service configuration - always start discoverer until we phase out completely
2420 (t0 = new Thread(discoverer)).start();
2425 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2427 // EnfinEnvision web service menu entries are rebuild every time the
2428 // menu is shown, so no changeSupport events are needed.
2429 jalview.ws.EnfinEnvision2OneWay.getInstance();
2430 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2433 } catch (Exception e)
2436 .info("Exception when trying to launch Envision2 workflow discovery.",
2438 Cache.log.info(e.getStackTrace());
2440 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2442 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2444 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2446 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2452 // TODO: do rest service discovery
2461 } catch (Exception e)
2464 alive = (t1 != null && t1.isAlive())
2465 || (t2 != null && t2.isAlive())
2466 || (t3 != null && t3.isAlive())
2467 || (t0 != null && t0.isAlive());
2473 * called to check if the service discovery process completed successfully.
2477 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2479 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2481 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2482 .getErrorMessages();
2485 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2487 if (serviceChangedDialog == null)
2489 // only run if we aren't already displaying one of these.
2490 javax.swing.SwingUtilities
2491 .invokeLater(serviceChangedDialog = new Runnable()
2497 .showInternalMessageDialog(
2500 + "It may be that you have invalid JABA URLs\nin your web service preferences.\n\nGo to the Web services tab of the\nTools->Preferences dialog box to change them.\n",
2501 "Preferences Problem",
2502 JOptionPane.WARNING_MESSAGE);
2503 serviceChangedDialog = null;
2512 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2519 private Runnable serviceChangedDialog = null;
2522 * start a thread to open a URL in the configured browser. Pops up a warning
2523 * dialog to the user if there is an exception when calling out to the browser
2528 public static void showUrl(final String url)
2530 showUrl(url, Desktop.instance);
2533 * Like showUrl but allows progress handler to be specified
2535 * @param progress (null) or object implementing IProgressIndicator
2537 public static void showUrl(final String url, final IProgressIndicator progress)
2539 new Thread(new Runnable()
2545 if (progress!=null) {
2546 progress.setProgressBar("Opening "+url, this.hashCode());
2548 jalview.util.BrowserLauncher.openURL(url);
2549 } catch (Exception ex)
2552 .showInternalMessageDialog(
2554 "Unixers: Couldn't find default web browser."
2555 + "\nAdd the full path to your browser in Preferences.",
2556 "Web browser not found",
2557 JOptionPane.WARNING_MESSAGE);
2559 ex.printStackTrace();
2561 if (progress!=null) {
2562 progress.setProgressBar(null, this.hashCode());
2568 public static WsParamSetManager wsparamManager = null;
2570 public static ParamManager getUserParameterStore()
2572 if (wsparamManager == null)
2574 wsparamManager = new WsParamSetManager();
2576 return wsparamManager;
2580 * static hyperlink handler proxy method for use by Jalview's internal windows
2583 public static void hyperlinkUpdate(HyperlinkEvent e)
2585 if (e.getEventType() == EventType.ACTIVATED)
2590 url = e.getURL().toString();
2591 Desktop.showUrl(url);
2592 } catch (Exception x)
2595 if (Cache.log!=null) {
2596 Cache.log.error("Couldn't handle string "+url+" as a URL.");
2598 System.err.println("Couldn't handle string "+url+" as a URL.");
2601 // ignore any exceptions due to dud links.