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 boolean success=true;
810 Transferable t = evt.getTransferable();
811 java.util.List files = null;
812 java.util.List protocols = null;
816 DataFlavor uriListFlavor = new DataFlavor(
817 "text/uri-list;class=java.lang.String");
818 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
820 // Works on Windows and MacOSX
821 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
822 files = (java.util.List) t
823 .getTransferData(DataFlavor.javaFileListFlavor);
825 else if (t.isDataFlavorSupported(uriListFlavor))
827 // This is used by Unix drag system
828 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
829 String data = (String) t.getTransferData(uriListFlavor);
830 files = new java.util.ArrayList(1);
831 protocols = new java.util.ArrayList(1);
832 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
833 data, "\r\n"); st.hasMoreTokens();)
835 String s = st.nextToken();
836 if (s.startsWith("#"))
838 // the line is a comment (as per the RFC 2483)
841 java.net.URI uri = new java.net.URI(s);
842 if (uri.getScheme().toLowerCase().startsWith("http"))
844 protocols.add(FormatAdapter.URL);
845 files.add(uri.toString());
849 // otherwise preserve old behaviour: catch all for file objects
850 java.io.File file = new java.io.File(uri);
851 protocols.add(FormatAdapter.FILE);
852 files.add(file.toString());
856 } catch (Exception e)
865 for (int i = 0; i < files.size(); i++)
867 String file = files.get(i).toString();
868 String protocol = (protocols == null) ? FormatAdapter.FILE
869 : (String) protocols.get(i);
870 String format = null;
872 if (file.endsWith(".jar"))
879 format = new IdentifyFile().Identify(file, protocol);
882 new FileLoader().LoadFile(file, protocol, format);
885 } catch (Exception ex)
890 evt.dropComplete(success); // need this to ensure input focus is properly transfered to any new windows created
899 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
901 JalviewFileChooser chooser = new JalviewFileChooser(
902 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
903 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
904 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
905 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
907 chooser.setFileView(new JalviewFileView());
908 chooser.setDialogTitle("Open local file");
909 chooser.setToolTipText("Open");
911 int value = chooser.showOpenDialog(this);
913 if (value == JalviewFileChooser.APPROVE_OPTION)
915 String choice = chooser.getSelectedFile().getPath();
916 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
917 .getSelectedFile().getParent());
919 String format = null;
920 if (chooser.getSelectedFormat().equals("Jalview"))
926 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
929 if (viewport != null)
931 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
936 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
947 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
949 // This construct allows us to have a wider textfield
951 JLabel label = new JLabel(MessageManager.getString("label.input_file_url"));
952 final JComboBox history = new JComboBox();
954 JPanel panel = new JPanel(new GridLayout(2, 1));
957 history.setPreferredSize(new Dimension(400, 20));
958 history.setEditable(true);
959 history.addItem("http://www.");
961 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
965 if (historyItems != null)
967 st = new StringTokenizer(historyItems, "\t");
969 while (st.hasMoreTokens())
971 history.addItem(st.nextElement());
975 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
976 MessageManager.getString("label.input_alignment_from_url"), JOptionPane.OK_CANCEL_OPTION);
978 if (reply != JOptionPane.OK_OPTION)
983 String url = history.getSelectedItem().toString();
985 if (url.toLowerCase().endsWith(".jar"))
987 if (viewport != null)
989 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
994 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
999 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1001 if (format.equals("URL NOT FOUND"))
1003 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1004 "Couldn't locate " + url, "URL not found",
1005 JOptionPane.WARNING_MESSAGE);
1010 if (viewport != null)
1012 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1016 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1027 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1029 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1030 cap.setForInput(viewport);
1031 Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
1039 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1041 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1042 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1044 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1045 getBounds().y, getWidth(), getHeight()));
1047 if (jconsole != null)
1049 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1050 jconsole.stopConsole();
1054 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1057 if (dialogExecutor != null)
1059 dialogExecutor.shutdownNow();
1065 private void storeLastKnownDimensions(String string, Rectangle jc)
1067 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1068 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1069 + " height:" + jc.height);
1071 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1072 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1073 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1074 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1083 public void aboutMenuItem_actionPerformed(ActionEvent e)
1085 // StringBuffer message = getAboutMessage(false);
1086 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1088 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1089 new Thread(new Runnable()
1093 new SplashScreen(true);
1098 public StringBuffer getAboutMessage(boolean shortv)
1100 StringBuffer message = new StringBuffer();
1101 message.append("<html>");
1104 message.append("<h1><strong>Version: "
1105 + jalview.bin.Cache.getProperty("VERSION")
1106 + "</strong></h1><br>");
1107 message.append("<strong>Last Updated: <em>"
1108 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1109 + "</em></strong>");
1115 message.append("<strong>Version "
1116 + jalview.bin.Cache.getProperty("VERSION")
1117 + "; last updated: "
1118 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1121 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1124 message.append("<br>...Checking latest version...</br>");
1126 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1127 .equals(jalview.bin.Cache.getProperty("VERSION")))
1129 boolean red = false;
1130 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1131 .indexOf("automated build") == -1)
1134 // Displayed when code version and jnlp version do not match and code
1135 // version is not a development build
1136 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1139 message.append("<br>!! Version "
1140 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1142 + " is available for download from "
1143 + jalview.bin.Cache.getDefault("www.jalview.org",
1144 "http://www.jalview.org") + " !!");
1147 message.append("</div>");
1150 message.append("<br>Authors: "
1154 "Jim Procter, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton")
1155 + "<br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1156 + "<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"
1157 + "<br>If you use Jalview, please cite:"
1158 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1159 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1160 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1171 public void documentationMenuItem_actionPerformed(ActionEvent e)
1175 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
1176 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
1177 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
1179 javax.help.HelpBroker hb = hs.createHelpBroker();
1180 hb.setCurrentID("home");
1181 hb.setDisplayed(true);
1182 } catch (Exception ex)
1187 public void closeAll_actionPerformed(ActionEvent e)
1189 JInternalFrame[] frames = desktop.getAllFrames();
1190 for (int i = 0; i < frames.length; i++)
1194 frames[i].setClosed(true);
1195 } catch (java.beans.PropertyVetoException ex)
1199 System.out.println("ALL CLOSED");
1200 if (v_client != null)
1202 // TODO clear binding to vamsas document objects on close_all
1207 public void raiseRelated_actionPerformed(ActionEvent e)
1209 reorderAssociatedWindows(false, false);
1212 public void minimizeAssociated_actionPerformed(ActionEvent e)
1214 reorderAssociatedWindows(true, false);
1217 void closeAssociatedWindows()
1219 reorderAssociatedWindows(false, true);
1225 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1228 protected void garbageCollect_actionPerformed(ActionEvent e)
1230 // We simply collect the garbage
1231 jalview.bin.Cache.log.debug("Collecting garbage...");
1233 jalview.bin.Cache.log.debug("Finished garbage collection.");
1240 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1243 protected void showMemusage_actionPerformed(ActionEvent e)
1245 desktop.showMemoryUsage(showMemusage.isSelected());
1252 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1255 protected void showConsole_actionPerformed(ActionEvent e)
1257 showConsole(showConsole.isSelected());
1260 Console jconsole = null;
1263 * control whether the java console is visible or not
1267 void showConsole(boolean selected)
1269 showConsole.setSelected(selected);
1270 // TODO: decide if we should update properties file
1271 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1273 jconsole.setVisible(selected);
1276 void reorderAssociatedWindows(boolean minimize, boolean close)
1278 JInternalFrame[] frames = desktop.getAllFrames();
1279 if (frames == null || frames.length < 1)
1284 AlignViewport source = null, target = null;
1285 if (frames[0] instanceof AlignFrame)
1287 source = ((AlignFrame) frames[0]).getCurrentView();
1289 else if (frames[0] instanceof TreePanel)
1291 source = ((TreePanel) frames[0]).getViewPort();
1293 else if (frames[0] instanceof PCAPanel)
1295 source = ((PCAPanel) frames[0]).av;
1297 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1299 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1304 for (int i = 0; i < frames.length; i++)
1307 if (frames[i] == null)
1311 if (frames[i] instanceof AlignFrame)
1313 target = ((AlignFrame) frames[i]).getCurrentView();
1315 else if (frames[i] instanceof TreePanel)
1317 target = ((TreePanel) frames[i]).getViewPort();
1319 else if (frames[i] instanceof PCAPanel)
1321 target = ((PCAPanel) frames[i]).av;
1323 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1325 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1328 if (source == target)
1334 frames[i].setClosed(true);
1338 frames[i].setIcon(minimize);
1341 frames[i].toFront();
1345 } catch (java.beans.PropertyVetoException ex)
1359 protected void preferences_actionPerformed(ActionEvent e)
1370 public void saveState_actionPerformed(ActionEvent e)
1372 JalviewFileChooser chooser = new JalviewFileChooser(
1373 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1374 { "jar" }, new String[]
1375 { "Jalview Project" }, "Jalview Project");
1377 chooser.setFileView(new JalviewFileView());
1378 chooser.setDialogTitle("Save State");
1380 int value = chooser.showSaveDialog(this);
1382 if (value == JalviewFileChooser.APPROVE_OPTION)
1384 final Desktop me = this;
1385 final java.io.File choice = chooser.getSelectedFile();
1386 new Thread(new Runnable()
1391 setProgressBar("Saving jalview project " + choice.getName(),
1393 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1394 choice.getParent());
1395 // TODO catch and handle errors for savestate
1396 // TODO prevent user from messing with the Desktop whilst we're saving
1399 new Jalview2XML().SaveState(choice);
1400 } catch (OutOfMemoryError oom)
1402 new OOMWarning("Whilst saving current state to "
1403 + choice.getName(), oom);
1404 } catch (Exception ex)
1407 "Problems whilst trying to save to " + choice.getName(),
1409 JOptionPane.showMessageDialog(
1411 "Error whilst saving current state to "
1412 + choice.getName(), "Couldn't save project",
1413 JOptionPane.WARNING_MESSAGE);
1415 setProgressBar(null, choice.hashCode());
1427 public void loadState_actionPerformed(ActionEvent e)
1429 JalviewFileChooser chooser = new JalviewFileChooser(
1430 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1431 { "jar" }, new String[]
1432 { "Jalview Project" }, "Jalview Project");
1433 chooser.setFileView(new JalviewFileView());
1434 chooser.setDialogTitle("Restore state");
1436 int value = chooser.showOpenDialog(this);
1438 if (value == JalviewFileChooser.APPROVE_OPTION)
1440 final String choice = chooser.getSelectedFile().getAbsolutePath();
1441 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1442 .getSelectedFile().getParent());
1443 new Thread(new Runnable()
1447 setProgressBar("loading jalview project " + choice,
1451 new Jalview2XML().LoadJalviewAlign(choice);
1452 } catch (OutOfMemoryError oom)
1454 new OOMWarning("Whilst loading project from " + choice, oom);
1455 } catch (Exception ex)
1457 Cache.log.error("Problems whilst loading project from "
1459 JOptionPane.showMessageDialog(Desktop.desktop,
1460 "Error whilst loading project from " + choice,
1461 "Couldn't load project", JOptionPane.WARNING_MESSAGE);
1463 setProgressBar(null, choice.hashCode());
1469 public void inputSequence_actionPerformed(ActionEvent e)
1471 new SequenceFetcher(this);
1474 JPanel progressPanel;
1476 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1478 public void startLoading(final String fileName)
1480 if (fileLoadingCount == 0)
1482 fileLoadingPanels.add(addProgressPanel("Loading File: " + fileName
1488 private JPanel addProgressPanel(String string)
1490 if (progressPanel == null)
1492 progressPanel = new JPanel(new GridLayout(1, 1));
1493 totalProgressCount = 0;
1494 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1496 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1497 JProgressBar progressBar = new JProgressBar();
1498 progressBar.setIndeterminate(true);
1500 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1502 thisprogress.add(progressBar, BorderLayout.CENTER);
1503 progressPanel.add(thisprogress);
1504 ((GridLayout) progressPanel.getLayout())
1505 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1506 ++totalProgressCount;
1507 instance.validate();
1508 return thisprogress;
1511 int totalProgressCount = 0;
1513 private void removeProgressPanel(JPanel progbar)
1515 if (progressPanel != null)
1517 progressPanel.remove(progbar);
1518 GridLayout gl = (GridLayout) progressPanel.getLayout();
1519 gl.setRows(gl.getRows() - 1);
1520 if (--totalProgressCount < 1)
1522 this.getContentPane().remove(progressPanel);
1523 progressPanel = null;
1529 public void stopLoading()
1532 if (fileLoadingCount < 1)
1534 for (JPanel flp : fileLoadingPanels)
1536 removeProgressPanel(flp);
1538 fileLoadingPanels.clear();
1539 fileLoadingCount = 0;
1544 public static int getViewCount(String alignmentId)
1546 AlignViewport[] aps = getViewports(alignmentId);
1547 return (aps == null) ? 0 : aps.length;
1552 * @param alignmentId
1553 * @return all AlignmentPanels concerning the alignmentId sequence set
1555 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1558 if (Desktop.desktop == null)
1560 // no frames created and in headless mode
1561 // TODO: verify that frames are recoverable when in headless mode
1564 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1565 ArrayList aps = new ArrayList();
1566 for (int t = 0; t < frames.length; t++)
1568 if (frames[t] instanceof AlignFrame)
1570 AlignFrame af = (AlignFrame) frames[t];
1571 for (int a = 0; a < af.alignPanels.size(); a++)
1573 if (alignmentId.equals(((AlignmentPanel) af.alignPanels
1574 .elementAt(a)).av.getSequenceSetId()))
1576 aps.add(af.alignPanels.elementAt(a));
1581 if (aps.size() == 0)
1585 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1586 for (int t = 0; t < vap.length; t++)
1588 vap[t] = (AlignmentPanel) aps.get(t);
1594 * get all the viewports on an alignment.
1596 * @param sequenceSetId
1597 * unique alignment id
1598 * @return all viewports on the alignment bound to sequenceSetId
1600 public static AlignViewport[] getViewports(String sequenceSetId)
1602 Vector viewp = new Vector();
1603 if (desktop != null)
1605 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1607 for (int t = 0; t < frames.length; t++)
1609 if (frames[t] instanceof AlignFrame)
1611 AlignFrame afr = ((AlignFrame) frames[t]);
1612 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1614 if (afr.alignPanels != null)
1616 for (int a = 0; a < afr.alignPanels.size(); a++)
1618 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1619 .elementAt(a)).av.getSequenceSetId()))
1621 viewp.addElement(((AlignmentPanel) afr.alignPanels
1628 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1633 if (viewp.size() > 0)
1635 AlignViewport[] vp = new AlignViewport[viewp.size()];
1643 public void explodeViews(AlignFrame af)
1645 int size = af.alignPanels.size();
1651 for (int i = 0; i < size; i++)
1653 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1654 AlignFrame newaf = new AlignFrame(ap);
1655 if (ap.av.explodedPosition != null
1656 && !ap.av.explodedPosition.equals(af.getBounds()))
1658 newaf.setBounds(ap.av.explodedPosition);
1661 ap.av.gatherViewsHere = false;
1663 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1664 AlignFrame.DEFAULT_HEIGHT);
1667 af.alignPanels.clear();
1668 af.closeMenuItem_actionPerformed(true);
1672 public void gatherViews(AlignFrame source)
1674 source.viewport.gatherViewsHere = true;
1675 source.viewport.explodedPosition = source.getBounds();
1676 JInternalFrame[] frames = desktop.getAllFrames();
1677 String viewId = source.viewport.getSequenceSetId();
1679 for (int t = 0; t < frames.length; t++)
1681 if (frames[t] instanceof AlignFrame && frames[t] != source)
1683 AlignFrame af = (AlignFrame) frames[t];
1684 boolean gatherThis = false;
1685 for (int a = 0; a < af.alignPanels.size(); a++)
1687 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1688 if (viewId.equals(ap.av.getSequenceSetId()))
1691 ap.av.gatherViewsHere = false;
1692 ap.av.explodedPosition = af.getBounds();
1693 source.addAlignmentPanel(ap, false);
1699 af.alignPanels.clear();
1700 af.closeMenuItem_actionPerformed(true);
1707 jalview.gui.VamsasApplication v_client = null;
1709 public void vamsasImport_actionPerformed(ActionEvent e)
1711 if (v_client == null)
1713 // Load and try to start a session.
1714 JalviewFileChooser chooser = new JalviewFileChooser(
1715 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1717 chooser.setFileView(new JalviewFileView());
1718 chooser.setDialogTitle("Open a saved VAMSAS session");
1719 chooser.setToolTipText("select a vamsas session to be opened as a new vamsas session.");
1721 int value = chooser.showOpenDialog(this);
1723 if (value == JalviewFileChooser.APPROVE_OPTION)
1725 String fle = chooser.getSelectedFile().toString();
1726 if (!vamsasImport(chooser.getSelectedFile()))
1728 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1729 MessageManager.formatMessage("label.couldnt_import_as_vamsas_session", new String[]{fle}),
1730 MessageManager.getString("label.vamsas_document_import_failed"),
1731 JOptionPane.ERROR_MESSAGE);
1737 jalview.bin.Cache.log
1738 .error("Implementation error - load session from a running session is not supported.");
1743 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1746 * @return true if import was a success and a session was started.
1748 public boolean vamsasImport(URL url)
1750 // TODO: create progress bar
1751 if (v_client != null)
1754 jalview.bin.Cache.log
1755 .error("Implementation error - load session from a running session is not supported.");
1761 // copy the URL content to a temporary local file
1762 // TODO: be a bit cleverer here with nio (?!)
1763 File file = File.createTempFile("vdocfromurl", ".vdj");
1764 FileOutputStream fos = new FileOutputStream(file);
1765 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1766 byte[] buffer = new byte[2048];
1768 while ((ln = bis.read(buffer)) > -1)
1770 fos.write(buffer, 0, ln);
1774 v_client = new jalview.gui.VamsasApplication(this, file,
1775 url.toExternalForm());
1776 } catch (Exception ex)
1778 jalview.bin.Cache.log.error(
1779 "Failed to create new vamsas session from contents of URL "
1783 setupVamsasConnectedGui();
1784 v_client.initial_update(); // TODO: thread ?
1785 return v_client.inSession();
1789 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1792 * @return true if import was a success and a session was started.
1794 public boolean vamsasImport(File file)
1796 if (v_client != null)
1799 jalview.bin.Cache.log
1800 .error("Implementation error - load session from a running session is not supported.");
1804 setProgressBar("Importing VAMSAS session from " + file.getName(),
1808 v_client = new jalview.gui.VamsasApplication(this, file, null);
1809 } catch (Exception ex)
1811 setProgressBar("Importing VAMSAS session from " + file.getName(),
1813 jalview.bin.Cache.log.error(
1814 "New vamsas session from existing session file failed:", ex);
1817 setupVamsasConnectedGui();
1818 v_client.initial_update(); // TODO: thread ?
1819 setProgressBar("Importing VAMSAS session from " + file.getName(),
1821 return v_client.inSession();
1824 public boolean joinVamsasSession(String mysesid)
1826 if (v_client != null)
1829 "Trying to join a vamsas session when another is already connected.");
1831 if (mysesid == null)
1833 throw new Error("Invalid vamsas session id.");
1835 v_client = new VamsasApplication(this, mysesid);
1836 setupVamsasConnectedGui();
1837 v_client.initial_update();
1838 return (v_client.inSession());
1841 public void vamsasStart_actionPerformed(ActionEvent e)
1843 if (v_client == null)
1846 // we just start a default session for moment.
1848 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1849 * getProperty("LAST_DIRECTORY"));
1851 * chooser.setFileView(new JalviewFileView());
1852 * chooser.setDialogTitle("Load Vamsas file");
1853 * chooser.setToolTipText("Import");
1855 * int value = chooser.showOpenDialog(this);
1857 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1858 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1860 v_client = new VamsasApplication(this);
1861 setupVamsasConnectedGui();
1862 v_client.initial_update(); // TODO: thread ?
1866 // store current data in session.
1867 v_client.push_update(); // TODO: thread
1871 protected void setupVamsasConnectedGui()
1873 vamsasStart.setText(MessageManager.getString("label.session_update"));
1874 vamsasSave.setVisible(true);
1875 vamsasStop.setVisible(true);
1876 vamsasImport.setVisible(false); // Document import to existing session is
1877 // not possible for vamsas-client-1.0.
1880 protected void setupVamsasDisconnectedGui()
1882 vamsasSave.setVisible(false);
1883 vamsasStop.setVisible(false);
1884 vamsasImport.setVisible(true);
1885 vamsasStart.setText(MessageManager.getString("label.new_vamsas_session"));
1888 public void vamsasStop_actionPerformed(ActionEvent e)
1890 if (v_client != null)
1892 v_client.end_session();
1894 setupVamsasDisconnectedGui();
1898 protected void buildVamsasStMenu()
1900 if (v_client == null)
1902 String[] sess = null;
1905 sess = VamsasApplication.getSessionList();
1906 } catch (Exception e)
1908 jalview.bin.Cache.log.warn(
1909 "Problem getting current sessions list.", e);
1914 jalview.bin.Cache.log.debug("Got current sessions list: "
1915 + sess.length + " entries.");
1916 VamsasStMenu.removeAll();
1917 for (int i = 0; i < sess.length; i++)
1919 JMenuItem sessit = new JMenuItem();
1920 sessit.setText(sess[i]);
1921 sessit.setToolTipText("Connect to session " + sess[i]);
1922 final Desktop dsktp = this;
1923 final String mysesid = sess[i];
1924 sessit.addActionListener(new ActionListener()
1927 public void actionPerformed(ActionEvent e)
1929 if (dsktp.v_client == null)
1931 Thread rthr = new Thread(new Runnable()
1936 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1937 dsktp.setupVamsasConnectedGui();
1938 dsktp.v_client.initial_update();
1946 VamsasStMenu.add(sessit);
1948 // don't show an empty menu.
1949 VamsasStMenu.setVisible(sess.length > 0);
1954 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1955 VamsasStMenu.removeAll();
1956 VamsasStMenu.setVisible(false);
1961 // Not interested in the content. Just hide ourselves.
1962 VamsasStMenu.setVisible(false);
1966 public void vamsasSave_actionPerformed(ActionEvent e)
1968 if (v_client != null)
1970 JalviewFileChooser chooser = new JalviewFileChooser(
1971 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1972 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1974 { "Vamsas Document" }, "Vamsas Document");
1976 chooser.setFileView(new JalviewFileView());
1977 chooser.setDialogTitle("Save Vamsas Document Archive");
1979 int value = chooser.showSaveDialog(this);
1981 if (value == JalviewFileChooser.APPROVE_OPTION)
1983 java.io.File choice = chooser.getSelectedFile();
1984 JPanel progpanel = addProgressPanel("Saving VAMSAS Document to "
1985 + choice.getName());
1986 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1987 String warnmsg = null;
1988 String warnttl = null;
1991 v_client.vclient.storeDocument(choice);
1994 warnttl = "Serious Problem saving Vamsas Document";
1995 warnmsg = ex.toString();
1996 jalview.bin.Cache.log.error("Error Whilst saving document to "
1999 } catch (Exception ex)
2001 warnttl = "Problem saving Vamsas Document.";
2002 warnmsg = ex.toString();
2003 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2007 removeProgressPanel(progpanel);
2008 if (warnmsg != null)
2010 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2012 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2018 JPanel vamUpdate = null;
2021 * hide vamsas user gui bits when a vamsas document event is being handled.
2024 * true to hide gui, false to reveal gui
2026 public void setVamsasUpdate(boolean b)
2028 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2029 + (b ? "in progress" : "finished"));
2031 if (vamUpdate != null)
2033 this.removeProgressPanel(vamUpdate);
2037 vamUpdate = this.addProgressPanel("Updating vamsas session");
2039 vamsasStart.setVisible(!b);
2040 vamsasStop.setVisible(!b);
2041 vamsasSave.setVisible(!b);
2044 public JInternalFrame[] getAllFrames()
2046 return desktop.getAllFrames();
2050 * Checks the given url to see if it gives a response indicating that the user
2051 * should be informed of a new questionnaire.
2055 public void checkForQuestionnaire(String url)
2057 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2058 // javax.swing.SwingUtilities.invokeLater(jvq);
2059 new Thread(jvq).start();
2063 * Proxy class for JDesktopPane which optionally displays the current memory
2064 * usage and highlights the desktop area with a red bar if free memory runs
2069 public class MyDesktopPane extends JDesktopPane implements Runnable
2072 boolean showMemoryUsage = false;
2076 java.text.NumberFormat df;
2078 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2081 public MyDesktopPane(boolean showMemoryUsage)
2083 showMemoryUsage(showMemoryUsage);
2086 public void showMemoryUsage(boolean showMemoryUsage)
2088 this.showMemoryUsage = showMemoryUsage;
2089 if (showMemoryUsage)
2091 Thread worker = new Thread(this);
2096 public boolean isShowMemoryUsage()
2098 return showMemoryUsage;
2103 df = java.text.NumberFormat.getNumberInstance();
2104 df.setMaximumFractionDigits(2);
2105 runtime = Runtime.getRuntime();
2107 while (showMemoryUsage)
2111 maxMemory = runtime.maxMemory() / 1048576f;
2112 allocatedMemory = runtime.totalMemory() / 1048576f;
2113 freeMemory = runtime.freeMemory() / 1048576f;
2114 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2116 percentUsage = (totalFreeMemory / maxMemory) * 100;
2118 // if (percentUsage < 20)
2120 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2122 // instance.set.setBorder(border1);
2125 // sleep after showing usage
2127 } catch (Exception ex)
2129 ex.printStackTrace();
2134 public void paintComponent(Graphics g)
2136 if (showMemoryUsage && g != null && df != null)
2138 if (percentUsage < 20)
2139 g.setColor(Color.red);
2140 FontMetrics fm = g.getFontMetrics();
2144 MessageManager.formatMessage("label.memory_stats", new String[]{df.format(totalFreeMemory),df.format(maxMemory),df.format(percentUsage)}), 10,
2145 getHeight() - fm.getHeight());
2152 * fixes stacking order after a modal dialog to ensure windows that should be
2153 * on top actually are
2155 public void relayerWindows()
2160 protected JMenuItem groovyShell;
2162 public void doGroovyCheck()
2164 if (jalview.bin.Cache.groovyJarsPresent())
2166 groovyShell = new JMenuItem();
2167 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2168 groovyShell.addActionListener(new ActionListener()
2170 public void actionPerformed(ActionEvent e)
2172 groovyShell_actionPerformed(e);
2175 toolsMenu.add(groovyShell);
2176 groovyShell.setVisible(true);
2181 * Accessor method to quickly get all the AlignmentFrames loaded.
2183 public static AlignFrame[] getAlignframes()
2185 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2191 Vector avp = new Vector();
2195 for (int i = frames.length - 1; i > -1; i--)
2197 if (frames[i] instanceof AlignFrame)
2199 AlignFrame af = (AlignFrame) frames[i];
2203 } catch (Exception ex)
2205 ex.printStackTrace();
2207 if (avp.size() == 0)
2211 AlignFrame afs[] = new AlignFrame[avp.size()];
2212 for (int i = 0, j = avp.size(); i < j; i++)
2214 afs[i] = (AlignFrame) avp.elementAt(i);
2220 public AppJmol[] getJmols()
2222 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2228 Vector avp = new Vector();
2232 for (int i = frames.length - 1; i > -1; i--)
2234 if (frames[i] instanceof AppJmol)
2236 AppJmol af = (AppJmol) frames[i];
2240 } catch (Exception ex)
2242 ex.printStackTrace();
2244 if (avp.size() == 0)
2248 AppJmol afs[] = new AppJmol[avp.size()];
2249 for (int i = 0, j = avp.size(); i < j; i++)
2251 afs[i] = (AppJmol) avp.elementAt(i);
2258 * Add Groovy Support to Jalview
2260 public void groovyShell_actionPerformed(ActionEvent e)
2262 // use reflection to avoid creating compilation dependency.
2263 if (!jalview.bin.Cache.groovyJarsPresent())
2266 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
2270 Class gcClass = Desktop.class.getClassLoader().loadClass(
2271 "groovy.ui.Console");
2272 Constructor gccons = gcClass.getConstructor(null);
2273 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2275 { String.class, Object.class });
2276 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2277 Object gc = gccons.newInstance(null);
2278 setvar.invoke(gc, new Object[]
2279 { "Jalview", this });
2280 run.invoke(gc, null);
2281 } catch (Exception ex)
2283 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2285 .showInternalMessageDialog(
2288 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
2289 "Jalview Groovy Support Failed",
2290 JOptionPane.ERROR_MESSAGE);
2295 * Progress bars managed by the IProgressIndicator method.
2297 private Hashtable<Long, JPanel> progressBars;
2299 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2304 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2306 public void setProgressBar(String message, long id)
2308 if (progressBars == null)
2310 progressBars = new Hashtable<Long, JPanel>();
2311 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2314 if (progressBars.get(new Long(id)) != null)
2316 JPanel progressPanel = progressBars.remove(new Long(id));
2317 if (progressBarHandlers.contains(new Long(id)))
2319 progressBarHandlers.remove(new Long(id));
2321 removeProgressPanel(progressPanel);
2325 progressBars.put(new Long(id), addProgressPanel(message));
2332 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2333 * jalview.gui.IProgressIndicatorHandler)
2335 public void registerHandler(final long id,
2336 final IProgressIndicatorHandler handler)
2338 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2341 "call setProgressBar before registering the progress bar's handler.");
2343 progressBarHandlers.put(new Long(id), handler);
2344 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
2345 if (handler.canCancel())
2347 JButton cancel = new JButton(MessageManager.getString("action.cancel"));
2348 final IProgressIndicator us = this;
2349 cancel.addActionListener(new ActionListener()
2352 public void actionPerformed(ActionEvent e)
2354 handler.cancelActivity(id);
2357 + ((JLabel) progressPanel.getComponent(0))
2361 progressPanel.add(cancel, BorderLayout.EAST);
2367 * @return true if any progress bars are still active
2370 public boolean operationInProgress()
2372 if (progressBars != null && progressBars.size() > 0)
2380 * This will return the first AlignFrame viewing AlignViewport av. It will
2381 * break if there are more than one AlignFrames viewing a particular av. This
2384 * @return alignFrame for av
2386 public static AlignFrame getAlignFrameFor(AlignViewport av)
2388 if (desktop != null)
2390 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2391 for (int panel = 0; aps != null && panel < aps.length; panel++)
2393 if (aps[panel] != null && aps[panel].av == av)
2395 return aps[panel].alignFrame;
2402 public VamsasApplication getVamsasApplication()
2409 * flag set if jalview GUI is being operated programmatically
2411 private boolean inBatchMode = false;
2414 * check if jalview GUI is being operated programmatically
2416 * @return inBatchMode
2418 public boolean isInBatchMode()
2424 * set flag if jalview GUI is being operated programmatically
2426 * @param inBatchMode
2428 public void setInBatchMode(boolean inBatchMode)
2430 this.inBatchMode = inBatchMode;
2433 public void startServiceDiscovery()
2435 startServiceDiscovery(false);
2438 public void startServiceDiscovery(boolean blocking)
2440 boolean alive = true;
2441 Thread t0 = null, t1 = null, t2 = null;
2442 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2445 // todo: changesupport handlers need to be transferred
2446 if (discoverer == null)
2448 discoverer = new jalview.ws.jws1.Discoverer();
2449 // register PCS handler for desktop.
2450 discoverer.addPropertyChangeListener(changeSupport);
2452 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2453 // until we phase out completely
2454 (t0 = new Thread(discoverer)).start();
2457 // ENFIN services are EOLed as of Jalview 2.8.1 release
2462 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2464 // EnfinEnvision web service menu entries are rebuild every time the
2465 // menu is shown, so no changeSupport events are needed.
2466 jalview.ws.EnfinEnvision2OneWay.getInstance();
2467 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2470 } catch (Exception e)
2473 .info("Exception when trying to launch Envision2 workflow discovery.",
2475 Cache.log.info(e.getStackTrace());
2479 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2481 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2483 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2485 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2491 // TODO: do rest service discovery
2500 } catch (Exception e)
2503 alive = (t1 != null && t1.isAlive())
2504 || (t2 != null && t2.isAlive())
2505 || (t3 != null && t3.isAlive())
2506 || (t0 != null && t0.isAlive());
2512 * called to check if the service discovery process completed successfully.
2516 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2518 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2520 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2521 .getErrorMessages();
2524 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2526 if (serviceChangedDialog == null)
2528 // only run if we aren't already displaying one of these.
2529 addDialogThread(serviceChangedDialog = new Runnable()
2535 * JalviewDialog jd =new JalviewDialog() {
2537 * @Override protected void cancelPressed() { // TODO
2538 * Auto-generated method stub
2540 * }@Override protected void okPressed() { // TODO
2541 * Auto-generated method stub
2543 * }@Override protected void raiseClosed() { // TODO
2544 * Auto-generated method stub
2546 * } }; jd.initDialogFrame(new
2547 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2548 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2549 * + " or mis-configured HTTP proxy settings.<br/>" +
2550 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2552 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2553 * ), true, true, "Web Service Configuration Problem", 450,
2556 * jd.waitForInput();
2562 "<html><table width=\"450\"><tr><td>"
2564 + "</td></tr></table>"
2565 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2566 + " or mis-configured HTTP proxy settings.</p>"
2567 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2568 + " Tools->Preferences dialog box to change them.</p></html>"),
2569 "Web Service Configuration Problem",
2570 JOptionPane.DEFAULT_OPTION,
2571 JOptionPane.ERROR_MESSAGE);
2572 serviceChangedDialog = null;
2581 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2588 private Runnable serviceChangedDialog = null;
2591 * start a thread to open a URL in the configured browser. Pops up a warning
2592 * dialog to the user if there is an exception when calling out to the browser
2597 public static void showUrl(final String url)
2599 showUrl(url, Desktop.instance);
2603 * Like showUrl but allows progress handler to be specified
2607 * (null) or object implementing IProgressIndicator
2609 public static void showUrl(final String url,
2610 final IProgressIndicator progress)
2612 new Thread(new Runnable()
2618 if (progress != null)
2620 progress.setProgressBar("Opening " + url, this.hashCode());
2622 jalview.util.BrowserLauncher.openURL(url);
2623 } catch (Exception ex)
2626 .showInternalMessageDialog(
2628 "Unixers: Couldn't find default web browser."
2629 + "\nAdd the full path to your browser in Preferences.",
2630 "Web browser not found",
2631 JOptionPane.WARNING_MESSAGE);
2633 ex.printStackTrace();
2635 if (progress != null)
2637 progress.setProgressBar(null, this.hashCode());
2643 public static WsParamSetManager wsparamManager = null;
2645 public static ParamManager getUserParameterStore()
2647 if (wsparamManager == null)
2649 wsparamManager = new WsParamSetManager();
2651 return wsparamManager;
2655 * static hyperlink handler proxy method for use by Jalview's internal windows
2659 public static void hyperlinkUpdate(HyperlinkEvent e)
2661 if (e.getEventType() == EventType.ACTIVATED)
2666 url = e.getURL().toString();
2667 Desktop.showUrl(url);
2668 } catch (Exception x)
2672 if (Cache.log != null)
2674 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2678 System.err.println("Couldn't handle string " + url
2682 // ignore any exceptions due to dud links.
2689 * single thread that handles display of dialogs to user.
2691 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2694 * flag indicating if dialogExecutor should try to acquire a permit
2696 private volatile boolean dialogPause = true;
2701 private java.util.concurrent.Semaphore block = new Semaphore(0);
2704 * add another dialog thread to the queue
2708 public void addDialogThread(final Runnable prompter)
2710 dialogExecutor.submit(new Runnable()
2719 } catch (InterruptedException x)
2724 if (instance == null)
2730 SwingUtilities.invokeAndWait(prompter);
2731 } catch (Exception q)
2733 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2739 public void startDialogQueue()
2741 // set the flag so we don't pause waiting for another permit and semaphore
2742 // the current task to begin
2743 dialogPause = false;