2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3 * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, 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;
67 import java.util.concurrent.ExecutorService;
68 import java.util.concurrent.Executors;
69 import java.util.concurrent.Semaphore;
71 import javax.swing.DefaultDesktopManager;
72 import javax.swing.DesktopManager;
73 import javax.swing.JButton;
74 import javax.swing.JComboBox;
75 import javax.swing.JComponent;
76 import javax.swing.JDesktopPane;
77 import javax.swing.JFrame;
78 import javax.swing.JInternalFrame;
79 import javax.swing.JLabel;
80 import javax.swing.JMenuItem;
81 import javax.swing.JOptionPane;
82 import javax.swing.JPanel;
83 import javax.swing.JPopupMenu;
84 import javax.swing.JProgressBar;
85 import javax.swing.SwingUtilities;
86 import javax.swing.event.HyperlinkEvent;
87 import javax.swing.event.MenuEvent;
88 import javax.swing.event.MenuListener;
89 import javax.swing.event.HyperlinkEvent.EventType;
96 * @version $Revision: 1.155 $
98 public class Desktop extends jalview.jbgui.GDesktop implements
99 DropTargetListener, ClipboardOwner, IProgressIndicator,
100 jalview.api.StructureSelectionManagerProvider
103 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
106 * news reader - null if it was never started.
108 private BlogReader jvnews = null;
112 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
114 public void addJalviewPropertyChangeListener(
115 PropertyChangeListener listener)
117 changeSupport.addJalviewPropertyChangeListener(listener);
121 * @param propertyName
123 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
124 * java.beans.PropertyChangeListener)
126 public void addJalviewPropertyChangeListener(String propertyName,
127 PropertyChangeListener listener)
129 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
133 * @param propertyName
135 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
136 * java.beans.PropertyChangeListener)
138 public void removeJalviewPropertyChangeListener(String propertyName,
139 PropertyChangeListener listener)
141 changeSupport.removeJalviewPropertyChangeListener(propertyName,
145 /** Singleton Desktop instance */
146 public static Desktop instance;
148 public static MyDesktopPane desktop;
150 static int openFrameCount = 0;
152 static final int xOffset = 30;
154 static final int yOffset = 30;
156 public static jalview.ws.jws1.Discoverer discoverer;
158 public static Object[] jalviewClipboard;
160 public static boolean internalCopy = false;
162 static int fileLoadingCount = 0;
164 class MyDesktopManager implements DesktopManager
167 private DesktopManager delegate;
169 public MyDesktopManager(DesktopManager delegate)
171 this.delegate = delegate;
174 public void activateFrame(JInternalFrame f)
178 delegate.activateFrame(f);
179 } catch (NullPointerException npe)
181 Point p = getMousePosition();
182 instance.showPasteMenu(p.x, p.y);
186 public void beginDraggingFrame(JComponent f)
188 delegate.beginDraggingFrame(f);
191 public void beginResizingFrame(JComponent f, int direction)
193 delegate.beginResizingFrame(f, direction);
196 public void closeFrame(JInternalFrame f)
198 delegate.closeFrame(f);
201 public void deactivateFrame(JInternalFrame f)
203 delegate.deactivateFrame(f);
206 public void deiconifyFrame(JInternalFrame f)
208 delegate.deiconifyFrame(f);
211 public void dragFrame(JComponent f, int newX, int newY)
217 delegate.dragFrame(f, newX, newY);
220 public void endDraggingFrame(JComponent f)
222 delegate.endDraggingFrame(f);
225 public void endResizingFrame(JComponent f)
227 delegate.endResizingFrame(f);
230 public void iconifyFrame(JInternalFrame f)
232 delegate.iconifyFrame(f);
235 public void maximizeFrame(JInternalFrame f)
237 delegate.maximizeFrame(f);
240 public void minimizeFrame(JInternalFrame f)
242 delegate.minimizeFrame(f);
245 public void openFrame(JInternalFrame f)
247 delegate.openFrame(f);
250 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
253 Rectangle b = desktop.getBounds();
258 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
261 public void setBoundsForFrame(JComponent f, int newX, int newY,
262 int newWidth, int newHeight)
264 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
267 // All other methods, simply delegate
272 * Creates a new Desktop object.
277 * A note to implementors. It is ESSENTIAL that any activities that might
278 * block are spawned off as threads rather than waited for during this
282 doVamsasClientCheck();
285 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
286 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
287 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
289 boolean showjconsole = jalview.bin.Cache.getDefault(
290 "SHOW_JAVA_CONSOLE", false);
291 desktop = new MyDesktopPane(selmemusage);
292 showMemusage.setSelected(selmemusage);
293 desktop.setBackground(Color.white);
294 getContentPane().setLayout(new BorderLayout());
295 // alternate config - have scrollbars - see notes in JAL-153
296 // JScrollPane sp = new JScrollPane();
297 // sp.getViewport().setView(desktop);
298 // getContentPane().add(sp, BorderLayout.CENTER);
299 getContentPane().add(desktop, BorderLayout.CENTER);
300 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
302 // This line prevents Windows Look&Feel resizing all new windows to maximum
303 // if previous window was maximised
304 desktop.setDesktopManager(new MyDesktopManager(
305 new DefaultDesktopManager()));
307 Rectangle dims = getLastKnownDimensions("");
314 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
315 setBounds((int) (screenSize.width - 900) / 2,
316 (int) (screenSize.height - 650) / 2, 900, 650);
318 jconsole = new Console(this, showjconsole);
319 // add essential build information
320 jconsole.setHeader("Jalview Desktop "
321 + jalview.bin.Cache.getProperty("VERSION") + "\n"
323 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
324 + "Java version: " + System.getProperty("java.version") + "\n"
325 + System.getProperty("os.arch") + " "
326 + System.getProperty("os.name") + " "
327 + System.getProperty("os.version"));
329 showConsole(showjconsole);
331 showNews.setVisible(false);
333 this.addWindowListener(new WindowAdapter()
335 public void windowClosing(WindowEvent evt)
342 this.addMouseListener(ma = new MouseAdapter()
344 public void mousePressed(MouseEvent evt)
346 if (SwingUtilities.isRightMouseButton(evt))
348 showPasteMenu(evt.getX(), evt.getY());
352 desktop.addMouseListener(ma);
354 this.addFocusListener(new FocusListener()
358 public void focusLost(FocusEvent e)
360 // TODO Auto-generated method stub
365 public void focusGained(FocusEvent e)
367 Cache.log.debug("Relaying windows after focus gain");
368 // make sure that we sort windows properly after we gain focus
369 instance.relayerWindows();
372 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
373 // Spawn a thread that shows the splashscreen
374 SwingUtilities.invokeLater(new Runnable()
383 // Thread off a new instance of the file chooser - this reduces the time it
384 // takes to open it later on.
385 new Thread(new Runnable()
389 Cache.log.debug("Filechooser init thread started.");
390 JalviewFileChooser chooser = new JalviewFileChooser(
391 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
392 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
393 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
394 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
395 Cache.log.debug("Filechooser init thread finished.");
398 // Add the service change listener
399 changeSupport.addJalviewPropertyChangeListener("services",
400 new PropertyChangeListener()
404 public void propertyChange(PropertyChangeEvent evt)
406 Cache.log.debug("Firing service changed event for "
407 + evt.getNewValue());
408 JalviewServicesChanged(evt);
414 public void checkForNews()
416 final Desktop me = this;
417 // Thread off the news reader, in case there are connection problems.
418 addDialogThread(new Runnable()
423 Cache.log.debug("Starting news thread.");
425 jvnews = new BlogReader(me);
426 showNews.setVisible(true);
427 Cache.log.debug("Completed news thread.");
432 protected void showNews_actionPerformed(ActionEvent e)
434 showNews(showNews.isSelected());
437 void showNews(boolean visible)
440 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
441 showNews.setSelected(visible);
442 if (visible && !jvnews.isVisible())
444 new Thread(new Runnable()
449 long instance = System.currentTimeMillis();
450 Desktop.instance.setProgressBar("Refreshing news", instance);
451 jvnews.refreshNews();
452 Desktop.instance.setProgressBar(null, instance);
461 * recover the last known dimensions for a jalview window
464 * - empty string is desktop, all other windows have unique prefix
465 * @return null or last known dimensions scaled to current geometry (if last
466 * window geom was known)
468 Rectangle getLastKnownDimensions(String windowName)
470 // TODO: lock aspect ratio for scaling desktop Bug #0058199
471 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
472 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
473 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
474 String width = jalview.bin.Cache.getProperty(windowName
476 String height = jalview.bin.Cache.getProperty(windowName
478 if ((x != null) && (y != null) && (width != null) && (height != null))
480 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
481 .parseInt(width), ih = Integer.parseInt(height);
482 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
484 // attempt #1 - try to cope with change in screen geometry - this
485 // version doesn't preserve original jv aspect ratio.
486 // take ratio of current screen size vs original screen size.
487 double sw = ((1f * screenSize.width) / (1f * Integer
488 .parseInt(jalview.bin.Cache
489 .getProperty("SCREENGEOMETRY_WIDTH"))));
490 double sh = ((1f * screenSize.height) / (1f * Integer
491 .parseInt(jalview.bin.Cache
492 .getProperty("SCREENGEOMETRY_HEIGHT"))));
493 // rescale the bounds depending upon the current screen geometry.
494 ix = (int) (ix * sw);
495 iw = (int) (iw * sw);
496 iy = (int) (iy * sh);
497 ih = (int) (ih * sh);
498 while (ix >= screenSize.width)
500 jalview.bin.Cache.log
501 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
502 ix -= screenSize.width;
504 while (iy >= screenSize.height)
506 jalview.bin.Cache.log
507 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
508 iy -= screenSize.height;
510 jalview.bin.Cache.log.debug("Got last known dimensions for "
511 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
514 // return dimensions for new instance
515 return new Rectangle(ix, iy, iw, ih);
520 private void doVamsasClientCheck()
522 if (jalview.bin.Cache.vamsasJarsPresent())
524 setupVamsasDisconnectedGui();
525 VamsasMenu.setVisible(true);
526 final Desktop us = this;
527 VamsasMenu.addMenuListener(new MenuListener()
529 // this listener remembers when the menu was first selected, and
530 // doesn't rebuild the session list until it has been cleared and
532 boolean refresh = true;
534 public void menuCanceled(MenuEvent e)
539 public void menuDeselected(MenuEvent e)
544 public void menuSelected(MenuEvent e)
548 us.buildVamsasStMenu();
553 vamsasStart.setVisible(true);
557 void showPasteMenu(int x, int y)
559 JPopupMenu popup = new JPopupMenu();
560 JMenuItem item = new JMenuItem("Paste To New Window");
561 item.addActionListener(new ActionListener()
563 public void actionPerformed(ActionEvent evt)
570 popup.show(this, x, y);
577 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
578 Transferable contents = c.getContents(this);
580 if (contents != null)
582 String file = (String) contents
583 .getTransferData(DataFlavor.stringFlavor);
585 String format = new IdentifyFile().Identify(file,
586 FormatAdapter.PASTE);
588 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
591 } catch (Exception ex)
594 .println("Unable to paste alignment from system clipboard:\n"
600 * Adds and opens the given frame to the desktop
611 public static synchronized void addInternalFrame(
612 final JInternalFrame frame, String title, int w, int h)
614 addInternalFrame(frame, title, w, h, true);
631 public static synchronized void addInternalFrame(
632 final JInternalFrame frame, String title, int w, int h,
636 // TODO: allow callers to determine X and Y position of frame (eg. via
638 // TODO: consider fixing method to update entries in the window submenu with
639 // the current window title
641 frame.setTitle(title);
642 if (frame.getWidth() < 1 || frame.getHeight() < 1)
646 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
647 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
648 // IF JALVIEW IS RUNNING HEADLESS
649 // ///////////////////////////////////////////////
650 if (System.getProperty("java.awt.headless") != null
651 && System.getProperty("java.awt.headless").equals("true"))
658 frame.setVisible(true);
659 frame.setClosable(true);
660 frame.setResizable(resizable);
661 frame.setMaximizable(resizable);
662 frame.setIconifiable(resizable);
663 frame.setFrameIcon(null);
665 if (frame.getX() < 1 && frame.getY() < 1)
667 frame.setLocation(xOffset * openFrameCount, yOffset
668 * ((openFrameCount - 1) % 10) + yOffset);
671 final JMenuItem menuItem = new JMenuItem(title);
672 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
674 public void internalFrameActivated(
675 javax.swing.event.InternalFrameEvent evt)
677 JInternalFrame itf = desktop.getSelectedFrame();
685 public void internalFrameClosed(
686 javax.swing.event.InternalFrameEvent evt)
688 PaintRefresher.RemoveComponent(frame);
690 windowMenu.remove(menuItem);
691 JInternalFrame itf = desktop.getSelectedFrame();
700 menuItem.addActionListener(new ActionListener()
702 public void actionPerformed(ActionEvent e)
706 frame.setSelected(true);
707 frame.setIcon(false);
708 } catch (java.beans.PropertyVetoException ex)
714 menuItem.addMouseListener(new MouseListener()
718 public void mouseReleased(MouseEvent e)
723 public void mousePressed(MouseEvent e)
728 public void mouseExited(MouseEvent e)
732 frame.setSelected(false);
733 } catch (PropertyVetoException e1)
739 public void mouseEntered(MouseEvent e)
743 frame.setSelected(true);
744 } catch (PropertyVetoException e1)
750 public void mouseClicked(MouseEvent e)
756 windowMenu.add(menuItem);
762 frame.setSelected(true);
763 frame.requestFocus();
764 } catch (java.beans.PropertyVetoException ve)
766 } catch (java.lang.ClassCastException cex)
769 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
774 public void lostOwnership(Clipboard clipboard, Transferable contents)
778 Desktop.jalviewClipboard = null;
781 internalCopy = false;
784 public void dragEnter(DropTargetDragEvent evt)
788 public void dragExit(DropTargetEvent evt)
792 public void dragOver(DropTargetDragEvent evt)
796 public void dropActionChanged(DropTargetDragEvent evt)
806 public void drop(DropTargetDropEvent evt)
808 Transferable t = evt.getTransferable();
809 java.util.List files = null;
810 java.util.List protocols = null;
814 DataFlavor uriListFlavor = new DataFlavor(
815 "text/uri-list;class=java.lang.String");
816 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
818 // Works on Windows and MacOSX
819 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
820 files = (java.util.List) t
821 .getTransferData(DataFlavor.javaFileListFlavor);
823 else if (t.isDataFlavorSupported(uriListFlavor))
825 // This is used by Unix drag system
826 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
827 String data = (String) t.getTransferData(uriListFlavor);
828 files = new java.util.ArrayList(1);
829 protocols = new java.util.ArrayList(1);
830 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
831 data, "\r\n"); st.hasMoreTokens();)
833 String s = st.nextToken();
834 if (s.startsWith("#"))
836 // the line is a comment (as per the RFC 2483)
839 java.net.URI uri = new java.net.URI(s);
840 if (uri.getScheme().toLowerCase().startsWith("http"))
842 protocols.add(FormatAdapter.URL);
843 files.add(uri.toString());
847 // otherwise preserve old behaviour: catch all for file objects
848 java.io.File file = new java.io.File(uri);
849 protocols.add(FormatAdapter.FILE);
850 files.add(file.toString());
854 } catch (Exception e)
862 for (int i = 0; i < files.size(); i++)
864 String file = files.get(i).toString();
865 String protocol = (protocols == null) ? FormatAdapter.FILE
866 : (String) protocols.get(i);
867 String format = null;
869 if (file.endsWith(".jar"))
876 format = new IdentifyFile().Identify(file, protocol);
879 new FileLoader().LoadFile(file, protocol, format);
882 } catch (Exception ex)
894 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
896 JalviewFileChooser chooser = new JalviewFileChooser(
897 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
898 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
899 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
900 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
902 chooser.setFileView(new JalviewFileView());
903 chooser.setDialogTitle("Open local file");
904 chooser.setToolTipText("Open");
906 int value = chooser.showOpenDialog(this);
908 if (value == JalviewFileChooser.APPROVE_OPTION)
910 String choice = chooser.getSelectedFile().getPath();
911 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
912 .getSelectedFile().getParent());
914 String format = null;
915 if (chooser.getSelectedFormat()!=null && chooser.getSelectedFormat().equals("Jalview"))
921 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
924 if (viewport != null)
926 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
931 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
942 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
944 // This construct allows us to have a wider textfield
946 JLabel label = new JLabel("Enter URL of Input File");
947 final JComboBox history = new JComboBox();
949 JPanel panel = new JPanel(new GridLayout(2, 1));
952 history.setPreferredSize(new Dimension(400, 20));
953 history.setEditable(true);
954 history.addItem("http://www.");
956 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
960 if (historyItems != null)
962 st = new StringTokenizer(historyItems, "\t");
964 while (st.hasMoreTokens())
966 history.addItem(st.nextElement());
970 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
971 "Input Alignment From URL", JOptionPane.OK_CANCEL_OPTION);
973 if (reply != JOptionPane.OK_OPTION)
978 String url = history.getSelectedItem().toString();
980 if (url.toLowerCase().endsWith(".jar"))
982 if (viewport != null)
984 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
989 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
994 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
996 if (format.equals("URL NOT FOUND"))
998 JOptionPane.showInternalMessageDialog(Desktop.desktop,
999 "Couldn't locate " + url, "URL not found",
1000 JOptionPane.WARNING_MESSAGE);
1005 if (viewport != null)
1007 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1011 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1022 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1024 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1025 cap.setForInput(viewport);
1026 Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
1034 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1036 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1037 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1039 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1040 getBounds().y, getWidth(), getHeight()));
1042 if (jconsole != null)
1044 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1045 jconsole.stopConsole();
1049 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1052 if (dialogExecutor != null)
1054 dialogExecutor.shutdownNow();
1060 private void storeLastKnownDimensions(String string, Rectangle jc)
1062 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1063 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1064 + " height:" + jc.height);
1066 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1067 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1068 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1069 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1078 public void aboutMenuItem_actionPerformed(ActionEvent e)
1080 // StringBuffer message = getAboutMessage(false);
1081 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1083 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1084 new Thread(new Runnable()
1088 new SplashScreen(true);
1093 public StringBuffer getAboutMessage(boolean shortv)
1095 StringBuffer message = new StringBuffer();
1096 message.append("<html>");
1099 message.append("<h1><strong>Version: "
1100 + jalview.bin.Cache.getProperty("VERSION")
1101 + "</strong></h1><br>");
1102 message.append("<strong>Last Updated: <em>"
1103 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1104 + "</em></strong>");
1110 message.append("<strong>Version "
1111 + jalview.bin.Cache.getProperty("VERSION")
1112 + "; last updated: "
1113 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1116 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1119 message.append("<br>...Checking latest version...</br>");
1121 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1122 .equals(jalview.bin.Cache.getProperty("VERSION")))
1124 boolean red = false;
1125 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1126 .indexOf("automated build") == -1)
1129 // Displayed when code version and jnlp version do not match and code
1130 // version is not a development build
1131 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1134 message.append("<br>!! Version "
1135 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1137 + " is available for download from "
1138 + jalview.bin.Cache.getDefault("www.jalview.org",
1139 "http://www.jalview.org") + " !!");
1142 message.append("</div>");
1145 message.append("<br>Authors: "
1149 "Jim Procter, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton")
1150 + "<br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1151 + "<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"
1152 + "<br>If you use Jalview, please cite:"
1153 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1154 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1155 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1166 public void documentationMenuItem_actionPerformed(ActionEvent e)
1170 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
1171 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
1172 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
1174 javax.help.HelpBroker hb = hs.createHelpBroker();
1175 hb.setCurrentID("home");
1176 hb.setDisplayed(true);
1177 } catch (Exception ex)
1182 public void closeAll_actionPerformed(ActionEvent e)
1184 JInternalFrame[] frames = desktop.getAllFrames();
1185 for (int i = 0; i < frames.length; i++)
1189 frames[i].setClosed(true);
1190 } catch (java.beans.PropertyVetoException ex)
1194 System.out.println("ALL CLOSED");
1195 if (v_client != null)
1197 // TODO clear binding to vamsas document objects on close_all
1202 public void raiseRelated_actionPerformed(ActionEvent e)
1204 reorderAssociatedWindows(false, false);
1207 public void minimizeAssociated_actionPerformed(ActionEvent e)
1209 reorderAssociatedWindows(true, false);
1212 void closeAssociatedWindows()
1214 reorderAssociatedWindows(false, true);
1220 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1223 protected void garbageCollect_actionPerformed(ActionEvent e)
1225 // We simply collect the garbage
1226 jalview.bin.Cache.log.debug("Collecting garbage...");
1228 jalview.bin.Cache.log.debug("Finished garbage collection.");
1235 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1238 protected void showMemusage_actionPerformed(ActionEvent e)
1240 desktop.showMemoryUsage(showMemusage.isSelected());
1247 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1250 protected void showConsole_actionPerformed(ActionEvent e)
1252 showConsole(showConsole.isSelected());
1255 Console jconsole = null;
1258 * control whether the java console is visible or not
1262 void showConsole(boolean selected)
1264 showConsole.setSelected(selected);
1265 // TODO: decide if we should update properties file
1266 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1268 jconsole.setVisible(selected);
1271 void reorderAssociatedWindows(boolean minimize, boolean close)
1273 JInternalFrame[] frames = desktop.getAllFrames();
1274 if (frames == null || frames.length < 1)
1279 AlignViewport source = null, target = null;
1280 if (frames[0] instanceof AlignFrame)
1282 source = ((AlignFrame) frames[0]).getCurrentView();
1284 else if (frames[0] instanceof TreePanel)
1286 source = ((TreePanel) frames[0]).getViewPort();
1288 else if (frames[0] instanceof PCAPanel)
1290 source = ((PCAPanel) frames[0]).av;
1292 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1294 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1299 for (int i = 0; i < frames.length; i++)
1302 if (frames[i] == null)
1306 if (frames[i] instanceof AlignFrame)
1308 target = ((AlignFrame) frames[i]).getCurrentView();
1310 else if (frames[i] instanceof TreePanel)
1312 target = ((TreePanel) frames[i]).getViewPort();
1314 else if (frames[i] instanceof PCAPanel)
1316 target = ((PCAPanel) frames[i]).av;
1318 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1320 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1323 if (source == target)
1329 frames[i].setClosed(true);
1333 frames[i].setIcon(minimize);
1336 frames[i].toFront();
1340 } catch (java.beans.PropertyVetoException ex)
1354 protected void preferences_actionPerformed(ActionEvent e)
1365 public void saveState_actionPerformed(ActionEvent e)
1367 JalviewFileChooser chooser = new JalviewFileChooser(
1368 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1369 { "jar" }, new String[]
1370 { "Jalview Project" }, "Jalview Project");
1372 chooser.setFileView(new JalviewFileView());
1373 chooser.setDialogTitle("Save State");
1375 int value = chooser.showSaveDialog(this);
1377 if (value == JalviewFileChooser.APPROVE_OPTION)
1379 final Desktop me = this;
1380 final java.io.File choice = chooser.getSelectedFile();
1381 new Thread(new Runnable()
1386 setProgressBar("Saving jalview project " + choice.getName(),
1388 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1389 choice.getParent());
1390 // TODO catch and handle errors for savestate
1391 // TODO prevent user from messing with the Desktop whilst we're saving
1394 new Jalview2XML().SaveState(choice);
1395 } catch (OutOfMemoryError oom)
1397 new OOMWarning("Whilst saving current state to "
1398 + choice.getName(), oom);
1399 } catch (Exception ex)
1402 "Problems whilst trying to save to " + choice.getName(),
1404 JOptionPane.showMessageDialog(
1406 "Error whilst saving current state to "
1407 + choice.getName(), "Couldn't save project",
1408 JOptionPane.WARNING_MESSAGE);
1410 setProgressBar(null, choice.hashCode());
1422 public void loadState_actionPerformed(ActionEvent e)
1424 JalviewFileChooser chooser = new JalviewFileChooser(
1425 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1426 { "jar" }, new String[]
1427 { "Jalview Project" }, "Jalview Project");
1428 chooser.setFileView(new JalviewFileView());
1429 chooser.setDialogTitle("Restore state");
1431 int value = chooser.showOpenDialog(this);
1433 if (value == JalviewFileChooser.APPROVE_OPTION)
1435 final String choice = chooser.getSelectedFile().getAbsolutePath();
1436 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1437 .getSelectedFile().getParent());
1438 new Thread(new Runnable()
1442 setProgressBar("loading jalview project " + choice,
1446 new Jalview2XML().LoadJalviewAlign(choice);
1447 } catch (OutOfMemoryError oom)
1449 new OOMWarning("Whilst loading project from " + choice, oom);
1450 } catch (Exception ex)
1452 Cache.log.error("Problems whilst loading project from "
1454 JOptionPane.showMessageDialog(Desktop.desktop,
1455 "Error whilst loading project from " + choice,
1456 "Couldn't load project", JOptionPane.WARNING_MESSAGE);
1458 setProgressBar(null, choice.hashCode());
1464 public void inputSequence_actionPerformed(ActionEvent e)
1466 new SequenceFetcher(this);
1469 JPanel progressPanel;
1471 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1473 public void startLoading(final String fileName)
1475 if (fileLoadingCount == 0)
1477 fileLoadingPanels.add(addProgressPanel("Loading File: " + fileName
1483 private JPanel addProgressPanel(String string)
1485 if (progressPanel == null)
1487 progressPanel = new JPanel(new GridLayout(1, 1));
1488 totalProgressCount = 0;
1489 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1491 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1492 JProgressBar progressBar = new JProgressBar();
1493 progressBar.setIndeterminate(true);
1495 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1497 thisprogress.add(progressBar, BorderLayout.CENTER);
1498 progressPanel.add(thisprogress);
1499 ((GridLayout) progressPanel.getLayout())
1500 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1501 ++totalProgressCount;
1502 instance.validate();
1503 return thisprogress;
1506 int totalProgressCount = 0;
1508 private void removeProgressPanel(JPanel progbar)
1510 if (progressPanel != null)
1512 synchronized(progressPanel) {
1513 progressPanel.remove(progbar);
1514 GridLayout gl = (GridLayout) progressPanel.getLayout();
1515 gl.setRows(gl.getRows() - 1);
1516 if (--totalProgressCount < 1)
1518 this.getContentPane().remove(progressPanel);
1519 progressPanel = null;
1526 public void stopLoading()
1529 if (fileLoadingCount < 1)
1531 while (fileLoadingPanels.size()>0)
1533 removeProgressPanel(fileLoadingPanels.remove(0));
1535 fileLoadingPanels.clear();
1536 fileLoadingCount = 0;
1541 public static int getViewCount(String alignmentId)
1543 AlignViewport[] aps = getViewports(alignmentId);
1544 return (aps == null) ? 0 : aps.length;
1549 * @param alignmentId
1550 * @return all AlignmentPanels concerning the alignmentId sequence set
1552 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1555 if (Desktop.desktop == null)
1557 // no frames created and in headless mode
1558 // TODO: verify that frames are recoverable when in headless mode
1561 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1562 ArrayList aps = new ArrayList();
1563 for (int t = 0; t < frames.length; t++)
1565 if (frames[t] instanceof AlignFrame)
1567 AlignFrame af = (AlignFrame) frames[t];
1568 for (int a = 0; a < af.alignPanels.size(); a++)
1570 if (alignmentId.equals(((AlignmentPanel) af.alignPanels
1571 .elementAt(a)).av.getSequenceSetId()))
1573 aps.add(af.alignPanels.elementAt(a));
1578 if (aps.size() == 0)
1582 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1583 for (int t = 0; t < vap.length; t++)
1585 vap[t] = (AlignmentPanel) aps.get(t);
1591 * get all the viewports on an alignment.
1593 * @param sequenceSetId
1594 * unique alignment id
1595 * @return all viewports on the alignment bound to sequenceSetId
1597 public static AlignViewport[] getViewports(String sequenceSetId)
1599 Vector viewp = new Vector();
1600 if (desktop != null)
1602 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1604 for (int t = 0; t < frames.length; t++)
1606 if (frames[t] instanceof AlignFrame)
1608 AlignFrame afr = ((AlignFrame) frames[t]);
1609 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1611 if (afr.alignPanels != null)
1613 for (int a = 0; a < afr.alignPanels.size(); a++)
1615 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1616 .elementAt(a)).av.getSequenceSetId()))
1618 viewp.addElement(((AlignmentPanel) afr.alignPanels
1625 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1630 if (viewp.size() > 0)
1632 AlignViewport[] vp = new AlignViewport[viewp.size()];
1640 public void explodeViews(AlignFrame af)
1642 int size = af.alignPanels.size();
1648 for (int i = 0; i < size; i++)
1650 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1651 AlignFrame newaf = new AlignFrame(ap);
1652 if (ap.av.explodedPosition != null
1653 && !ap.av.explodedPosition.equals(af.getBounds()))
1655 newaf.setBounds(ap.av.explodedPosition);
1658 ap.av.gatherViewsHere = false;
1660 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1661 AlignFrame.DEFAULT_HEIGHT);
1664 af.alignPanels.clear();
1665 af.closeMenuItem_actionPerformed(true);
1669 public void gatherViews(AlignFrame source)
1671 source.viewport.gatherViewsHere = true;
1672 source.viewport.explodedPosition = source.getBounds();
1673 JInternalFrame[] frames = desktop.getAllFrames();
1674 String viewId = source.viewport.getSequenceSetId();
1676 for (int t = 0; t < frames.length; t++)
1678 if (frames[t] instanceof AlignFrame && frames[t] != source)
1680 AlignFrame af = (AlignFrame) frames[t];
1681 boolean gatherThis = false;
1682 for (int a = 0; a < af.alignPanels.size(); a++)
1684 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1685 if (viewId.equals(ap.av.getSequenceSetId()))
1688 ap.av.gatherViewsHere = false;
1689 ap.av.explodedPosition = af.getBounds();
1690 source.addAlignmentPanel(ap, false);
1696 af.alignPanels.clear();
1697 af.closeMenuItem_actionPerformed(true);
1704 jalview.gui.VamsasApplication v_client = null;
1706 public void vamsasImport_actionPerformed(ActionEvent e)
1708 if (v_client == null)
1710 // Load and try to start a session.
1711 JalviewFileChooser chooser = new JalviewFileChooser(
1712 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1714 chooser.setFileView(new JalviewFileView());
1715 chooser.setDialogTitle("Open a saved VAMSAS session");
1716 chooser.setToolTipText("select a vamsas session to be opened as a new vamsas session.");
1718 int value = chooser.showOpenDialog(this);
1720 if (value == JalviewFileChooser.APPROVE_OPTION)
1722 String fle = chooser.getSelectedFile().toString();
1723 if (!vamsasImport(chooser.getSelectedFile()))
1725 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1726 "Couldn't import '" + fle + "' as a new vamsas session.",
1727 "Vamsas Document Import Failed",
1728 JOptionPane.ERROR_MESSAGE);
1734 jalview.bin.Cache.log
1735 .error("Implementation error - load session from a running session is not supported.");
1740 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1743 * @return true if import was a success and a session was started.
1745 public boolean vamsasImport(URL url)
1747 // TODO: create progress bar
1748 if (v_client != null)
1751 jalview.bin.Cache.log
1752 .error("Implementation error - load session from a running session is not supported.");
1758 // copy the URL content to a temporary local file
1759 // TODO: be a bit cleverer here with nio (?!)
1760 File file = File.createTempFile("vdocfromurl", ".vdj");
1761 FileOutputStream fos = new FileOutputStream(file);
1762 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1763 byte[] buffer = new byte[2048];
1765 while ((ln = bis.read(buffer)) > -1)
1767 fos.write(buffer, 0, ln);
1771 v_client = new jalview.gui.VamsasApplication(this, file,
1772 url.toExternalForm());
1773 } catch (Exception ex)
1775 jalview.bin.Cache.log.error(
1776 "Failed to create new vamsas session from contents of URL "
1780 setupVamsasConnectedGui();
1781 v_client.initial_update(); // TODO: thread ?
1782 return v_client.inSession();
1786 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1789 * @return true if import was a success and a session was started.
1791 public boolean vamsasImport(File file)
1793 if (v_client != null)
1796 jalview.bin.Cache.log
1797 .error("Implementation error - load session from a running session is not supported.");
1801 setProgressBar("Importing VAMSAS session from " + file.getName(),
1805 v_client = new jalview.gui.VamsasApplication(this, file, null);
1806 } catch (Exception ex)
1808 setProgressBar("Importing VAMSAS session from " + file.getName(),
1810 jalview.bin.Cache.log.error(
1811 "New vamsas session from existing session file failed:", ex);
1814 setupVamsasConnectedGui();
1815 v_client.initial_update(); // TODO: thread ?
1816 setProgressBar("Importing VAMSAS session from " + file.getName(),
1818 return v_client.inSession();
1821 public boolean joinVamsasSession(String mysesid)
1823 if (v_client != null)
1826 "Trying to join a vamsas session when another is already connected.");
1828 if (mysesid == null)
1830 throw new Error("Invalid vamsas session id.");
1832 v_client = new VamsasApplication(this, mysesid);
1833 setupVamsasConnectedGui();
1834 v_client.initial_update();
1835 return (v_client.inSession());
1838 public void vamsasStart_actionPerformed(ActionEvent e)
1840 if (v_client == null)
1843 // we just start a default session for moment.
1845 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1846 * getProperty("LAST_DIRECTORY"));
1848 * chooser.setFileView(new JalviewFileView());
1849 * chooser.setDialogTitle("Load Vamsas file");
1850 * chooser.setToolTipText("Import");
1852 * int value = chooser.showOpenDialog(this);
1854 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1855 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1857 v_client = new VamsasApplication(this);
1858 setupVamsasConnectedGui();
1859 v_client.initial_update(); // TODO: thread ?
1863 // store current data in session.
1864 v_client.push_update(); // TODO: thread
1868 protected void setupVamsasConnectedGui()
1870 vamsasStart.setText("Session Update");
1871 vamsasSave.setVisible(true);
1872 vamsasStop.setVisible(true);
1873 vamsasImport.setVisible(false); // Document import to existing session is
1874 // not possible for vamsas-client-1.0.
1877 protected void setupVamsasDisconnectedGui()
1879 vamsasSave.setVisible(false);
1880 vamsasStop.setVisible(false);
1881 vamsasImport.setVisible(true);
1882 vamsasStart.setText("New Vamsas Session");
1885 public void vamsasStop_actionPerformed(ActionEvent e)
1887 if (v_client != null)
1889 v_client.end_session();
1891 setupVamsasDisconnectedGui();
1895 protected void buildVamsasStMenu()
1897 if (v_client == null)
1899 String[] sess = null;
1902 sess = VamsasApplication.getSessionList();
1903 } catch (Exception e)
1905 jalview.bin.Cache.log.warn(
1906 "Problem getting current sessions list.", e);
1911 jalview.bin.Cache.log.debug("Got current sessions list: "
1912 + sess.length + " entries.");
1913 VamsasStMenu.removeAll();
1914 for (int i = 0; i < sess.length; i++)
1916 JMenuItem sessit = new JMenuItem();
1917 sessit.setText(sess[i]);
1918 sessit.setToolTipText("Connect to session " + sess[i]);
1919 final Desktop dsktp = this;
1920 final String mysesid = sess[i];
1921 sessit.addActionListener(new ActionListener()
1924 public void actionPerformed(ActionEvent e)
1926 if (dsktp.v_client == null)
1928 Thread rthr = new Thread(new Runnable()
1933 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1934 dsktp.setupVamsasConnectedGui();
1935 dsktp.v_client.initial_update();
1943 VamsasStMenu.add(sessit);
1945 // don't show an empty menu.
1946 VamsasStMenu.setVisible(sess.length > 0);
1951 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1952 VamsasStMenu.removeAll();
1953 VamsasStMenu.setVisible(false);
1958 // Not interested in the content. Just hide ourselves.
1959 VamsasStMenu.setVisible(false);
1963 public void vamsasSave_actionPerformed(ActionEvent e)
1965 if (v_client != null)
1967 JalviewFileChooser chooser = new JalviewFileChooser(
1968 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1969 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1971 { "Vamsas Document" }, "Vamsas Document");
1973 chooser.setFileView(new JalviewFileView());
1974 chooser.setDialogTitle("Save Vamsas Document Archive");
1976 int value = chooser.showSaveDialog(this);
1978 if (value == JalviewFileChooser.APPROVE_OPTION)
1980 java.io.File choice = chooser.getSelectedFile();
1981 JPanel progpanel = addProgressPanel("Saving VAMSAS Document to "
1982 + choice.getName());
1983 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1984 String warnmsg = null;
1985 String warnttl = null;
1988 v_client.vclient.storeDocument(choice);
1991 warnttl = "Serious Problem saving Vamsas Document";
1992 warnmsg = ex.toString();
1993 jalview.bin.Cache.log.error("Error Whilst saving document to "
1996 } catch (Exception ex)
1998 warnttl = "Problem saving Vamsas Document.";
1999 warnmsg = ex.toString();
2000 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2004 removeProgressPanel(progpanel);
2005 if (warnmsg != null)
2007 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2009 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2015 JPanel vamUpdate = null;
2018 * hide vamsas user gui bits when a vamsas document event is being handled.
2021 * true to hide gui, false to reveal gui
2023 public void setVamsasUpdate(boolean b)
2025 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2026 + (b ? "in progress" : "finished"));
2028 if (vamUpdate != null)
2030 this.removeProgressPanel(vamUpdate);
2034 vamUpdate = this.addProgressPanel("Updating vamsas session");
2036 vamsasStart.setVisible(!b);
2037 vamsasStop.setVisible(!b);
2038 vamsasSave.setVisible(!b);
2041 public JInternalFrame[] getAllFrames()
2043 return desktop.getAllFrames();
2047 * Checks the given url to see if it gives a response indicating that the user
2048 * should be informed of a new questionnaire.
2052 public void checkForQuestionnaire(String url)
2054 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2055 // javax.swing.SwingUtilities.invokeLater(jvq);
2056 new Thread(jvq).start();
2060 * Proxy class for JDesktopPane which optionally displays the current memory
2061 * usage and highlights the desktop area with a red bar if free memory runs
2066 public class MyDesktopPane extends JDesktopPane implements Runnable
2069 boolean showMemoryUsage = false;
2073 java.text.NumberFormat df;
2075 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2078 public MyDesktopPane(boolean showMemoryUsage)
2080 showMemoryUsage(showMemoryUsage);
2083 public void showMemoryUsage(boolean showMemoryUsage)
2085 this.showMemoryUsage = showMemoryUsage;
2086 if (showMemoryUsage)
2088 Thread worker = new Thread(this);
2093 public boolean isShowMemoryUsage()
2095 return showMemoryUsage;
2100 df = java.text.NumberFormat.getNumberInstance();
2101 df.setMaximumFractionDigits(2);
2102 runtime = Runtime.getRuntime();
2104 while (showMemoryUsage)
2108 maxMemory = runtime.maxMemory() / 1048576f;
2109 allocatedMemory = runtime.totalMemory() / 1048576f;
2110 freeMemory = runtime.freeMemory() / 1048576f;
2111 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2113 percentUsage = (totalFreeMemory / maxMemory) * 100;
2115 // if (percentUsage < 20)
2117 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2119 // instance.set.setBorder(border1);
2122 // sleep after showing usage
2124 } catch (Exception ex)
2126 ex.printStackTrace();
2131 public void paintComponent(Graphics g)
2133 if (showMemoryUsage && g != null && df != null)
2135 if (percentUsage < 20)
2136 g.setColor(Color.red);
2137 FontMetrics fm = g.getFontMetrics();
2141 "Total Free Memory: " + df.format(totalFreeMemory)
2142 + "MB; Max Memory: " + df.format(maxMemory)
2143 + "MB; " + df.format(percentUsage) + "%", 10,
2144 getHeight() - fm.getHeight());
2151 * fixes stacking order after a modal dialog to ensure windows that should be
2152 * on top actually are
2154 public void relayerWindows()
2159 protected JMenuItem groovyShell;
2161 public void doGroovyCheck()
2163 if (jalview.bin.Cache.groovyJarsPresent())
2165 groovyShell = new JMenuItem();
2166 groovyShell.setText("Groovy Console...");
2167 groovyShell.addActionListener(new ActionListener()
2169 public void actionPerformed(ActionEvent e)
2171 groovyShell_actionPerformed(e);
2174 toolsMenu.add(groovyShell);
2175 groovyShell.setVisible(true);
2180 * Accessor method to quickly get all the AlignmentFrames loaded.
2182 public static AlignFrame[] getAlignframes()
2184 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2190 Vector avp = new Vector();
2194 for (int i = frames.length - 1; i > -1; i--)
2196 if (frames[i] instanceof AlignFrame)
2198 AlignFrame af = (AlignFrame) frames[i];
2202 } catch (Exception ex)
2204 ex.printStackTrace();
2206 if (avp.size() == 0)
2210 AlignFrame afs[] = new AlignFrame[avp.size()];
2211 for (int i = 0, j = avp.size(); i < j; i++)
2213 afs[i] = (AlignFrame) avp.elementAt(i);
2219 public AppJmol[] getJmols()
2221 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2227 Vector avp = new Vector();
2231 for (int i = frames.length - 1; i > -1; i--)
2233 if (frames[i] instanceof AppJmol)
2235 AppJmol af = (AppJmol) frames[i];
2239 } catch (Exception ex)
2241 ex.printStackTrace();
2243 if (avp.size() == 0)
2247 AppJmol afs[] = new AppJmol[avp.size()];
2248 for (int i = 0, j = avp.size(); i < j; i++)
2250 afs[i] = (AppJmol) avp.elementAt(i);
2257 * Add Groovy Support to Jalview
2259 public void groovyShell_actionPerformed(ActionEvent e)
2261 // use reflection to avoid creating compilation dependency.
2262 if (!jalview.bin.Cache.groovyJarsPresent())
2265 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
2269 Class gcClass = Desktop.class.getClassLoader().loadClass(
2270 "groovy.ui.Console");
2271 Constructor gccons = gcClass.getConstructor(null);
2272 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2274 { String.class, Object.class });
2275 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2276 Object gc = gccons.newInstance(null);
2277 setvar.invoke(gc, new Object[]
2278 { "Jalview", this });
2279 run.invoke(gc, null);
2280 } catch (Exception ex)
2282 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2284 .showInternalMessageDialog(
2287 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
2288 "Jalview Groovy Support Failed",
2289 JOptionPane.ERROR_MESSAGE);
2294 * Progress bars managed by the IProgressIndicator method.
2296 private Hashtable<Long, JPanel> progressBars;
2298 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2303 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2305 public void setProgressBar(String message, long id)
2307 if (progressBars == null)
2309 progressBars = new Hashtable<Long, JPanel>();
2310 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2313 if (progressBars.get(new Long(id)) != null)
2315 JPanel progressPanel = progressBars.remove(new Long(id));
2316 if (progressBarHandlers.contains(new Long(id)))
2318 progressBarHandlers.remove(new Long(id));
2320 removeProgressPanel(progressPanel);
2324 progressBars.put(new Long(id), addProgressPanel(message));
2331 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2332 * jalview.gui.IProgressIndicatorHandler)
2334 public void registerHandler(final long id,
2335 final IProgressIndicatorHandler handler)
2337 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2340 "call setProgressBar before registering the progress bar's handler.");
2342 progressBarHandlers.put(new Long(id), handler);
2343 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
2344 if (handler.canCancel())
2346 JButton cancel = new JButton("Cancel");
2347 final IProgressIndicator us = this;
2348 cancel.addActionListener(new ActionListener()
2351 public void actionPerformed(ActionEvent e)
2353 handler.cancelActivity(id);
2356 + ((JLabel) progressPanel.getComponent(0))
2360 progressPanel.add(cancel, BorderLayout.EAST);
2366 * @return true if any progress bars are still active
2369 public boolean operationInProgress()
2371 if (progressBars != null && progressBars.size() > 0)
2379 * This will return the first AlignFrame viewing AlignViewport av. It will
2380 * break if there are more than one AlignFrames viewing a particular av. This
2383 * @return alignFrame for av
2385 public static AlignFrame getAlignFrameFor(AlignViewport av)
2387 if (desktop != null)
2389 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2390 for (int panel = 0; aps != null && panel < aps.length; panel++)
2392 if (aps[panel] != null && aps[panel].av == av)
2394 return aps[panel].alignFrame;
2401 public VamsasApplication getVamsasApplication()
2408 * flag set if jalview GUI is being operated programmatically
2410 private boolean inBatchMode = false;
2413 * check if jalview GUI is being operated programmatically
2415 * @return inBatchMode
2417 public boolean isInBatchMode()
2423 * set flag if jalview GUI is being operated programmatically
2425 * @param inBatchMode
2427 public void setInBatchMode(boolean inBatchMode)
2429 this.inBatchMode = inBatchMode;
2432 public void startServiceDiscovery()
2434 startServiceDiscovery(false);
2437 public void startServiceDiscovery(boolean blocking)
2439 boolean alive = true;
2440 Thread t0 = null, t1 = null, t2 = null;
2442 // todo: changesupport handlers need to be transferred
2443 if (discoverer == null)
2445 discoverer = new jalview.ws.jws1.Discoverer();
2446 // register PCS handler for desktop.
2447 discoverer.addPropertyChangeListener(changeSupport);
2449 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2450 // until we phase out completely
2453 (t0 = new Thread(discoverer)).start();
2458 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2460 // EnfinEnvision web service menu entries are rebuild every time the
2461 // menu is shown, so no changeSupport events are needed.
2462 jalview.ws.EnfinEnvision2OneWay.getInstance();
2463 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2466 } catch (Exception e)
2469 .info("Exception when trying to launch Envision2 workflow discovery.",
2471 Cache.log.info(e.getStackTrace());
2473 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2475 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2477 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2479 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2485 // TODO: do rest service discovery
2494 } catch (Exception e)
2497 alive = (t1 != null && t1.isAlive())
2498 || (t2 != null && t2.isAlive())
2499 || (t3 != null && t3.isAlive())
2500 || (t0 != null && t0.isAlive());
2506 * called to check if the service discovery process completed successfully.
2510 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2512 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2514 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2515 .getErrorMessages();
2518 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2520 if (serviceChangedDialog == null)
2522 // only run if we aren't already displaying one of these.
2523 addDialogThread(serviceChangedDialog = new Runnable()
2529 * JalviewDialog jd =new JalviewDialog() {
2531 * @Override protected void cancelPressed() { // TODO
2532 * Auto-generated method stub
2534 * }@Override protected void okPressed() { // TODO
2535 * Auto-generated method stub
2537 * }@Override protected void raiseClosed() { // TODO
2538 * Auto-generated method stub
2540 * } }; jd.initDialogFrame(new
2541 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2542 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2543 * + " or mis-configured HTTP proxy settings.<br/>" +
2544 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2546 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2547 * ), true, true, "Web Service Configuration Problem", 450,
2550 * jd.waitForInput();
2556 "<html><table width=\"450\"><tr><td>"
2558 + "</td></tr></table>"
2559 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2560 + " or mis-configured HTTP proxy settings.</p>"
2561 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2562 + " Tools->Preferences dialog box to change them.</p></html>"),
2563 "Web Service Configuration Problem",
2564 JOptionPane.DEFAULT_OPTION,
2565 JOptionPane.ERROR_MESSAGE);
2566 serviceChangedDialog = null;
2575 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2582 private Runnable serviceChangedDialog = null;
2585 * start a thread to open a URL in the configured browser. Pops up a warning
2586 * dialog to the user if there is an exception when calling out to the browser
2591 public static void showUrl(final String url)
2593 showUrl(url, Desktop.instance);
2597 * Like showUrl but allows progress handler to be specified
2601 * (null) or object implementing IProgressIndicator
2603 public static void showUrl(final String url,
2604 final IProgressIndicator progress)
2606 new Thread(new Runnable()
2612 if (progress != null)
2614 progress.setProgressBar("Opening " + url, this.hashCode());
2616 jalview.util.BrowserLauncher.openURL(url);
2617 } catch (Exception ex)
2620 .showInternalMessageDialog(
2622 "Unixers: Couldn't find default web browser."
2623 + "\nAdd the full path to your browser in Preferences.",
2624 "Web browser not found",
2625 JOptionPane.WARNING_MESSAGE);
2627 ex.printStackTrace();
2629 if (progress != null)
2631 progress.setProgressBar(null, this.hashCode());
2637 public static WsParamSetManager wsparamManager = null;
2639 public static ParamManager getUserParameterStore()
2641 if (wsparamManager == null)
2643 wsparamManager = new WsParamSetManager();
2645 return wsparamManager;
2649 * static hyperlink handler proxy method for use by Jalview's internal windows
2653 public static void hyperlinkUpdate(HyperlinkEvent e)
2655 if (e.getEventType() == EventType.ACTIVATED)
2660 url = e.getURL().toString();
2661 Desktop.showUrl(url);
2662 } catch (Exception x)
2666 if (Cache.log != null)
2668 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2672 System.err.println("Couldn't handle string " + url
2676 // ignore any exceptions due to dud links.
2683 * single thread that handles display of dialogs to user.
2685 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2688 * flag indicating if dialogExecutor should try to acquire a permit
2690 private volatile boolean dialogPause = true;
2695 private java.util.concurrent.Semaphore block = new Semaphore(0);
2698 * add another dialog thread to the queue
2702 public void addDialogThread(final Runnable prompter)
2704 dialogExecutor.submit(new Runnable()
2713 } catch (InterruptedException x)
2718 if (instance == null)
2724 SwingUtilities.invokeAndWait(prompter);
2725 } catch (Exception q)
2727 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2733 public void startDialogQueue()
2735 // set the flag so we don't pause waiting for another permit and semaphore
2736 // the current task to begin
2737 dialogPause = false;