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.util.MessageManager;
27 import jalview.ws.params.ParamManager;
29 import java.awt.BorderLayout;
30 import java.awt.Color;
31 import java.awt.Dimension;
32 import java.awt.FontMetrics;
33 import java.awt.Graphics;
34 import java.awt.GridLayout;
35 import java.awt.Point;
36 import java.awt.Rectangle;
37 import java.awt.Toolkit;
38 import java.awt.datatransfer.Clipboard;
39 import java.awt.datatransfer.ClipboardOwner;
40 import java.awt.datatransfer.DataFlavor;
41 import java.awt.datatransfer.Transferable;
42 import java.awt.dnd.DnDConstants;
43 import java.awt.dnd.DropTargetDragEvent;
44 import java.awt.dnd.DropTargetDropEvent;
45 import java.awt.dnd.DropTargetEvent;
46 import java.awt.dnd.DropTargetListener;
47 import java.awt.event.ActionEvent;
48 import java.awt.event.ActionListener;
49 import java.awt.event.FocusEvent;
50 import java.awt.event.FocusListener;
51 import java.awt.event.MouseAdapter;
52 import java.awt.event.MouseEvent;
53 import java.awt.event.MouseListener;
54 import java.awt.event.WindowAdapter;
55 import java.awt.event.WindowEvent;
56 import java.beans.PropertyChangeEvent;
57 import java.beans.PropertyChangeListener;
58 import java.beans.PropertyVetoException;
59 import java.io.BufferedInputStream;
61 import java.io.FileOutputStream;
62 import java.lang.reflect.Constructor;
64 import java.util.ArrayList;
65 import java.util.Hashtable;
66 import java.util.StringTokenizer;
67 import java.util.Vector;
68 import java.util.concurrent.ExecutorService;
69 import java.util.concurrent.Executors;
70 import java.util.concurrent.Semaphore;
72 import javax.swing.DefaultDesktopManager;
73 import javax.swing.DesktopManager;
74 import javax.swing.JButton;
75 import javax.swing.JComboBox;
76 import javax.swing.JComponent;
77 import javax.swing.JDesktopPane;
78 import javax.swing.JFrame;
79 import javax.swing.JInternalFrame;
80 import javax.swing.JLabel;
81 import javax.swing.JMenuItem;
82 import javax.swing.JOptionPane;
83 import javax.swing.JPanel;
84 import javax.swing.JPopupMenu;
85 import javax.swing.JProgressBar;
86 import javax.swing.SwingUtilities;
87 import javax.swing.event.HyperlinkEvent;
88 import javax.swing.event.MenuEvent;
89 import javax.swing.event.MenuListener;
90 import javax.swing.event.HyperlinkEvent.EventType;
97 * @version $Revision: 1.155 $
99 public class Desktop extends jalview.jbgui.GDesktop implements
100 DropTargetListener, ClipboardOwner, IProgressIndicator,
101 jalview.api.StructureSelectionManagerProvider
104 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
107 * news reader - null if it was never started.
109 private BlogReader jvnews = null;
113 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
115 public void addJalviewPropertyChangeListener(
116 PropertyChangeListener listener)
118 changeSupport.addJalviewPropertyChangeListener(listener);
122 * @param propertyName
124 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
125 * java.beans.PropertyChangeListener)
127 public void addJalviewPropertyChangeListener(String propertyName,
128 PropertyChangeListener listener)
130 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
134 * @param propertyName
136 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
137 * java.beans.PropertyChangeListener)
139 public void removeJalviewPropertyChangeListener(String propertyName,
140 PropertyChangeListener listener)
142 changeSupport.removeJalviewPropertyChangeListener(propertyName,
146 /** Singleton Desktop instance */
147 public static Desktop instance;
149 public static MyDesktopPane desktop;
151 static int openFrameCount = 0;
153 static final int xOffset = 30;
155 static final int yOffset = 30;
157 public static jalview.ws.jws1.Discoverer discoverer;
159 public static Object[] jalviewClipboard;
161 public static boolean internalCopy = false;
163 static int fileLoadingCount = 0;
165 class MyDesktopManager implements DesktopManager
168 private DesktopManager delegate;
170 public MyDesktopManager(DesktopManager delegate)
172 this.delegate = delegate;
175 public void activateFrame(JInternalFrame f)
179 delegate.activateFrame(f);
180 } catch (NullPointerException npe)
182 Point p = getMousePosition();
183 instance.showPasteMenu(p.x, p.y);
187 public void beginDraggingFrame(JComponent f)
189 delegate.beginDraggingFrame(f);
192 public void beginResizingFrame(JComponent f, int direction)
194 delegate.beginResizingFrame(f, direction);
197 public void closeFrame(JInternalFrame f)
199 delegate.closeFrame(f);
202 public void deactivateFrame(JInternalFrame f)
204 delegate.deactivateFrame(f);
207 public void deiconifyFrame(JInternalFrame f)
209 delegate.deiconifyFrame(f);
212 public void dragFrame(JComponent f, int newX, int newY)
218 delegate.dragFrame(f, newX, newY);
221 public void endDraggingFrame(JComponent f)
223 delegate.endDraggingFrame(f);
226 public void endResizingFrame(JComponent f)
228 delegate.endResizingFrame(f);
231 public void iconifyFrame(JInternalFrame f)
233 delegate.iconifyFrame(f);
236 public void maximizeFrame(JInternalFrame f)
238 delegate.maximizeFrame(f);
241 public void minimizeFrame(JInternalFrame f)
243 delegate.minimizeFrame(f);
246 public void openFrame(JInternalFrame f)
248 delegate.openFrame(f);
251 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
254 Rectangle b = desktop.getBounds();
259 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
262 public void setBoundsForFrame(JComponent f, int newX, int newY,
263 int newWidth, int newHeight)
265 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
268 // All other methods, simply delegate
273 * Creates a new Desktop object.
278 * A note to implementors. It is ESSENTIAL that any activities that might
279 * block are spawned off as threads rather than waited for during this
283 doVamsasClientCheck();
286 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
287 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
288 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
290 boolean showjconsole = jalview.bin.Cache.getDefault(
291 "SHOW_JAVA_CONSOLE", false);
292 desktop = new MyDesktopPane(selmemusage);
293 showMemusage.setSelected(selmemusage);
294 desktop.setBackground(Color.white);
295 getContentPane().setLayout(new BorderLayout());
296 // alternate config - have scrollbars - see notes in JAL-153
297 // JScrollPane sp = new JScrollPane();
298 // sp.getViewport().setView(desktop);
299 // getContentPane().add(sp, BorderLayout.CENTER);
300 getContentPane().add(desktop, BorderLayout.CENTER);
301 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
303 // This line prevents Windows Look&Feel resizing all new windows to maximum
304 // if previous window was maximised
305 desktop.setDesktopManager(new MyDesktopManager(
306 new DefaultDesktopManager()));
308 Rectangle dims = getLastKnownDimensions("");
315 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
316 setBounds((int) (screenSize.width - 900) / 2,
317 (int) (screenSize.height - 650) / 2, 900, 650);
319 jconsole = new Console(this, showjconsole);
320 // add essential build information
321 jconsole.setHeader("Jalview Desktop "
322 + jalview.bin.Cache.getProperty("VERSION") + "\n"
324 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
325 + "Java version: " + System.getProperty("java.version") + "\n"
326 + System.getProperty("os.arch") + " "
327 + System.getProperty("os.name") + " "
328 + System.getProperty("os.version"));
330 showConsole(showjconsole);
332 showNews.setVisible(false);
334 this.addWindowListener(new WindowAdapter()
336 public void windowClosing(WindowEvent evt)
343 this.addMouseListener(ma = new MouseAdapter()
345 public void mousePressed(MouseEvent evt)
347 if (SwingUtilities.isRightMouseButton(evt))
349 showPasteMenu(evt.getX(), evt.getY());
353 desktop.addMouseListener(ma);
355 this.addFocusListener(new FocusListener()
359 public void focusLost(FocusEvent e)
361 // TODO Auto-generated method stub
366 public void focusGained(FocusEvent e)
368 Cache.log.debug("Relaying windows after focus gain");
369 // make sure that we sort windows properly after we gain focus
370 instance.relayerWindows();
373 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
374 // Spawn a thread that shows the splashscreen
375 SwingUtilities.invokeLater(new Runnable()
384 // Thread off a new instance of the file chooser - this reduces the time it
385 // takes to open it later on.
386 new Thread(new Runnable()
390 Cache.log.debug("Filechooser init thread started.");
391 JalviewFileChooser chooser = new JalviewFileChooser(
392 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
393 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
394 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
395 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
396 Cache.log.debug("Filechooser init thread finished.");
399 // Add the service change listener
400 changeSupport.addJalviewPropertyChangeListener("services",
401 new PropertyChangeListener()
405 public void propertyChange(PropertyChangeEvent evt)
407 Cache.log.debug("Firing service changed event for "
408 + evt.getNewValue());
409 JalviewServicesChanged(evt);
415 public void checkForNews()
417 final Desktop me = this;
418 // Thread off the news reader, in case there are connection problems.
419 addDialogThread(new Runnable()
424 Cache.log.debug("Starting news thread.");
426 jvnews = new BlogReader(me);
427 showNews.setVisible(true);
428 Cache.log.debug("Completed news thread.");
433 protected void showNews_actionPerformed(ActionEvent e)
435 showNews(showNews.isSelected());
438 void showNews(boolean visible)
441 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
442 showNews.setSelected(visible);
443 if (visible && !jvnews.isVisible())
445 new Thread(new Runnable()
450 long instance = System.currentTimeMillis();
451 Desktop.instance.setProgressBar("Refreshing news", instance);
452 jvnews.refreshNews();
453 Desktop.instance.setProgressBar(null, instance);
462 * recover the last known dimensions for a jalview window
465 * - empty string is desktop, all other windows have unique prefix
466 * @return null or last known dimensions scaled to current geometry (if last
467 * window geom was known)
469 Rectangle getLastKnownDimensions(String windowName)
471 // TODO: lock aspect ratio for scaling desktop Bug #0058199
472 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
473 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
474 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
475 String width = jalview.bin.Cache.getProperty(windowName
477 String height = jalview.bin.Cache.getProperty(windowName
479 if ((x != null) && (y != null) && (width != null) && (height != null))
481 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
482 .parseInt(width), ih = Integer.parseInt(height);
483 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
485 // attempt #1 - try to cope with change in screen geometry - this
486 // version doesn't preserve original jv aspect ratio.
487 // take ratio of current screen size vs original screen size.
488 double sw = ((1f * screenSize.width) / (1f * Integer
489 .parseInt(jalview.bin.Cache
490 .getProperty("SCREENGEOMETRY_WIDTH"))));
491 double sh = ((1f * screenSize.height) / (1f * Integer
492 .parseInt(jalview.bin.Cache
493 .getProperty("SCREENGEOMETRY_HEIGHT"))));
494 // rescale the bounds depending upon the current screen geometry.
495 ix = (int) (ix * sw);
496 iw = (int) (iw * sw);
497 iy = (int) (iy * sh);
498 ih = (int) (ih * sh);
499 while (ix >= screenSize.width)
501 jalview.bin.Cache.log
502 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
503 ix -= screenSize.width;
505 while (iy >= screenSize.height)
507 jalview.bin.Cache.log
508 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
509 iy -= screenSize.height;
511 jalview.bin.Cache.log.debug("Got last known dimensions for "
512 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
515 // return dimensions for new instance
516 return new Rectangle(ix, iy, iw, ih);
521 private void doVamsasClientCheck()
523 if (jalview.bin.Cache.vamsasJarsPresent())
525 setupVamsasDisconnectedGui();
526 VamsasMenu.setVisible(true);
527 final Desktop us = this;
528 VamsasMenu.addMenuListener(new MenuListener()
530 // this listener remembers when the menu was first selected, and
531 // doesn't rebuild the session list until it has been cleared and
533 boolean refresh = true;
535 public void menuCanceled(MenuEvent e)
540 public void menuDeselected(MenuEvent e)
545 public void menuSelected(MenuEvent e)
549 us.buildVamsasStMenu();
554 vamsasStart.setVisible(true);
558 void showPasteMenu(int x, int y)
560 JPopupMenu popup = new JPopupMenu();
561 JMenuItem item = new JMenuItem("Paste To New Window");
562 item.addActionListener(new ActionListener()
564 public void actionPerformed(ActionEvent evt)
571 popup.show(this, x, y);
578 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
579 Transferable contents = c.getContents(this);
581 if (contents != null)
583 String file = (String) contents
584 .getTransferData(DataFlavor.stringFlavor);
586 String format = new IdentifyFile().Identify(file,
587 FormatAdapter.PASTE);
589 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
592 } catch (Exception ex)
595 .println("Unable to paste alignment from system clipboard:\n"
601 * Adds and opens the given frame to the desktop
612 public static synchronized void addInternalFrame(
613 final JInternalFrame frame, String title, int w, int h)
615 addInternalFrame(frame, title, w, h, true);
632 public static synchronized void addInternalFrame(
633 final JInternalFrame frame, String title, int w, int h,
637 // TODO: allow callers to determine X and Y position of frame (eg. via
639 // TODO: consider fixing method to update entries in the window submenu with
640 // the current window title
642 frame.setTitle(title);
643 if (frame.getWidth() < 1 || frame.getHeight() < 1)
647 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
648 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
649 // IF JALVIEW IS RUNNING HEADLESS
650 // ///////////////////////////////////////////////
651 if (instance == null || (System.getProperty("java.awt.headless") != null
652 && System.getProperty("java.awt.headless").equals("true")))
659 frame.setVisible(true);
660 frame.setClosable(true);
661 frame.setResizable(resizable);
662 frame.setMaximizable(resizable);
663 frame.setIconifiable(resizable);
664 frame.setFrameIcon(null);
666 if (frame.getX() < 1 && frame.getY() < 1)
668 frame.setLocation(xOffset * openFrameCount, yOffset
669 * ((openFrameCount - 1) % 10) + yOffset);
672 final JMenuItem menuItem = new JMenuItem(title);
673 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
675 public void internalFrameActivated(
676 javax.swing.event.InternalFrameEvent evt)
678 JInternalFrame itf = desktop.getSelectedFrame();
686 public void internalFrameClosed(
687 javax.swing.event.InternalFrameEvent evt)
689 PaintRefresher.RemoveComponent(frame);
691 windowMenu.remove(menuItem);
692 JInternalFrame itf = desktop.getSelectedFrame();
701 menuItem.addActionListener(new ActionListener()
703 public void actionPerformed(ActionEvent e)
707 frame.setSelected(true);
708 frame.setIcon(false);
709 } catch (java.beans.PropertyVetoException ex)
715 menuItem.addMouseListener(new MouseListener()
719 public void mouseReleased(MouseEvent e)
724 public void mousePressed(MouseEvent e)
729 public void mouseExited(MouseEvent e)
733 frame.setSelected(false);
734 } catch (PropertyVetoException e1)
740 public void mouseEntered(MouseEvent e)
744 frame.setSelected(true);
745 } catch (PropertyVetoException e1)
751 public void mouseClicked(MouseEvent e)
757 windowMenu.add(menuItem);
763 frame.setSelected(true);
764 frame.requestFocus();
765 } catch (java.beans.PropertyVetoException ve)
767 } catch (java.lang.ClassCastException cex)
770 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
775 public void lostOwnership(Clipboard clipboard, Transferable contents)
779 Desktop.jalviewClipboard = null;
782 internalCopy = false;
785 public void dragEnter(DropTargetDragEvent evt)
789 public void dragExit(DropTargetEvent evt)
793 public void dragOver(DropTargetDragEvent evt)
797 public void dropActionChanged(DropTargetDragEvent evt)
807 public void drop(DropTargetDropEvent evt)
809 Transferable t = evt.getTransferable();
810 java.util.List files = null;
811 java.util.List protocols = null;
815 DataFlavor uriListFlavor = new DataFlavor(
816 "text/uri-list;class=java.lang.String");
817 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
819 // Works on Windows and MacOSX
820 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
821 files = (java.util.List) t
822 .getTransferData(DataFlavor.javaFileListFlavor);
824 else if (t.isDataFlavorSupported(uriListFlavor))
826 // This is used by Unix drag system
827 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
828 String data = (String) t.getTransferData(uriListFlavor);
829 files = new java.util.ArrayList(1);
830 protocols = new java.util.ArrayList(1);
831 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
832 data, "\r\n"); st.hasMoreTokens();)
834 String s = st.nextToken();
835 if (s.startsWith("#"))
837 // the line is a comment (as per the RFC 2483)
840 java.net.URI uri = new java.net.URI(s);
841 if (uri.getScheme().toLowerCase().startsWith("http"))
843 protocols.add(FormatAdapter.URL);
844 files.add(uri.toString());
848 // otherwise preserve old behaviour: catch all for file objects
849 java.io.File file = new java.io.File(uri);
850 protocols.add(FormatAdapter.FILE);
851 files.add(file.toString());
855 } catch (Exception e)
863 for (int i = 0; i < files.size(); i++)
865 String file = files.get(i).toString();
866 String protocol = (protocols == null) ? FormatAdapter.FILE
867 : (String) protocols.get(i);
868 String format = null;
870 if (file.endsWith(".jar"))
877 format = new IdentifyFile().Identify(file, protocol);
880 new FileLoader().LoadFile(file, protocol, format);
883 } catch (Exception ex)
895 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
897 JalviewFileChooser chooser = new JalviewFileChooser(
898 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
899 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
900 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
901 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
903 chooser.setFileView(new JalviewFileView());
904 chooser.setDialogTitle("Open local file");
905 chooser.setToolTipText("Open");
907 int value = chooser.showOpenDialog(this);
909 if (value == JalviewFileChooser.APPROVE_OPTION)
911 String choice = chooser.getSelectedFile().getPath();
912 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
913 .getSelectedFile().getParent());
915 String format = null;
916 if (chooser.getSelectedFormat().equals("Jalview"))
922 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
925 if (viewport != null)
927 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
932 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
943 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
945 // This construct allows us to have a wider textfield
947 JLabel label = new JLabel(MessageManager.getString("label.input_file_url"));
948 final JComboBox history = new JComboBox();
950 JPanel panel = new JPanel(new GridLayout(2, 1));
953 history.setPreferredSize(new Dimension(400, 20));
954 history.setEditable(true);
955 history.addItem("http://www.");
957 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
961 if (historyItems != null)
963 st = new StringTokenizer(historyItems, "\t");
965 while (st.hasMoreTokens())
967 history.addItem(st.nextElement());
971 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
972 MessageManager.getString("label.input_alignment_from_url"), JOptionPane.OK_CANCEL_OPTION);
974 if (reply != JOptionPane.OK_OPTION)
979 String url = history.getSelectedItem().toString();
981 if (url.toLowerCase().endsWith(".jar"))
983 if (viewport != null)
985 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
990 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
995 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
997 if (format.equals("URL NOT FOUND"))
999 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1000 "Couldn't locate " + url, "URL not found",
1001 JOptionPane.WARNING_MESSAGE);
1006 if (viewport != null)
1008 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1012 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1023 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1025 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1026 cap.setForInput(viewport);
1027 Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
1035 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1037 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1038 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1040 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1041 getBounds().y, getWidth(), getHeight()));
1043 if (jconsole != null)
1045 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1046 jconsole.stopConsole();
1050 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1053 if (dialogExecutor != null)
1055 dialogExecutor.shutdownNow();
1061 private void storeLastKnownDimensions(String string, Rectangle jc)
1063 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1064 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1065 + " height:" + jc.height);
1067 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1068 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1069 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1070 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1079 public void aboutMenuItem_actionPerformed(ActionEvent e)
1081 // StringBuffer message = getAboutMessage(false);
1082 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1084 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1085 new Thread(new Runnable()
1089 new SplashScreen(true);
1094 public StringBuffer getAboutMessage(boolean shortv)
1096 StringBuffer message = new StringBuffer();
1097 message.append("<html>");
1100 message.append("<h1><strong>Version: "
1101 + jalview.bin.Cache.getProperty("VERSION")
1102 + "</strong></h1><br>");
1103 message.append("<strong>Last Updated: <em>"
1104 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1105 + "</em></strong>");
1111 message.append("<strong>Version "
1112 + jalview.bin.Cache.getProperty("VERSION")
1113 + "; last updated: "
1114 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1117 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1120 message.append("<br>...Checking latest version...</br>");
1122 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1123 .equals(jalview.bin.Cache.getProperty("VERSION")))
1125 boolean red = false;
1126 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1127 .indexOf("automated build") == -1)
1130 // Displayed when code version and jnlp version do not match and code
1131 // version is not a development build
1132 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1135 message.append("<br>!! Version "
1136 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1138 + " is available for download from "
1139 + jalview.bin.Cache.getDefault("www.jalview.org",
1140 "http://www.jalview.org") + " !!");
1143 message.append("</div>");
1146 message.append("<br>Authors: "
1150 "Jim Procter, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton")
1151 + "<br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1152 + "<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"
1153 + "<br>If you use Jalview, please cite:"
1154 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1155 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1156 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1167 public void documentationMenuItem_actionPerformed(ActionEvent e)
1171 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
1172 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
1173 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
1175 javax.help.HelpBroker hb = hs.createHelpBroker();
1176 hb.setCurrentID("home");
1177 hb.setDisplayed(true);
1178 } catch (Exception ex)
1183 public void closeAll_actionPerformed(ActionEvent e)
1185 JInternalFrame[] frames = desktop.getAllFrames();
1186 for (int i = 0; i < frames.length; i++)
1190 frames[i].setClosed(true);
1191 } catch (java.beans.PropertyVetoException ex)
1195 System.out.println("ALL CLOSED");
1196 if (v_client != null)
1198 // TODO clear binding to vamsas document objects on close_all
1203 public void raiseRelated_actionPerformed(ActionEvent e)
1205 reorderAssociatedWindows(false, false);
1208 public void minimizeAssociated_actionPerformed(ActionEvent e)
1210 reorderAssociatedWindows(true, false);
1213 void closeAssociatedWindows()
1215 reorderAssociatedWindows(false, true);
1221 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1224 protected void garbageCollect_actionPerformed(ActionEvent e)
1226 // We simply collect the garbage
1227 jalview.bin.Cache.log.debug("Collecting garbage...");
1229 jalview.bin.Cache.log.debug("Finished garbage collection.");
1236 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1239 protected void showMemusage_actionPerformed(ActionEvent e)
1241 desktop.showMemoryUsage(showMemusage.isSelected());
1248 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1251 protected void showConsole_actionPerformed(ActionEvent e)
1253 showConsole(showConsole.isSelected());
1256 Console jconsole = null;
1259 * control whether the java console is visible or not
1263 void showConsole(boolean selected)
1265 showConsole.setSelected(selected);
1266 // TODO: decide if we should update properties file
1267 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1269 jconsole.setVisible(selected);
1272 void reorderAssociatedWindows(boolean minimize, boolean close)
1274 JInternalFrame[] frames = desktop.getAllFrames();
1275 if (frames == null || frames.length < 1)
1280 AlignViewport source = null, target = null;
1281 if (frames[0] instanceof AlignFrame)
1283 source = ((AlignFrame) frames[0]).getCurrentView();
1285 else if (frames[0] instanceof TreePanel)
1287 source = ((TreePanel) frames[0]).getViewPort();
1289 else if (frames[0] instanceof PCAPanel)
1291 source = ((PCAPanel) frames[0]).av;
1293 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1295 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1300 for (int i = 0; i < frames.length; i++)
1303 if (frames[i] == null)
1307 if (frames[i] instanceof AlignFrame)
1309 target = ((AlignFrame) frames[i]).getCurrentView();
1311 else if (frames[i] instanceof TreePanel)
1313 target = ((TreePanel) frames[i]).getViewPort();
1315 else if (frames[i] instanceof PCAPanel)
1317 target = ((PCAPanel) frames[i]).av;
1319 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1321 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1324 if (source == target)
1330 frames[i].setClosed(true);
1334 frames[i].setIcon(minimize);
1337 frames[i].toFront();
1341 } catch (java.beans.PropertyVetoException ex)
1355 protected void preferences_actionPerformed(ActionEvent e)
1366 public void saveState_actionPerformed(ActionEvent e)
1368 JalviewFileChooser chooser = new JalviewFileChooser(
1369 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1370 { "jar" }, new String[]
1371 { "Jalview Project" }, "Jalview Project");
1373 chooser.setFileView(new JalviewFileView());
1374 chooser.setDialogTitle("Save State");
1376 int value = chooser.showSaveDialog(this);
1378 if (value == JalviewFileChooser.APPROVE_OPTION)
1380 final Desktop me = this;
1381 final java.io.File choice = chooser.getSelectedFile();
1382 new Thread(new Runnable()
1387 setProgressBar("Saving jalview project " + choice.getName(),
1389 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1390 choice.getParent());
1391 // TODO catch and handle errors for savestate
1392 // TODO prevent user from messing with the Desktop whilst we're saving
1395 new Jalview2XML().SaveState(choice);
1396 } catch (OutOfMemoryError oom)
1398 new OOMWarning("Whilst saving current state to "
1399 + choice.getName(), oom);
1400 } catch (Exception ex)
1403 "Problems whilst trying to save to " + choice.getName(),
1405 JOptionPane.showMessageDialog(
1407 "Error whilst saving current state to "
1408 + choice.getName(), "Couldn't save project",
1409 JOptionPane.WARNING_MESSAGE);
1411 setProgressBar(null, choice.hashCode());
1423 public void loadState_actionPerformed(ActionEvent e)
1425 JalviewFileChooser chooser = new JalviewFileChooser(
1426 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1427 { "jar" }, new String[]
1428 { "Jalview Project" }, "Jalview Project");
1429 chooser.setFileView(new JalviewFileView());
1430 chooser.setDialogTitle("Restore state");
1432 int value = chooser.showOpenDialog(this);
1434 if (value == JalviewFileChooser.APPROVE_OPTION)
1436 final String choice = chooser.getSelectedFile().getAbsolutePath();
1437 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1438 .getSelectedFile().getParent());
1439 new Thread(new Runnable()
1443 setProgressBar("loading jalview project " + choice,
1447 new Jalview2XML().LoadJalviewAlign(choice);
1448 } catch (OutOfMemoryError oom)
1450 new OOMWarning("Whilst loading project from " + choice, oom);
1451 } catch (Exception ex)
1453 Cache.log.error("Problems whilst loading project from "
1455 JOptionPane.showMessageDialog(Desktop.desktop,
1456 "Error whilst loading project from " + choice,
1457 "Couldn't load project", JOptionPane.WARNING_MESSAGE);
1459 setProgressBar(null, choice.hashCode());
1465 public void inputSequence_actionPerformed(ActionEvent e)
1467 new SequenceFetcher(this);
1470 JPanel progressPanel;
1472 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1474 public void startLoading(final String fileName)
1476 if (fileLoadingCount == 0)
1478 fileLoadingPanels.add(addProgressPanel("Loading File: " + fileName
1484 private JPanel addProgressPanel(String string)
1486 if (progressPanel == null)
1488 progressPanel = new JPanel(new GridLayout(1, 1));
1489 totalProgressCount = 0;
1490 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1492 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1493 JProgressBar progressBar = new JProgressBar();
1494 progressBar.setIndeterminate(true);
1496 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1498 thisprogress.add(progressBar, BorderLayout.CENTER);
1499 progressPanel.add(thisprogress);
1500 ((GridLayout) progressPanel.getLayout())
1501 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1502 ++totalProgressCount;
1503 instance.validate();
1504 return thisprogress;
1507 int totalProgressCount = 0;
1509 private void removeProgressPanel(JPanel progbar)
1511 if (progressPanel != null)
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;
1525 public void stopLoading()
1528 if (fileLoadingCount < 1)
1530 for (JPanel flp : fileLoadingPanels)
1532 removeProgressPanel(flp);
1534 fileLoadingPanels.clear();
1535 fileLoadingCount = 0;
1540 public static int getViewCount(String alignmentId)
1542 AlignViewport[] aps = getViewports(alignmentId);
1543 return (aps == null) ? 0 : aps.length;
1548 * @param alignmentId
1549 * @return all AlignmentPanels concerning the alignmentId sequence set
1551 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1554 if (Desktop.desktop == null)
1556 // no frames created and in headless mode
1557 // TODO: verify that frames are recoverable when in headless mode
1560 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1561 ArrayList aps = new ArrayList();
1562 for (int t = 0; t < frames.length; t++)
1564 if (frames[t] instanceof AlignFrame)
1566 AlignFrame af = (AlignFrame) frames[t];
1567 for (int a = 0; a < af.alignPanels.size(); a++)
1569 if (alignmentId.equals(((AlignmentPanel) af.alignPanels
1570 .elementAt(a)).av.getSequenceSetId()))
1572 aps.add(af.alignPanels.elementAt(a));
1577 if (aps.size() == 0)
1581 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1582 for (int t = 0; t < vap.length; t++)
1584 vap[t] = (AlignmentPanel) aps.get(t);
1590 * get all the viewports on an alignment.
1592 * @param sequenceSetId
1593 * unique alignment id
1594 * @return all viewports on the alignment bound to sequenceSetId
1596 public static AlignViewport[] getViewports(String sequenceSetId)
1598 Vector viewp = new Vector();
1599 if (desktop != null)
1601 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1603 for (int t = 0; t < frames.length; t++)
1605 if (frames[t] instanceof AlignFrame)
1607 AlignFrame afr = ((AlignFrame) frames[t]);
1608 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1610 if (afr.alignPanels != null)
1612 for (int a = 0; a < afr.alignPanels.size(); a++)
1614 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1615 .elementAt(a)).av.getSequenceSetId()))
1617 viewp.addElement(((AlignmentPanel) afr.alignPanels
1624 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1629 if (viewp.size() > 0)
1631 AlignViewport[] vp = new AlignViewport[viewp.size()];
1639 public void explodeViews(AlignFrame af)
1641 int size = af.alignPanels.size();
1647 for (int i = 0; i < size; i++)
1649 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1650 AlignFrame newaf = new AlignFrame(ap);
1651 if (ap.av.explodedPosition != null
1652 && !ap.av.explodedPosition.equals(af.getBounds()))
1654 newaf.setBounds(ap.av.explodedPosition);
1657 ap.av.gatherViewsHere = false;
1659 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1660 AlignFrame.DEFAULT_HEIGHT);
1663 af.alignPanels.clear();
1664 af.closeMenuItem_actionPerformed(true);
1668 public void gatherViews(AlignFrame source)
1670 source.viewport.gatherViewsHere = true;
1671 source.viewport.explodedPosition = source.getBounds();
1672 JInternalFrame[] frames = desktop.getAllFrames();
1673 String viewId = source.viewport.getSequenceSetId();
1675 for (int t = 0; t < frames.length; t++)
1677 if (frames[t] instanceof AlignFrame && frames[t] != source)
1679 AlignFrame af = (AlignFrame) frames[t];
1680 boolean gatherThis = false;
1681 for (int a = 0; a < af.alignPanels.size(); a++)
1683 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1684 if (viewId.equals(ap.av.getSequenceSetId()))
1687 ap.av.gatherViewsHere = false;
1688 ap.av.explodedPosition = af.getBounds();
1689 source.addAlignmentPanel(ap, false);
1695 af.alignPanels.clear();
1696 af.closeMenuItem_actionPerformed(true);
1703 jalview.gui.VamsasApplication v_client = null;
1705 public void vamsasImport_actionPerformed(ActionEvent e)
1707 if (v_client == null)
1709 // Load and try to start a session.
1710 JalviewFileChooser chooser = new JalviewFileChooser(
1711 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1713 chooser.setFileView(new JalviewFileView());
1714 chooser.setDialogTitle("Open a saved VAMSAS session");
1715 chooser.setToolTipText("select a vamsas session to be opened as a new vamsas session.");
1717 int value = chooser.showOpenDialog(this);
1719 if (value == JalviewFileChooser.APPROVE_OPTION)
1721 String fle = chooser.getSelectedFile().toString();
1722 if (!vamsasImport(chooser.getSelectedFile()))
1724 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1725 MessageManager.formatMessage("label.couldnt_import_as_vamsas_session", new String[]{fle}),
1726 MessageManager.getString("label.vamsas_document_import_failed"),
1727 JOptionPane.ERROR_MESSAGE);
1733 jalview.bin.Cache.log
1734 .error("Implementation error - load session from a running session is not supported.");
1739 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1742 * @return true if import was a success and a session was started.
1744 public boolean vamsasImport(URL url)
1746 // TODO: create progress bar
1747 if (v_client != null)
1750 jalview.bin.Cache.log
1751 .error("Implementation error - load session from a running session is not supported.");
1757 // copy the URL content to a temporary local file
1758 // TODO: be a bit cleverer here with nio (?!)
1759 File file = File.createTempFile("vdocfromurl", ".vdj");
1760 FileOutputStream fos = new FileOutputStream(file);
1761 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1762 byte[] buffer = new byte[2048];
1764 while ((ln = bis.read(buffer)) > -1)
1766 fos.write(buffer, 0, ln);
1770 v_client = new jalview.gui.VamsasApplication(this, file,
1771 url.toExternalForm());
1772 } catch (Exception ex)
1774 jalview.bin.Cache.log.error(
1775 "Failed to create new vamsas session from contents of URL "
1779 setupVamsasConnectedGui();
1780 v_client.initial_update(); // TODO: thread ?
1781 return v_client.inSession();
1785 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1788 * @return true if import was a success and a session was started.
1790 public boolean vamsasImport(File file)
1792 if (v_client != null)
1795 jalview.bin.Cache.log
1796 .error("Implementation error - load session from a running session is not supported.");
1800 setProgressBar("Importing VAMSAS session from " + file.getName(),
1804 v_client = new jalview.gui.VamsasApplication(this, file, null);
1805 } catch (Exception ex)
1807 setProgressBar("Importing VAMSAS session from " + file.getName(),
1809 jalview.bin.Cache.log.error(
1810 "New vamsas session from existing session file failed:", ex);
1813 setupVamsasConnectedGui();
1814 v_client.initial_update(); // TODO: thread ?
1815 setProgressBar("Importing VAMSAS session from " + file.getName(),
1817 return v_client.inSession();
1820 public boolean joinVamsasSession(String mysesid)
1822 if (v_client != null)
1825 "Trying to join a vamsas session when another is already connected.");
1827 if (mysesid == null)
1829 throw new Error("Invalid vamsas session id.");
1831 v_client = new VamsasApplication(this, mysesid);
1832 setupVamsasConnectedGui();
1833 v_client.initial_update();
1834 return (v_client.inSession());
1837 public void vamsasStart_actionPerformed(ActionEvent e)
1839 if (v_client == null)
1842 // we just start a default session for moment.
1844 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1845 * getProperty("LAST_DIRECTORY"));
1847 * chooser.setFileView(new JalviewFileView());
1848 * chooser.setDialogTitle("Load Vamsas file");
1849 * chooser.setToolTipText("Import");
1851 * int value = chooser.showOpenDialog(this);
1853 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1854 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1856 v_client = new VamsasApplication(this);
1857 setupVamsasConnectedGui();
1858 v_client.initial_update(); // TODO: thread ?
1862 // store current data in session.
1863 v_client.push_update(); // TODO: thread
1867 protected void setupVamsasConnectedGui()
1869 vamsasStart.setText(MessageManager.getString("label.session_update"));
1870 vamsasSave.setVisible(true);
1871 vamsasStop.setVisible(true);
1872 vamsasImport.setVisible(false); // Document import to existing session is
1873 // not possible for vamsas-client-1.0.
1876 protected void setupVamsasDisconnectedGui()
1878 vamsasSave.setVisible(false);
1879 vamsasStop.setVisible(false);
1880 vamsasImport.setVisible(true);
1881 vamsasStart.setText(MessageManager.getString("label.new_vamsas_session"));
1884 public void vamsasStop_actionPerformed(ActionEvent e)
1886 if (v_client != null)
1888 v_client.end_session();
1890 setupVamsasDisconnectedGui();
1894 protected void buildVamsasStMenu()
1896 if (v_client == null)
1898 String[] sess = null;
1901 sess = VamsasApplication.getSessionList();
1902 } catch (Exception e)
1904 jalview.bin.Cache.log.warn(
1905 "Problem getting current sessions list.", e);
1910 jalview.bin.Cache.log.debug("Got current sessions list: "
1911 + sess.length + " entries.");
1912 VamsasStMenu.removeAll();
1913 for (int i = 0; i < sess.length; i++)
1915 JMenuItem sessit = new JMenuItem();
1916 sessit.setText(sess[i]);
1917 sessit.setToolTipText("Connect to session " + sess[i]);
1918 final Desktop dsktp = this;
1919 final String mysesid = sess[i];
1920 sessit.addActionListener(new ActionListener()
1923 public void actionPerformed(ActionEvent e)
1925 if (dsktp.v_client == null)
1927 Thread rthr = new Thread(new Runnable()
1932 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1933 dsktp.setupVamsasConnectedGui();
1934 dsktp.v_client.initial_update();
1942 VamsasStMenu.add(sessit);
1944 // don't show an empty menu.
1945 VamsasStMenu.setVisible(sess.length > 0);
1950 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1951 VamsasStMenu.removeAll();
1952 VamsasStMenu.setVisible(false);
1957 // Not interested in the content. Just hide ourselves.
1958 VamsasStMenu.setVisible(false);
1962 public void vamsasSave_actionPerformed(ActionEvent e)
1964 if (v_client != null)
1966 JalviewFileChooser chooser = new JalviewFileChooser(
1967 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1968 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1970 { "Vamsas Document" }, "Vamsas Document");
1972 chooser.setFileView(new JalviewFileView());
1973 chooser.setDialogTitle("Save Vamsas Document Archive");
1975 int value = chooser.showSaveDialog(this);
1977 if (value == JalviewFileChooser.APPROVE_OPTION)
1979 java.io.File choice = chooser.getSelectedFile();
1980 JPanel progpanel = addProgressPanel("Saving VAMSAS Document to "
1981 + choice.getName());
1982 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1983 String warnmsg = null;
1984 String warnttl = null;
1987 v_client.vclient.storeDocument(choice);
1990 warnttl = "Serious Problem saving Vamsas Document";
1991 warnmsg = ex.toString();
1992 jalview.bin.Cache.log.error("Error Whilst saving document to "
1995 } catch (Exception ex)
1997 warnttl = "Problem saving Vamsas Document.";
1998 warnmsg = ex.toString();
1999 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2003 removeProgressPanel(progpanel);
2004 if (warnmsg != null)
2006 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2008 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2014 JPanel vamUpdate = null;
2017 * hide vamsas user gui bits when a vamsas document event is being handled.
2020 * true to hide gui, false to reveal gui
2022 public void setVamsasUpdate(boolean b)
2024 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2025 + (b ? "in progress" : "finished"));
2027 if (vamUpdate != null)
2029 this.removeProgressPanel(vamUpdate);
2033 vamUpdate = this.addProgressPanel("Updating vamsas session");
2035 vamsasStart.setVisible(!b);
2036 vamsasStop.setVisible(!b);
2037 vamsasSave.setVisible(!b);
2040 public JInternalFrame[] getAllFrames()
2042 return desktop.getAllFrames();
2046 * Checks the given url to see if it gives a response indicating that the user
2047 * should be informed of a new questionnaire.
2051 public void checkForQuestionnaire(String url)
2053 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2054 // javax.swing.SwingUtilities.invokeLater(jvq);
2055 new Thread(jvq).start();
2059 * Proxy class for JDesktopPane which optionally displays the current memory
2060 * usage and highlights the desktop area with a red bar if free memory runs
2065 public class MyDesktopPane extends JDesktopPane implements Runnable
2068 boolean showMemoryUsage = false;
2072 java.text.NumberFormat df;
2074 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2077 public MyDesktopPane(boolean showMemoryUsage)
2079 showMemoryUsage(showMemoryUsage);
2082 public void showMemoryUsage(boolean showMemoryUsage)
2084 this.showMemoryUsage = showMemoryUsage;
2085 if (showMemoryUsage)
2087 Thread worker = new Thread(this);
2092 public boolean isShowMemoryUsage()
2094 return showMemoryUsage;
2099 df = java.text.NumberFormat.getNumberInstance();
2100 df.setMaximumFractionDigits(2);
2101 runtime = Runtime.getRuntime();
2103 while (showMemoryUsage)
2107 maxMemory = runtime.maxMemory() / 1048576f;
2108 allocatedMemory = runtime.totalMemory() / 1048576f;
2109 freeMemory = runtime.freeMemory() / 1048576f;
2110 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2112 percentUsage = (totalFreeMemory / maxMemory) * 100;
2114 // if (percentUsage < 20)
2116 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2118 // instance.set.setBorder(border1);
2121 // sleep after showing usage
2123 } catch (Exception ex)
2125 ex.printStackTrace();
2130 public void paintComponent(Graphics g)
2132 if (showMemoryUsage && g != null && df != null)
2134 if (percentUsage < 20)
2135 g.setColor(Color.red);
2136 FontMetrics fm = g.getFontMetrics();
2140 MessageManager.formatMessage("label.memory_stats", new String[]{df.format(totalFreeMemory),df.format(maxMemory),df.format(percentUsage)}), 10,
2141 getHeight() - fm.getHeight());
2148 * fixes stacking order after a modal dialog to ensure windows that should be
2149 * on top actually are
2151 public void relayerWindows()
2156 protected JMenuItem groovyShell;
2158 public void doGroovyCheck()
2160 if (jalview.bin.Cache.groovyJarsPresent())
2162 groovyShell = new JMenuItem();
2163 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2164 groovyShell.addActionListener(new ActionListener()
2166 public void actionPerformed(ActionEvent e)
2168 groovyShell_actionPerformed(e);
2171 toolsMenu.add(groovyShell);
2172 groovyShell.setVisible(true);
2177 * Accessor method to quickly get all the AlignmentFrames loaded.
2179 public static AlignFrame[] getAlignframes()
2181 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2187 Vector avp = new Vector();
2191 for (int i = frames.length - 1; i > -1; i--)
2193 if (frames[i] instanceof AlignFrame)
2195 AlignFrame af = (AlignFrame) frames[i];
2199 } catch (Exception ex)
2201 ex.printStackTrace();
2203 if (avp.size() == 0)
2207 AlignFrame afs[] = new AlignFrame[avp.size()];
2208 for (int i = 0, j = avp.size(); i < j; i++)
2210 afs[i] = (AlignFrame) avp.elementAt(i);
2216 public AppJmol[] getJmols()
2218 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2224 Vector avp = new Vector();
2228 for (int i = frames.length - 1; i > -1; i--)
2230 if (frames[i] instanceof AppJmol)
2232 AppJmol af = (AppJmol) frames[i];
2236 } catch (Exception ex)
2238 ex.printStackTrace();
2240 if (avp.size() == 0)
2244 AppJmol afs[] = new AppJmol[avp.size()];
2245 for (int i = 0, j = avp.size(); i < j; i++)
2247 afs[i] = (AppJmol) avp.elementAt(i);
2254 * Add Groovy Support to Jalview
2256 public void groovyShell_actionPerformed(ActionEvent e)
2258 // use reflection to avoid creating compilation dependency.
2259 if (!jalview.bin.Cache.groovyJarsPresent())
2262 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
2266 Class gcClass = Desktop.class.getClassLoader().loadClass(
2267 "groovy.ui.Console");
2268 Constructor gccons = gcClass.getConstructor(null);
2269 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2271 { String.class, Object.class });
2272 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2273 Object gc = gccons.newInstance(null);
2274 setvar.invoke(gc, new Object[]
2275 { "Jalview", this });
2276 run.invoke(gc, null);
2277 } catch (Exception ex)
2279 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2281 .showInternalMessageDialog(
2284 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
2285 "Jalview Groovy Support Failed",
2286 JOptionPane.ERROR_MESSAGE);
2291 * Progress bars managed by the IProgressIndicator method.
2293 private Hashtable<Long, JPanel> progressBars;
2295 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2300 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2302 public void setProgressBar(String message, long id)
2304 if (progressBars == null)
2306 progressBars = new Hashtable<Long, JPanel>();
2307 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2310 if (progressBars.get(new Long(id)) != null)
2312 JPanel progressPanel = progressBars.remove(new Long(id));
2313 if (progressBarHandlers.contains(new Long(id)))
2315 progressBarHandlers.remove(new Long(id));
2317 removeProgressPanel(progressPanel);
2321 progressBars.put(new Long(id), addProgressPanel(message));
2328 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2329 * jalview.gui.IProgressIndicatorHandler)
2331 public void registerHandler(final long id,
2332 final IProgressIndicatorHandler handler)
2334 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2337 "call setProgressBar before registering the progress bar's handler.");
2339 progressBarHandlers.put(new Long(id), handler);
2340 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
2341 if (handler.canCancel())
2343 JButton cancel = new JButton(MessageManager.getString("action.cancel"));
2344 final IProgressIndicator us = this;
2345 cancel.addActionListener(new ActionListener()
2348 public void actionPerformed(ActionEvent e)
2350 handler.cancelActivity(id);
2353 + ((JLabel) progressPanel.getComponent(0))
2357 progressPanel.add(cancel, BorderLayout.EAST);
2363 * @return true if any progress bars are still active
2366 public boolean operationInProgress()
2368 if (progressBars != null && progressBars.size() > 0)
2376 * This will return the first AlignFrame viewing AlignViewport av. It will
2377 * break if there are more than one AlignFrames viewing a particular av. This
2380 * @return alignFrame for av
2382 public static AlignFrame getAlignFrameFor(AlignViewport av)
2384 if (desktop != null)
2386 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2387 for (int panel = 0; aps != null && panel < aps.length; panel++)
2389 if (aps[panel] != null && aps[panel].av == av)
2391 return aps[panel].alignFrame;
2398 public VamsasApplication getVamsasApplication()
2405 * flag set if jalview GUI is being operated programmatically
2407 private boolean inBatchMode = false;
2410 * check if jalview GUI is being operated programmatically
2412 * @return inBatchMode
2414 public boolean isInBatchMode()
2420 * set flag if jalview GUI is being operated programmatically
2422 * @param inBatchMode
2424 public void setInBatchMode(boolean inBatchMode)
2426 this.inBatchMode = inBatchMode;
2429 public void startServiceDiscovery()
2431 startServiceDiscovery(false);
2434 public void startServiceDiscovery(boolean blocking)
2436 boolean alive = true;
2437 Thread t0 = null, t1 = null, t2 = null;
2438 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2441 // todo: changesupport handlers need to be transferred
2442 if (discoverer == null)
2444 discoverer = new jalview.ws.jws1.Discoverer();
2445 // register PCS handler for desktop.
2446 discoverer.addPropertyChangeListener(changeSupport);
2448 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2449 // until we phase out completely
2450 (t0 = new Thread(discoverer)).start();
2453 // ENFIN services are EOLed as of Jalview 2.8.1 release
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());
2475 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2477 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2479 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2481 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2487 // TODO: do rest service discovery
2496 } catch (Exception e)
2499 alive = (t1 != null && t1.isAlive())
2500 || (t2 != null && t2.isAlive())
2501 || (t3 != null && t3.isAlive())
2502 || (t0 != null && t0.isAlive());
2508 * called to check if the service discovery process completed successfully.
2512 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2514 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2516 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2517 .getErrorMessages();
2520 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2522 if (serviceChangedDialog == null)
2524 // only run if we aren't already displaying one of these.
2525 addDialogThread(serviceChangedDialog = new Runnable()
2531 * JalviewDialog jd =new JalviewDialog() {
2533 * @Override protected void cancelPressed() { // TODO
2534 * Auto-generated method stub
2536 * }@Override protected void okPressed() { // TODO
2537 * Auto-generated method stub
2539 * }@Override protected void raiseClosed() { // TODO
2540 * Auto-generated method stub
2542 * } }; jd.initDialogFrame(new
2543 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2544 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2545 * + " or mis-configured HTTP proxy settings.<br/>" +
2546 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2548 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2549 * ), true, true, "Web Service Configuration Problem", 450,
2552 * jd.waitForInput();
2558 "<html><table width=\"450\"><tr><td>"
2560 + "</td></tr></table>"
2561 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2562 + " or mis-configured HTTP proxy settings.</p>"
2563 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2564 + " Tools->Preferences dialog box to change them.</p></html>"),
2565 "Web Service Configuration Problem",
2566 JOptionPane.DEFAULT_OPTION,
2567 JOptionPane.ERROR_MESSAGE);
2568 serviceChangedDialog = null;
2577 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2584 private Runnable serviceChangedDialog = null;
2587 * start a thread to open a URL in the configured browser. Pops up a warning
2588 * dialog to the user if there is an exception when calling out to the browser
2593 public static void showUrl(final String url)
2595 showUrl(url, Desktop.instance);
2599 * Like showUrl but allows progress handler to be specified
2603 * (null) or object implementing IProgressIndicator
2605 public static void showUrl(final String url,
2606 final IProgressIndicator progress)
2608 new Thread(new Runnable()
2614 if (progress != null)
2616 progress.setProgressBar("Opening " + url, this.hashCode());
2618 jalview.util.BrowserLauncher.openURL(url);
2619 } catch (Exception ex)
2622 .showInternalMessageDialog(
2624 "Unixers: Couldn't find default web browser."
2625 + "\nAdd the full path to your browser in Preferences.",
2626 "Web browser not found",
2627 JOptionPane.WARNING_MESSAGE);
2629 ex.printStackTrace();
2631 if (progress != null)
2633 progress.setProgressBar(null, this.hashCode());
2639 public static WsParamSetManager wsparamManager = null;
2641 public static ParamManager getUserParameterStore()
2643 if (wsparamManager == null)
2645 wsparamManager = new WsParamSetManager();
2647 return wsparamManager;
2651 * static hyperlink handler proxy method for use by Jalview's internal windows
2655 public static void hyperlinkUpdate(HyperlinkEvent e)
2657 if (e.getEventType() == EventType.ACTIVATED)
2662 url = e.getURL().toString();
2663 Desktop.showUrl(url);
2664 } catch (Exception x)
2668 if (Cache.log != null)
2670 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2674 System.err.println("Couldn't handle string " + url
2678 // ignore any exceptions due to dud links.
2685 * single thread that handles display of dialogs to user.
2687 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2690 * flag indicating if dialogExecutor should try to acquire a permit
2692 private volatile boolean dialogPause = true;
2697 private java.util.concurrent.Semaphore block = new Semaphore(0);
2700 * add another dialog thread to the queue
2704 public void addDialogThread(final Runnable prompter)
2706 dialogExecutor.submit(new Runnable()
2715 } catch (InterruptedException x)
2720 if (instance == null)
2726 SwingUtilities.invokeAndWait(prompter);
2727 } catch (Exception q)
2729 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2735 public void startDialogQueue()
2737 // set the flag so we don't pause waiting for another permit and semaphore
2738 // the current task to begin
2739 dialogPause = false;