2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
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
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.bin.Cache;
24 import jalview.io.FileLoader;
25 import jalview.io.FormatAdapter;
26 import jalview.io.IdentifyFile;
27 import jalview.io.JalviewFileChooser;
28 import jalview.io.JalviewFileView;
29 import jalview.structure.StructureSelectionManager;
30 import jalview.util.ImageMaker;
31 import jalview.util.MessageManager;
32 import jalview.ws.params.ParamManager;
34 import java.awt.BorderLayout;
35 import java.awt.Color;
36 import java.awt.Dimension;
37 import java.awt.FontMetrics;
38 import java.awt.Graphics;
39 import java.awt.GridLayout;
40 import java.awt.Point;
41 import java.awt.Rectangle;
42 import java.awt.Toolkit;
43 import java.awt.datatransfer.Clipboard;
44 import java.awt.datatransfer.ClipboardOwner;
45 import java.awt.datatransfer.DataFlavor;
46 import java.awt.datatransfer.Transferable;
47 import java.awt.dnd.DnDConstants;
48 import java.awt.dnd.DropTargetDragEvent;
49 import java.awt.dnd.DropTargetDropEvent;
50 import java.awt.dnd.DropTargetEvent;
51 import java.awt.dnd.DropTargetListener;
52 import java.awt.event.ActionEvent;
53 import java.awt.event.ActionListener;
54 import java.awt.event.FocusEvent;
55 import java.awt.event.FocusListener;
56 import java.awt.event.MouseAdapter;
57 import java.awt.event.MouseEvent;
58 import java.awt.event.MouseListener;
59 import java.awt.event.WindowAdapter;
60 import java.awt.event.WindowEvent;
61 import java.beans.PropertyChangeEvent;
62 import java.beans.PropertyChangeListener;
63 import java.beans.PropertyVetoException;
64 import java.io.BufferedInputStream;
66 import java.io.FileOutputStream;
67 import java.lang.reflect.Constructor;
69 import java.util.ArrayList;
70 import java.util.Hashtable;
71 import java.util.StringTokenizer;
72 import java.util.Vector;
73 import java.util.concurrent.ExecutorService;
74 import java.util.concurrent.Executors;
75 import java.util.concurrent.Semaphore;
77 import javax.swing.DefaultDesktopManager;
78 import javax.swing.DesktopManager;
79 import javax.swing.JButton;
80 import javax.swing.JComboBox;
81 import javax.swing.JComponent;
82 import javax.swing.JDesktopPane;
83 import javax.swing.JFrame;
84 import javax.swing.JInternalFrame;
85 import javax.swing.JLabel;
86 import javax.swing.JMenuItem;
87 import javax.swing.JOptionPane;
88 import javax.swing.JPanel;
89 import javax.swing.JPopupMenu;
90 import javax.swing.JProgressBar;
91 import javax.swing.SwingUtilities;
92 import javax.swing.event.HyperlinkEvent;
93 import javax.swing.event.HyperlinkEvent.EventType;
94 import javax.swing.event.MenuEvent;
95 import javax.swing.event.MenuListener;
102 * @version $Revision: 1.155 $
104 public class Desktop extends jalview.jbgui.GDesktop implements
105 DropTargetListener, ClipboardOwner, IProgressIndicator,
106 jalview.api.StructureSelectionManagerProvider
109 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
112 * news reader - null if it was never started.
114 private BlogReader jvnews = null;
118 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
120 public void addJalviewPropertyChangeListener(
121 PropertyChangeListener listener)
123 changeSupport.addJalviewPropertyChangeListener(listener);
127 * @param propertyName
129 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
130 * java.beans.PropertyChangeListener)
132 public void addJalviewPropertyChangeListener(String propertyName,
133 PropertyChangeListener listener)
135 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
139 * @param propertyName
141 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
142 * java.beans.PropertyChangeListener)
144 public void removeJalviewPropertyChangeListener(String propertyName,
145 PropertyChangeListener listener)
147 changeSupport.removeJalviewPropertyChangeListener(propertyName,
151 /** Singleton Desktop instance */
152 public static Desktop instance;
154 public static MyDesktopPane desktop;
156 static int openFrameCount = 0;
158 static final int xOffset = 30;
160 static final int yOffset = 30;
162 public static jalview.ws.jws1.Discoverer discoverer;
164 public static Object[] jalviewClipboard;
166 public static boolean internalCopy = false;
168 static int fileLoadingCount = 0;
170 class MyDesktopManager implements DesktopManager
173 private DesktopManager delegate;
175 public MyDesktopManager(DesktopManager delegate)
177 this.delegate = delegate;
180 public void activateFrame(JInternalFrame f)
184 delegate.activateFrame(f);
185 } catch (NullPointerException npe)
187 Point p = getMousePosition();
188 instance.showPasteMenu(p.x, p.y);
192 public void beginDraggingFrame(JComponent f)
194 delegate.beginDraggingFrame(f);
197 public void beginResizingFrame(JComponent f, int direction)
199 delegate.beginResizingFrame(f, direction);
202 public void closeFrame(JInternalFrame f)
204 delegate.closeFrame(f);
207 public void deactivateFrame(JInternalFrame f)
209 delegate.deactivateFrame(f);
212 public void deiconifyFrame(JInternalFrame f)
214 delegate.deiconifyFrame(f);
217 public void dragFrame(JComponent f, int newX, int newY)
223 delegate.dragFrame(f, newX, newY);
226 public void endDraggingFrame(JComponent f)
228 delegate.endDraggingFrame(f);
231 public void endResizingFrame(JComponent f)
233 delegate.endResizingFrame(f);
236 public void iconifyFrame(JInternalFrame f)
238 delegate.iconifyFrame(f);
241 public void maximizeFrame(JInternalFrame f)
243 delegate.maximizeFrame(f);
246 public void minimizeFrame(JInternalFrame f)
248 delegate.minimizeFrame(f);
251 public void openFrame(JInternalFrame f)
253 delegate.openFrame(f);
256 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
259 Rectangle b = desktop.getBounds();
264 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
267 public void setBoundsForFrame(JComponent f, int newX, int newY,
268 int newWidth, int newHeight)
270 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
273 // All other methods, simply delegate
278 * Creates a new Desktop object.
283 * A note to implementors. It is ESSENTIAL that any activities that might
284 * block are spawned off as threads rather than waited for during this
288 doVamsasClientCheck();
290 doConfigureStructurePrefs();
291 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
292 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
293 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
295 boolean showjconsole = jalview.bin.Cache.getDefault(
296 "SHOW_JAVA_CONSOLE", false);
297 desktop = new MyDesktopPane(selmemusage);
298 showMemusage.setSelected(selmemusage);
299 desktop.setBackground(Color.white);
300 getContentPane().setLayout(new BorderLayout());
301 // alternate config - have scrollbars - see notes in JAL-153
302 // JScrollPane sp = new JScrollPane();
303 // sp.getViewport().setView(desktop);
304 // getContentPane().add(sp, BorderLayout.CENTER);
305 getContentPane().add(desktop, BorderLayout.CENTER);
306 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
308 // This line prevents Windows Look&Feel resizing all new windows to maximum
309 // if previous window was maximised
310 desktop.setDesktopManager(new MyDesktopManager(
311 new DefaultDesktopManager()));
313 Rectangle dims = getLastKnownDimensions("");
320 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
321 setBounds((screenSize.width - 900) / 2,
322 (screenSize.height - 650) / 2, 900, 650);
324 jconsole = new Console(this, showjconsole);
325 // add essential build information
326 jconsole.setHeader("Jalview Version: "
327 + jalview.bin.Cache.getProperty("VERSION") + "\n"
328 + "Jalview Installation: "
329 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
332 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
333 + "Java version: " + System.getProperty("java.version") + "\n"
334 + System.getProperty("os.arch") + " "
335 + System.getProperty("os.name") + " "
336 + System.getProperty("os.version"));
338 showConsole(showjconsole);
340 showNews.setVisible(false);
342 this.addWindowListener(new WindowAdapter()
344 public void windowClosing(WindowEvent evt)
351 this.addMouseListener(ma = new MouseAdapter()
353 public void mousePressed(MouseEvent evt)
355 if (SwingUtilities.isRightMouseButton(evt))
357 showPasteMenu(evt.getX(), evt.getY());
361 desktop.addMouseListener(ma);
363 this.addFocusListener(new FocusListener()
367 public void focusLost(FocusEvent e)
369 // TODO Auto-generated method stub
374 public void focusGained(FocusEvent e)
376 Cache.log.debug("Relaying windows after focus gain");
377 // make sure that we sort windows properly after we gain focus
378 instance.relayerWindows();
381 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
382 // Spawn a thread that shows the splashscreen
383 SwingUtilities.invokeLater(new Runnable()
392 // Thread off a new instance of the file chooser - this reduces the time it
393 // takes to open it later on.
394 new Thread(new Runnable()
398 Cache.log.debug("Filechooser init thread started.");
399 JalviewFileChooser chooser = new JalviewFileChooser(
400 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
401 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
402 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
403 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
404 Cache.log.debug("Filechooser init thread finished.");
407 // Add the service change listener
408 changeSupport.addJalviewPropertyChangeListener("services",
409 new PropertyChangeListener()
413 public void propertyChange(PropertyChangeEvent evt)
415 Cache.log.debug("Firing service changed event for "
416 + evt.getNewValue());
417 JalviewServicesChanged(evt);
423 public void doConfigureStructurePrefs()
425 // configure services
426 StructureSelectionManager ssm = StructureSelectionManager
427 .getStructureSelectionManager(this);
428 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
430 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
431 Preferences.ADD_TEMPFACT_ANN, true));
432 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(Preferences.STRUCT_FROM_PDB, true));
433 ssm.setSecStructServices(jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW,
438 ssm.setAddTempFacAnnot(false);
439 ssm.setProcessSecondaryStructure(false);
440 ssm.setSecStructServices(false);
444 public void checkForNews()
446 final Desktop me = this;
447 // Thread off the news reader, in case there are connection problems.
448 addDialogThread(new Runnable()
453 Cache.log.debug("Starting news thread.");
455 jvnews = new BlogReader(me);
456 showNews.setVisible(true);
457 Cache.log.debug("Completed news thread.");
462 protected void showNews_actionPerformed(ActionEvent e)
464 showNews(showNews.isSelected());
467 void showNews(boolean visible)
470 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
471 showNews.setSelected(visible);
472 if (visible && !jvnews.isVisible())
474 new Thread(new Runnable()
479 long instance = System.currentTimeMillis();
480 Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_news"), instance);
481 jvnews.refreshNews();
482 Desktop.instance.setProgressBar(null, instance);
491 * recover the last known dimensions for a jalview window
494 * - empty string is desktop, all other windows have unique prefix
495 * @return null or last known dimensions scaled to current geometry (if last
496 * window geom was known)
498 Rectangle getLastKnownDimensions(String windowName)
500 // TODO: lock aspect ratio for scaling desktop Bug #0058199
501 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
502 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
503 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
504 String width = jalview.bin.Cache.getProperty(windowName
506 String height = jalview.bin.Cache.getProperty(windowName
508 if ((x != null) && (y != null) && (width != null) && (height != null))
510 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
511 .parseInt(width), ih = Integer.parseInt(height);
512 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
514 // attempt #1 - try to cope with change in screen geometry - this
515 // version doesn't preserve original jv aspect ratio.
516 // take ratio of current screen size vs original screen size.
517 double sw = ((1f * screenSize.width) / (1f * Integer
518 .parseInt(jalview.bin.Cache
519 .getProperty("SCREENGEOMETRY_WIDTH"))));
520 double sh = ((1f * screenSize.height) / (1f * Integer
521 .parseInt(jalview.bin.Cache
522 .getProperty("SCREENGEOMETRY_HEIGHT"))));
523 // rescale the bounds depending upon the current screen geometry.
524 ix = (int) (ix * sw);
525 iw = (int) (iw * sw);
526 iy = (int) (iy * sh);
527 ih = (int) (ih * sh);
528 while (ix >= screenSize.width)
530 jalview.bin.Cache.log
531 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
532 ix -= screenSize.width;
534 while (iy >= screenSize.height)
536 jalview.bin.Cache.log
537 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
538 iy -= screenSize.height;
540 jalview.bin.Cache.log.debug("Got last known dimensions for "
541 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
544 // return dimensions for new instance
545 return new Rectangle(ix, iy, iw, ih);
550 private void doVamsasClientCheck()
552 if (jalview.bin.Cache.vamsasJarsPresent())
554 setupVamsasDisconnectedGui();
555 VamsasMenu.setVisible(true);
556 final Desktop us = this;
557 VamsasMenu.addMenuListener(new MenuListener()
559 // this listener remembers when the menu was first selected, and
560 // doesn't rebuild the session list until it has been cleared and
562 boolean refresh = true;
564 public void menuCanceled(MenuEvent e)
569 public void menuDeselected(MenuEvent e)
574 public void menuSelected(MenuEvent e)
578 us.buildVamsasStMenu();
583 vamsasStart.setVisible(true);
587 void showPasteMenu(int x, int y)
589 JPopupMenu popup = new JPopupMenu();
590 JMenuItem item = new JMenuItem(
591 MessageManager.getString("label.paste_new_window"));
592 item.addActionListener(new ActionListener()
594 public void actionPerformed(ActionEvent evt)
601 popup.show(this, x, y);
608 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
609 Transferable contents = c.getContents(this);
611 if (contents != null)
613 String file = (String) contents
614 .getTransferData(DataFlavor.stringFlavor);
616 String format = new IdentifyFile().Identify(file,
617 FormatAdapter.PASTE);
619 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
622 } catch (Exception ex)
625 .println("Unable to paste alignment from system clipboard:\n"
631 * Adds and opens the given frame to the desktop
642 public static synchronized void addInternalFrame(
643 final JInternalFrame frame, String title, int w, int h)
645 addInternalFrame(frame, title, true, w, h, true);
650 * Add an internal frame to the Jalview desktop
657 * When true, display frame immediately, otherwise, caller must call
658 * setVisible themselves.
664 public static synchronized void addInternalFrame(
665 final JInternalFrame frame, String title, boolean makeVisible,
668 addInternalFrame(frame, title, makeVisible, w, h, true);
672 * Add an internal frame to the Jalview desktop and make it visible
685 public static synchronized void addInternalFrame(
686 final JInternalFrame frame, String title, int w, int h,
689 addInternalFrame(frame, title, true, w, h, resizable);
693 * Add an internal frame to the Jalview desktop
700 * When true, display frame immediately, otherwise, caller must call
701 * setVisible themselves.
709 public static synchronized void addInternalFrame(
710 final JInternalFrame frame, String title, boolean makeVisible,
711 int w, int h, boolean resizable)
714 // TODO: allow callers to determine X and Y position of frame (eg. via
716 // TODO: consider fixing method to update entries in the window submenu with
717 // the current window title
719 frame.setTitle(title);
720 if (frame.getWidth() < 1 || frame.getHeight() < 1)
724 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
725 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
726 // IF JALVIEW IS RUNNING HEADLESS
727 // ///////////////////////////////////////////////
729 || (System.getProperty("java.awt.headless") != null && System
730 .getProperty("java.awt.headless").equals("true")))
737 frame.setVisible(makeVisible);
738 frame.setClosable(true);
739 frame.setResizable(resizable);
740 frame.setMaximizable(resizable);
741 frame.setIconifiable(resizable);
742 frame.setFrameIcon(null);
744 if (frame.getX() < 1 && frame.getY() < 1)
746 frame.setLocation(xOffset * openFrameCount, yOffset
747 * ((openFrameCount - 1) % 10) + yOffset);
750 final JMenuItem menuItem = new JMenuItem(title);
751 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
753 public void internalFrameActivated(
754 javax.swing.event.InternalFrameEvent evt)
756 JInternalFrame itf = desktop.getSelectedFrame();
764 public void internalFrameClosed(
765 javax.swing.event.InternalFrameEvent evt)
767 PaintRefresher.RemoveComponent(frame);
769 windowMenu.remove(menuItem);
770 JInternalFrame itf = desktop.getSelectedFrame();
779 menuItem.addActionListener(new ActionListener()
781 public void actionPerformed(ActionEvent e)
785 frame.setSelected(true);
786 frame.setIcon(false);
787 } catch (java.beans.PropertyVetoException ex)
793 menuItem.addMouseListener(new MouseListener()
797 public void mouseReleased(MouseEvent e)
802 public void mousePressed(MouseEvent e)
807 public void mouseExited(MouseEvent e)
811 frame.setSelected(false);
812 } catch (PropertyVetoException e1)
818 public void mouseEntered(MouseEvent e)
822 frame.setSelected(true);
823 } catch (PropertyVetoException e1)
829 public void mouseClicked(MouseEvent e)
835 windowMenu.add(menuItem);
841 frame.setSelected(true);
842 frame.requestFocus();
843 } catch (java.beans.PropertyVetoException ve)
845 } catch (java.lang.ClassCastException cex)
848 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
853 public void lostOwnership(Clipboard clipboard, Transferable contents)
857 Desktop.jalviewClipboard = null;
860 internalCopy = false;
863 public void dragEnter(DropTargetDragEvent evt)
867 public void dragExit(DropTargetEvent evt)
871 public void dragOver(DropTargetDragEvent evt)
875 public void dropActionChanged(DropTargetDragEvent evt)
885 public void drop(DropTargetDropEvent evt)
887 boolean success = true;
888 Transferable t = evt.getTransferable();
889 java.util.List files = null;
890 java.util.List protocols = null;
894 DataFlavor uriListFlavor = new DataFlavor(
895 "text/uri-list;class=java.lang.String");
896 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
898 // Works on Windows and MacOSX
899 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
900 files = (java.util.List) t
901 .getTransferData(DataFlavor.javaFileListFlavor);
903 else if (t.isDataFlavorSupported(uriListFlavor))
905 // This is used by Unix drag system
906 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
907 String data = (String) t.getTransferData(uriListFlavor);
908 files = new java.util.ArrayList(1);
909 protocols = new java.util.ArrayList(1);
910 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
911 data, "\r\n"); st.hasMoreTokens();)
913 String s = st.nextToken();
914 if (s.startsWith("#"))
916 // the line is a comment (as per the RFC 2483)
919 java.net.URI uri = new java.net.URI(s);
920 if (uri.getScheme().toLowerCase().startsWith("http"))
922 protocols.add(FormatAdapter.URL);
923 files.add(uri.toString());
927 // otherwise preserve old behaviour: catch all for file objects
928 java.io.File file = new java.io.File(uri);
929 protocols.add(FormatAdapter.FILE);
930 files.add(file.toString());
934 } catch (Exception e)
943 for (int i = 0; i < files.size(); i++)
945 String file = files.get(i).toString();
946 String protocol = (protocols == null) ? FormatAdapter.FILE
947 : (String) protocols.get(i);
948 String format = null;
950 if (file.endsWith(".jar"))
957 format = new IdentifyFile().Identify(file, protocol);
960 new FileLoader().LoadFile(file, protocol, format);
963 } catch (Exception ex)
968 evt.dropComplete(success); // need this to ensure input focus is properly
969 // transfered to any new windows created
978 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
980 JalviewFileChooser chooser = new JalviewFileChooser(
981 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
982 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
983 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
984 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
986 chooser.setFileView(new JalviewFileView());
987 chooser.setDialogTitle(MessageManager
988 .getString("label.open_local_file"));
989 chooser.setToolTipText(MessageManager.getString("action.open"));
991 int value = chooser.showOpenDialog(this);
993 if (value == JalviewFileChooser.APPROVE_OPTION)
995 String choice = chooser.getSelectedFile().getPath();
996 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
997 .getSelectedFile().getParent());
999 String format = null;
1000 if (chooser.getSelectedFormat() != null
1001 && chooser.getSelectedFormat().equals("Jalview"))
1007 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1010 if (viewport != null)
1012 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1017 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1028 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1030 // This construct allows us to have a wider textfield
1032 JLabel label = new JLabel(
1033 MessageManager.getString("label.input_file_url"));
1034 final JComboBox history = new JComboBox();
1036 JPanel panel = new JPanel(new GridLayout(2, 1));
1039 history.setPreferredSize(new Dimension(400, 20));
1040 history.setEditable(true);
1041 history.addItem("http://www.");
1043 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1047 if (historyItems != null)
1049 st = new StringTokenizer(historyItems, "\t");
1051 while (st.hasMoreTokens())
1053 history.addItem(st.nextElement());
1057 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1058 MessageManager.getString("label.input_alignment_from_url"),
1059 JOptionPane.OK_CANCEL_OPTION);
1061 if (reply != JOptionPane.OK_OPTION)
1066 String url = history.getSelectedItem().toString();
1068 if (url.toLowerCase().endsWith(".jar"))
1070 if (viewport != null)
1072 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1077 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1082 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1084 if (format.equals("URL NOT FOUND"))
1086 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1087 MessageManager.formatMessage("label.couldnt_locate", new String[]{url}), MessageManager.getString("label.url_not_found"),
1088 JOptionPane.WARNING_MESSAGE);
1093 if (viewport != null)
1095 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1099 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1110 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1112 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1113 cap.setForInput(viewport);
1114 Desktop.addInternalFrame(cap,
1115 MessageManager.getString("label.cut_paste_alignmen_file"),
1124 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1126 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1127 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1129 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1130 getBounds().y, getWidth(), getHeight()));
1132 if (jconsole != null)
1134 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1135 jconsole.stopConsole();
1139 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1142 if (dialogExecutor != null)
1144 dialogExecutor.shutdownNow();
1150 private void storeLastKnownDimensions(String string, Rectangle jc)
1152 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1153 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1154 + " height:" + jc.height);
1156 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1157 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1158 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1159 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1168 public void aboutMenuItem_actionPerformed(ActionEvent e)
1170 // StringBuffer message = getAboutMessage(false);
1171 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1173 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1174 new Thread(new Runnable()
1178 new SplashScreen(true);
1183 public StringBuffer getAboutMessage(boolean shortv)
1185 StringBuffer message = new StringBuffer();
1186 message.append("<html>");
1189 message.append("<h1><strong>Version: "
1190 + jalview.bin.Cache.getProperty("VERSION")
1191 + "</strong></h1>");
1192 message.append("<strong>Last Updated: <em>"
1193 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1194 + "</em></strong>");
1200 message.append("<strong>Version "
1201 + jalview.bin.Cache.getProperty("VERSION")
1202 + "; last updated: "
1203 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1206 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1209 message.append("<br>...Checking latest version...</br>");
1211 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1212 .equals(jalview.bin.Cache.getProperty("VERSION")))
1214 boolean red = false;
1215 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1216 .indexOf("automated build") == -1)
1219 // Displayed when code version and jnlp version do not match and code
1220 // version is not a development build
1221 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1224 message.append("<br>!! Version "
1225 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1227 + " is available for download from "
1228 + jalview.bin.Cache.getDefault("www.jalview.org",
1229 "http://www.jalview.org") + " !!");
1232 message.append("</div>");
1235 message.append("<br>Authors: "
1239 "The Jalview Authors (See AUTHORS file for current list)")
1240 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1241 + "<br><br>For help, see the FAQ at <a href=\"http://www.jalview.org/faq\">www.jalview.org/faq</a> and/or join the jalview-discuss@jalview.org mailing list"
1242 + "<br><br>If you use Jalview, please cite:"
1243 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1244 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1245 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1256 public void documentationMenuItem_actionPerformed(ActionEvent e)
1260 Help.showHelpWindow();
1261 } catch (Exception ex)
1266 public void closeAll_actionPerformed(ActionEvent e)
1268 JInternalFrame[] frames = desktop.getAllFrames();
1269 for (int i = 0; i < frames.length; i++)
1273 frames[i].setClosed(true);
1274 } catch (java.beans.PropertyVetoException ex)
1278 System.out.println("ALL CLOSED");
1279 if (v_client != null)
1281 // TODO clear binding to vamsas document objects on close_all
1286 public void raiseRelated_actionPerformed(ActionEvent e)
1288 reorderAssociatedWindows(false, false);
1291 public void minimizeAssociated_actionPerformed(ActionEvent e)
1293 reorderAssociatedWindows(true, false);
1296 void closeAssociatedWindows()
1298 reorderAssociatedWindows(false, true);
1304 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1307 protected void garbageCollect_actionPerformed(ActionEvent e)
1309 // We simply collect the garbage
1310 jalview.bin.Cache.log.debug("Collecting garbage...");
1312 jalview.bin.Cache.log.debug("Finished garbage collection.");
1319 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1322 protected void showMemusage_actionPerformed(ActionEvent e)
1324 desktop.showMemoryUsage(showMemusage.isSelected());
1331 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1334 protected void showConsole_actionPerformed(ActionEvent e)
1336 showConsole(showConsole.isSelected());
1339 Console jconsole = null;
1342 * control whether the java console is visible or not
1346 void showConsole(boolean selected)
1348 showConsole.setSelected(selected);
1349 // TODO: decide if we should update properties file
1350 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1352 jconsole.setVisible(selected);
1355 void reorderAssociatedWindows(boolean minimize, boolean close)
1357 JInternalFrame[] frames = desktop.getAllFrames();
1358 if (frames == null || frames.length < 1)
1363 AlignViewport source = null, target = null;
1364 if (frames[0] instanceof AlignFrame)
1366 source = ((AlignFrame) frames[0]).getCurrentView();
1368 else if (frames[0] instanceof TreePanel)
1370 source = ((TreePanel) frames[0]).getViewPort();
1372 else if (frames[0] instanceof PCAPanel)
1374 source = ((PCAPanel) frames[0]).av;
1376 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1378 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1383 for (int i = 0; i < frames.length; i++)
1386 if (frames[i] == null)
1390 if (frames[i] instanceof AlignFrame)
1392 target = ((AlignFrame) frames[i]).getCurrentView();
1394 else if (frames[i] instanceof TreePanel)
1396 target = ((TreePanel) frames[i]).getViewPort();
1398 else if (frames[i] instanceof PCAPanel)
1400 target = ((PCAPanel) frames[i]).av;
1402 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1404 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1407 if (source == target)
1413 frames[i].setClosed(true);
1417 frames[i].setIcon(minimize);
1420 frames[i].toFront();
1424 } catch (java.beans.PropertyVetoException ex)
1438 protected void preferences_actionPerformed(ActionEvent e)
1449 public void saveState_actionPerformed(ActionEvent e)
1451 JalviewFileChooser chooser = new JalviewFileChooser(
1452 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1453 { "jvp" }, new String[]
1454 { "Jalview Project" }, "Jalview Project");
1456 chooser.setFileView(new JalviewFileView());
1457 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1459 int value = chooser.showSaveDialog(this);
1461 if (value == JalviewFileChooser.APPROVE_OPTION)
1463 final Desktop me = this;
1464 final java.io.File choice = chooser.getSelectedFile();
1465 new Thread(new Runnable()
1470 setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new String[]{choice.getName()}),
1472 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1473 choice.getParent());
1474 // TODO catch and handle errors for savestate
1475 // TODO prevent user from messing with the Desktop whilst we're saving
1478 new Jalview2XML().SaveState(choice);
1479 } catch (OutOfMemoryError oom)
1481 new OOMWarning("Whilst saving current state to "
1482 + choice.getName(), oom);
1483 } catch (Exception ex)
1486 "Problems whilst trying to save to " + choice.getName(),
1488 JOptionPane.showMessageDialog(
1490 MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new String[]{ choice.getName()}),
1491 MessageManager.getString("label.couldnt_save_project"),
1492 JOptionPane.WARNING_MESSAGE);
1494 setProgressBar(null, choice.hashCode());
1506 public void loadState_actionPerformed(ActionEvent e)
1508 JalviewFileChooser chooser = new JalviewFileChooser(
1509 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1510 { "jvp", "jar" }, new String[]
1511 { "Jalview Project", "Jalview Project (old)" },
1513 chooser.setFileView(new JalviewFileView());
1514 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1516 int value = chooser.showOpenDialog(this);
1518 if (value == JalviewFileChooser.APPROVE_OPTION)
1520 final String choice = chooser.getSelectedFile().getAbsolutePath();
1521 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1522 .getSelectedFile().getParent());
1523 new Thread(new Runnable()
1527 setProgressBar(MessageManager.formatMessage("label.loading_jalview_project", new String[]{choice}),
1531 new Jalview2XML().LoadJalviewAlign(choice);
1532 } catch (OutOfMemoryError oom)
1534 new OOMWarning("Whilst loading project from " + choice, oom);
1535 } catch (Exception ex)
1537 Cache.log.error("Problems whilst loading project from "
1539 JOptionPane.showMessageDialog(Desktop.desktop,
1540 MessageManager.formatMessage("label.error_whilst_loading_project_from", new String[]{choice}),
1541 MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE);
1543 setProgressBar(null, choice.hashCode());
1549 public void inputSequence_actionPerformed(ActionEvent e)
1551 new SequenceFetcher(this);
1554 JPanel progressPanel;
1556 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1558 public void startLoading(final String fileName)
1560 if (fileLoadingCount == 0)
1562 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage("label.loading_file", new String[]{fileName})));
1567 private JPanel addProgressPanel(String string)
1569 if (progressPanel == null)
1571 progressPanel = new JPanel(new GridLayout(1, 1));
1572 totalProgressCount = 0;
1573 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1575 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1576 JProgressBar progressBar = new JProgressBar();
1577 progressBar.setIndeterminate(true);
1579 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1581 thisprogress.add(progressBar, BorderLayout.CENTER);
1582 progressPanel.add(thisprogress);
1583 ((GridLayout) progressPanel.getLayout())
1584 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1585 ++totalProgressCount;
1586 instance.validate();
1587 return thisprogress;
1590 int totalProgressCount = 0;
1592 private void removeProgressPanel(JPanel progbar)
1594 if (progressPanel != null)
1596 synchronized (progressPanel)
1598 progressPanel.remove(progbar);
1599 GridLayout gl = (GridLayout) progressPanel.getLayout();
1600 gl.setRows(gl.getRows() - 1);
1601 if (--totalProgressCount < 1)
1603 this.getContentPane().remove(progressPanel);
1604 progressPanel = null;
1611 public void stopLoading()
1614 if (fileLoadingCount < 1)
1616 while (fileLoadingPanels.size() > 0)
1618 removeProgressPanel(fileLoadingPanels.remove(0));
1620 fileLoadingPanels.clear();
1621 fileLoadingCount = 0;
1626 public static int getViewCount(String alignmentId)
1628 AlignViewport[] aps = getViewports(alignmentId);
1629 return (aps == null) ? 0 : aps.length;
1634 * @param alignmentId
1635 * @return all AlignmentPanels concerning the alignmentId sequence set
1637 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1640 if (Desktop.desktop == null)
1642 // no frames created and in headless mode
1643 // TODO: verify that frames are recoverable when in headless mode
1646 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1647 ArrayList aps = new ArrayList();
1648 for (int t = 0; t < frames.length; t++)
1650 if (frames[t] instanceof AlignFrame)
1652 AlignFrame af = (AlignFrame) frames[t];
1653 for (int a = 0; a < af.alignPanels.size(); a++)
1655 if (alignmentId.equals(((AlignmentPanel) af.alignPanels
1656 .elementAt(a)).av.getSequenceSetId()))
1658 aps.add(af.alignPanels.elementAt(a));
1663 if (aps.size() == 0)
1667 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1668 for (int t = 0; t < vap.length; t++)
1670 vap[t] = (AlignmentPanel) aps.get(t);
1676 * get all the viewports on an alignment.
1678 * @param sequenceSetId
1679 * unique alignment id
1680 * @return all viewports on the alignment bound to sequenceSetId
1682 public static AlignViewport[] getViewports(String sequenceSetId)
1684 Vector viewp = new Vector();
1685 if (desktop != null)
1687 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1689 for (int t = 0; t < frames.length; t++)
1691 if (frames[t] instanceof AlignFrame)
1693 AlignFrame afr = ((AlignFrame) frames[t]);
1694 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1696 if (afr.alignPanels != null)
1698 for (int a = 0; a < afr.alignPanels.size(); a++)
1700 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1701 .elementAt(a)).av.getSequenceSetId()))
1703 viewp.addElement(((AlignmentPanel) afr.alignPanels
1710 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1715 if (viewp.size() > 0)
1717 AlignViewport[] vp = new AlignViewport[viewp.size()];
1725 public void explodeViews(AlignFrame af)
1727 int size = af.alignPanels.size();
1733 for (int i = 0; i < size; i++)
1735 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1736 AlignFrame newaf = new AlignFrame(ap);
1737 if (ap.av.explodedPosition != null
1738 && !ap.av.explodedPosition.equals(af.getBounds()))
1740 newaf.setBounds(ap.av.explodedPosition);
1743 ap.av.gatherViewsHere = false;
1745 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1746 AlignFrame.DEFAULT_HEIGHT);
1749 af.alignPanels.clear();
1750 af.closeMenuItem_actionPerformed(true);
1754 public void gatherViews(AlignFrame source)
1756 source.viewport.gatherViewsHere = true;
1757 source.viewport.explodedPosition = source.getBounds();
1758 JInternalFrame[] frames = desktop.getAllFrames();
1759 String viewId = source.viewport.getSequenceSetId();
1761 for (int t = 0; t < frames.length; t++)
1763 if (frames[t] instanceof AlignFrame && frames[t] != source)
1765 AlignFrame af = (AlignFrame) frames[t];
1766 boolean gatherThis = false;
1767 for (int a = 0; a < af.alignPanels.size(); a++)
1769 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1770 if (viewId.equals(ap.av.getSequenceSetId()))
1773 ap.av.gatherViewsHere = false;
1774 ap.av.explodedPosition = af.getBounds();
1775 source.addAlignmentPanel(ap, false);
1781 af.alignPanels.clear();
1782 af.closeMenuItem_actionPerformed(true);
1789 jalview.gui.VamsasApplication v_client = null;
1791 public void vamsasImport_actionPerformed(ActionEvent e)
1793 if (v_client == null)
1795 // Load and try to start a session.
1796 JalviewFileChooser chooser = new JalviewFileChooser(
1797 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1799 chooser.setFileView(new JalviewFileView());
1800 chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
1801 chooser.setToolTipText(MessageManager
1802 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1804 int value = chooser.showOpenDialog(this);
1806 if (value == JalviewFileChooser.APPROVE_OPTION)
1808 String fle = chooser.getSelectedFile().toString();
1809 if (!vamsasImport(chooser.getSelectedFile()))
1812 .showInternalMessageDialog(
1814 MessageManager.formatMessage(
1815 "label.couldnt_import_as_vamsas_session",
1819 .getString("label.vamsas_document_import_failed"),
1820 JOptionPane.ERROR_MESSAGE);
1826 jalview.bin.Cache.log
1827 .error("Implementation error - load session from a running session is not supported.");
1832 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1835 * @return true if import was a success and a session was started.
1837 public boolean vamsasImport(URL url)
1839 // TODO: create progress bar
1840 if (v_client != null)
1843 jalview.bin.Cache.log
1844 .error("Implementation error - load session from a running session is not supported.");
1850 // copy the URL content to a temporary local file
1851 // TODO: be a bit cleverer here with nio (?!)
1852 File file = File.createTempFile("vdocfromurl", ".vdj");
1853 FileOutputStream fos = new FileOutputStream(file);
1854 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1855 byte[] buffer = new byte[2048];
1857 while ((ln = bis.read(buffer)) > -1)
1859 fos.write(buffer, 0, ln);
1863 v_client = new jalview.gui.VamsasApplication(this, file,
1864 url.toExternalForm());
1865 } catch (Exception ex)
1867 jalview.bin.Cache.log.error(
1868 "Failed to create new vamsas session from contents of URL "
1872 setupVamsasConnectedGui();
1873 v_client.initial_update(); // TODO: thread ?
1874 return v_client.inSession();
1878 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1881 * @return true if import was a success and a session was started.
1883 public boolean vamsasImport(File file)
1885 if (v_client != null)
1888 jalview.bin.Cache.log
1889 .error("Implementation error - load session from a running session is not supported.");
1893 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1897 v_client = new jalview.gui.VamsasApplication(this, file, null);
1898 } catch (Exception ex)
1900 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1902 jalview.bin.Cache.log.error(
1903 "New vamsas session from existing session file failed:", ex);
1906 setupVamsasConnectedGui();
1907 v_client.initial_update(); // TODO: thread ?
1908 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1910 return v_client.inSession();
1913 public boolean joinVamsasSession(String mysesid)
1915 if (v_client != null)
1917 throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
1919 if (mysesid == null)
1921 throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
1923 v_client = new VamsasApplication(this, mysesid);
1924 setupVamsasConnectedGui();
1925 v_client.initial_update();
1926 return (v_client.inSession());
1929 public void vamsasStart_actionPerformed(ActionEvent e)
1931 if (v_client == null)
1934 // we just start a default session for moment.
1936 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1937 * getProperty("LAST_DIRECTORY"));
1939 * chooser.setFileView(new JalviewFileView());
1940 * chooser.setDialogTitle("Load Vamsas file");
1941 * chooser.setToolTipText("Import");
1943 * int value = chooser.showOpenDialog(this);
1945 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1946 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1948 v_client = new VamsasApplication(this);
1949 setupVamsasConnectedGui();
1950 v_client.initial_update(); // TODO: thread ?
1954 // store current data in session.
1955 v_client.push_update(); // TODO: thread
1959 protected void setupVamsasConnectedGui()
1961 vamsasStart.setText(MessageManager.getString("label.session_update"));
1962 vamsasSave.setVisible(true);
1963 vamsasStop.setVisible(true);
1964 vamsasImport.setVisible(false); // Document import to existing session is
1965 // not possible for vamsas-client-1.0.
1968 protected void setupVamsasDisconnectedGui()
1970 vamsasSave.setVisible(false);
1971 vamsasStop.setVisible(false);
1972 vamsasImport.setVisible(true);
1973 vamsasStart.setText(MessageManager
1974 .getString("label.new_vamsas_session"));
1977 public void vamsasStop_actionPerformed(ActionEvent e)
1979 if (v_client != null)
1981 v_client.end_session();
1983 setupVamsasDisconnectedGui();
1987 protected void buildVamsasStMenu()
1989 if (v_client == null)
1991 String[] sess = null;
1994 sess = VamsasApplication.getSessionList();
1995 } catch (Exception e)
1997 jalview.bin.Cache.log.warn(
1998 "Problem getting current sessions list.", e);
2003 jalview.bin.Cache.log.debug("Got current sessions list: "
2004 + sess.length + " entries.");
2005 VamsasStMenu.removeAll();
2006 for (int i = 0; i < sess.length; i++)
2008 JMenuItem sessit = new JMenuItem();
2009 sessit.setText(sess[i]);
2010 sessit.setToolTipText(MessageManager.formatMessage(
2011 "label.connect_to_session", new String[]
2013 final Desktop dsktp = this;
2014 final String mysesid = sess[i];
2015 sessit.addActionListener(new ActionListener()
2018 public void actionPerformed(ActionEvent e)
2020 if (dsktp.v_client == null)
2022 Thread rthr = new Thread(new Runnable()
2027 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2028 dsktp.setupVamsasConnectedGui();
2029 dsktp.v_client.initial_update();
2037 VamsasStMenu.add(sessit);
2039 // don't show an empty menu.
2040 VamsasStMenu.setVisible(sess.length > 0);
2045 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2046 VamsasStMenu.removeAll();
2047 VamsasStMenu.setVisible(false);
2052 // Not interested in the content. Just hide ourselves.
2053 VamsasStMenu.setVisible(false);
2057 public void vamsasSave_actionPerformed(ActionEvent e)
2059 if (v_client != null)
2061 JalviewFileChooser chooser = new JalviewFileChooser(
2062 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2063 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2065 { "Vamsas Document" }, "Vamsas Document");
2067 chooser.setFileView(new JalviewFileView());
2068 chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
2070 int value = chooser.showSaveDialog(this);
2072 if (value == JalviewFileChooser.APPROVE_OPTION)
2074 java.io.File choice = chooser.getSelectedFile();
2075 JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new String[]{choice.getName()}));
2076 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2077 String warnmsg = null;
2078 String warnttl = null;
2081 v_client.vclient.storeDocument(choice);
2084 warnttl = "Serious Problem saving Vamsas Document";
2085 warnmsg = ex.toString();
2086 jalview.bin.Cache.log.error("Error Whilst saving document to "
2089 } catch (Exception ex)
2091 warnttl = "Problem saving Vamsas Document.";
2092 warnmsg = ex.toString();
2093 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2097 removeProgressPanel(progpanel);
2098 if (warnmsg != null)
2100 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2102 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2108 JPanel vamUpdate = null;
2111 * hide vamsas user gui bits when a vamsas document event is being handled.
2114 * true to hide gui, false to reveal gui
2116 public void setVamsasUpdate(boolean b)
2118 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2119 + (b ? "in progress" : "finished"));
2121 if (vamUpdate != null)
2123 this.removeProgressPanel(vamUpdate);
2127 vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
2129 vamsasStart.setVisible(!b);
2130 vamsasStop.setVisible(!b);
2131 vamsasSave.setVisible(!b);
2134 public JInternalFrame[] getAllFrames()
2136 return desktop.getAllFrames();
2140 * Checks the given url to see if it gives a response indicating that the user
2141 * should be informed of a new questionnaire.
2145 public void checkForQuestionnaire(String url)
2147 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2148 // javax.swing.SwingUtilities.invokeLater(jvq);
2149 new Thread(jvq).start();
2153 * Proxy class for JDesktopPane which optionally displays the current memory
2154 * usage and highlights the desktop area with a red bar if free memory runs
2159 public class MyDesktopPane extends JDesktopPane implements Runnable
2162 boolean showMemoryUsage = false;
2166 java.text.NumberFormat df;
2168 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2171 public MyDesktopPane(boolean showMemoryUsage)
2173 showMemoryUsage(showMemoryUsage);
2176 public void showMemoryUsage(boolean showMemoryUsage)
2178 this.showMemoryUsage = showMemoryUsage;
2179 if (showMemoryUsage)
2181 Thread worker = new Thread(this);
2186 public boolean isShowMemoryUsage()
2188 return showMemoryUsage;
2193 df = java.text.NumberFormat.getNumberInstance();
2194 df.setMaximumFractionDigits(2);
2195 runtime = Runtime.getRuntime();
2197 while (showMemoryUsage)
2201 maxMemory = runtime.maxMemory() / 1048576f;
2202 allocatedMemory = runtime.totalMemory() / 1048576f;
2203 freeMemory = runtime.freeMemory() / 1048576f;
2204 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2206 percentUsage = (totalFreeMemory / maxMemory) * 100;
2208 // if (percentUsage < 20)
2210 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2212 // instance.set.setBorder(border1);
2215 // sleep after showing usage
2217 } catch (Exception ex)
2219 ex.printStackTrace();
2224 public void paintComponent(Graphics g)
2226 if (showMemoryUsage && g != null && df != null)
2228 if (percentUsage < 20)
2230 g.setColor(Color.red);
2232 FontMetrics fm = g.getFontMetrics();
2235 g.drawString(MessageManager.formatMessage(
2236 "label.memory_stats",
2238 { df.format(totalFreeMemory), df.format(maxMemory),
2239 df.format(percentUsage) }), 10,
2240 getHeight() - fm.getHeight());
2247 * fixes stacking order after a modal dialog to ensure windows that should be
2248 * on top actually are
2250 public void relayerWindows()
2255 protected JMenuItem groovyShell;
2257 public void doGroovyCheck()
2259 if (jalview.bin.Cache.groovyJarsPresent())
2261 groovyShell = new JMenuItem();
2262 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2263 groovyShell.addActionListener(new ActionListener()
2265 public void actionPerformed(ActionEvent e)
2267 groovyShell_actionPerformed(e);
2270 toolsMenu.add(groovyShell);
2271 groovyShell.setVisible(true);
2276 * Accessor method to quickly get all the AlignmentFrames loaded.
2278 public static AlignFrame[] getAlignframes()
2280 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2286 Vector avp = new Vector();
2290 for (int i = frames.length - 1; i > -1; i--)
2292 if (frames[i] instanceof AlignFrame)
2294 AlignFrame af = (AlignFrame) frames[i];
2298 } catch (Exception ex)
2300 ex.printStackTrace();
2302 if (avp.size() == 0)
2306 AlignFrame afs[] = new AlignFrame[avp.size()];
2307 for (int i = 0, j = avp.size(); i < j; i++)
2309 afs[i] = (AlignFrame) avp.elementAt(i);
2315 public AppJmol[] getJmols()
2317 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2323 Vector avp = new Vector();
2327 for (int i = frames.length - 1; i > -1; i--)
2329 if (frames[i] instanceof AppJmol)
2331 AppJmol af = (AppJmol) frames[i];
2335 } catch (Exception ex)
2337 ex.printStackTrace();
2339 if (avp.size() == 0)
2343 AppJmol afs[] = new AppJmol[avp.size()];
2344 for (int i = 0, j = avp.size(); i < j; i++)
2346 afs[i] = (AppJmol) avp.elementAt(i);
2353 * Add Groovy Support to Jalview
2355 public void groovyShell_actionPerformed(ActionEvent e)
2357 // use reflection to avoid creating compilation dependency.
2358 if (!jalview.bin.Cache.groovyJarsPresent())
2360 throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
2364 Class gcClass = Desktop.class.getClassLoader().loadClass(
2365 "groovy.ui.Console");
2366 Constructor gccons = gcClass.getConstructor(null);
2367 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2369 { String.class, Object.class });
2370 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2371 Object gc = gccons.newInstance(null);
2372 setvar.invoke(gc, new Object[]
2373 { "Jalview", this });
2374 run.invoke(gc, null);
2375 } catch (Exception ex)
2377 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2379 .showInternalMessageDialog(
2382 MessageManager.getString("label.couldnt_create_groovy_shell"),
2383 MessageManager.getString("label.groovy_support_failed"),
2384 JOptionPane.ERROR_MESSAGE);
2389 * Progress bars managed by the IProgressIndicator method.
2391 private Hashtable<Long, JPanel> progressBars;
2393 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2398 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2400 public void setProgressBar(String message, long id)
2402 if (progressBars == null)
2404 progressBars = new Hashtable<Long, JPanel>();
2405 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2408 if (progressBars.get(new Long(id)) != null)
2410 JPanel progressPanel = progressBars.remove(new Long(id));
2411 if (progressBarHandlers.contains(new Long(id)))
2413 progressBarHandlers.remove(new Long(id));
2415 removeProgressPanel(progressPanel);
2419 progressBars.put(new Long(id), addProgressPanel(message));
2426 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2427 * jalview.gui.IProgressIndicatorHandler)
2429 public void registerHandler(final long id,
2430 final IProgressIndicatorHandler handler)
2432 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2434 throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
2436 progressBarHandlers.put(new Long(id), handler);
2437 final JPanel progressPanel = progressBars.get(new Long(id));
2438 if (handler.canCancel())
2440 JButton cancel = new JButton(
2441 MessageManager.getString("action.cancel"));
2442 final IProgressIndicator us = this;
2443 cancel.addActionListener(new ActionListener()
2446 public void actionPerformed(ActionEvent e)
2448 handler.cancelActivity(id);
2449 us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
2452 progressPanel.add(cancel, BorderLayout.EAST);
2458 * @return true if any progress bars are still active
2461 public boolean operationInProgress()
2463 if (progressBars != null && progressBars.size() > 0)
2471 * This will return the first AlignFrame viewing AlignViewport av. It will
2472 * break if there are more than one AlignFrames viewing a particular av. This
2475 * @return alignFrame for av
2477 public static AlignFrame getAlignFrameFor(AlignViewport av)
2479 if (desktop != null)
2481 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2482 for (int panel = 0; aps != null && panel < aps.length; panel++)
2484 if (aps[panel] != null && aps[panel].av == av)
2486 return aps[panel].alignFrame;
2493 public VamsasApplication getVamsasApplication()
2500 * flag set if jalview GUI is being operated programmatically
2502 private boolean inBatchMode = false;
2505 * check if jalview GUI is being operated programmatically
2507 * @return inBatchMode
2509 public boolean isInBatchMode()
2515 * set flag if jalview GUI is being operated programmatically
2517 * @param inBatchMode
2519 public void setInBatchMode(boolean inBatchMode)
2521 this.inBatchMode = inBatchMode;
2524 public void startServiceDiscovery()
2526 startServiceDiscovery(false);
2529 public void startServiceDiscovery(boolean blocking)
2531 boolean alive = true;
2532 Thread t0 = null, t1 = null, t2 = null;
2533 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2536 // todo: changesupport handlers need to be transferred
2537 if (discoverer == null)
2539 discoverer = new jalview.ws.jws1.Discoverer();
2540 // register PCS handler for desktop.
2541 discoverer.addPropertyChangeListener(changeSupport);
2543 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2544 // until we phase out completely
2545 (t0 = new Thread(discoverer)).start();
2548 // ENFIN services are EOLed as of Jalview 2.8.1 release
2553 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2555 // EnfinEnvision web service menu entries are rebuild every time the
2556 // menu is shown, so no changeSupport events are needed.
2557 jalview.ws.EnfinEnvision2OneWay.getInstance();
2558 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2561 } catch (Exception e)
2564 .info("Exception when trying to launch Envision2 workflow discovery.",
2566 Cache.log.info(e.getStackTrace());
2570 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2572 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2574 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2576 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2582 // TODO: do rest service discovery
2591 } catch (Exception e)
2594 alive = (t1 != null && t1.isAlive())
2595 || (t2 != null && t2.isAlive())
2596 || (t3 != null && t3.isAlive())
2597 || (t0 != null && t0.isAlive());
2603 * called to check if the service discovery process completed successfully.
2607 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2609 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2611 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2612 .getErrorMessages();
2615 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2617 if (serviceChangedDialog == null)
2619 // only run if we aren't already displaying one of these.
2620 addDialogThread(serviceChangedDialog = new Runnable()
2626 * JalviewDialog jd =new JalviewDialog() {
2628 * @Override protected void cancelPressed() { // TODO
2629 * Auto-generated method stub
2631 * }@Override protected void okPressed() { // TODO
2632 * Auto-generated method stub
2634 * }@Override protected void raiseClosed() { // TODO
2635 * Auto-generated method stub
2637 * } }; jd.initDialogFrame(new
2638 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2639 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2640 * + " or mis-configured HTTP proxy settings.<br/>" +
2641 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2643 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2644 * ), true, true, "Web Service Configuration Problem", 450,
2647 * jd.waitForInput();
2653 "<html><table width=\"450\"><tr><td>"
2655 + "</td></tr></table>"
2656 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2657 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2658 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2659 + " Tools->Preferences dialog box to change them.</p></html>"),
2660 "Web Service Configuration Problem",
2661 JOptionPane.DEFAULT_OPTION,
2662 JOptionPane.ERROR_MESSAGE);
2663 serviceChangedDialog = null;
2672 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2679 private Runnable serviceChangedDialog = null;
2682 * start a thread to open a URL in the configured browser. Pops up a warning
2683 * dialog to the user if there is an exception when calling out to the browser
2688 public static void showUrl(final String url)
2690 showUrl(url, Desktop.instance);
2694 * Like showUrl but allows progress handler to be specified
2698 * (null) or object implementing IProgressIndicator
2700 public static void showUrl(final String url,
2701 final IProgressIndicator progress)
2703 new Thread(new Runnable()
2709 if (progress != null)
2711 progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new String[]{url}), this.hashCode());
2713 jalview.util.BrowserLauncher.openURL(url);
2714 } catch (Exception ex)
2717 .showInternalMessageDialog(
2719 MessageManager.getString("label.web_browser_not_found_unix"),
2720 MessageManager.getString("label.web_browser_not_found"),
2721 JOptionPane.WARNING_MESSAGE);
2723 ex.printStackTrace();
2725 if (progress != null)
2727 progress.setProgressBar(null, this.hashCode());
2733 public static WsParamSetManager wsparamManager = null;
2735 public static ParamManager getUserParameterStore()
2737 if (wsparamManager == null)
2739 wsparamManager = new WsParamSetManager();
2741 return wsparamManager;
2745 * static hyperlink handler proxy method for use by Jalview's internal windows
2749 public static void hyperlinkUpdate(HyperlinkEvent e)
2751 if (e.getEventType() == EventType.ACTIVATED)
2756 url = e.getURL().toString();
2757 Desktop.showUrl(url);
2758 } catch (Exception x)
2762 if (Cache.log != null)
2764 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2768 System.err.println("Couldn't handle string " + url
2772 // ignore any exceptions due to dud links.
2779 * single thread that handles display of dialogs to user.
2781 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2784 * flag indicating if dialogExecutor should try to acquire a permit
2786 private volatile boolean dialogPause = true;
2791 private java.util.concurrent.Semaphore block = new Semaphore(0);
2794 * add another dialog thread to the queue
2798 public void addDialogThread(final Runnable prompter)
2800 dialogExecutor.submit(new Runnable()
2809 } catch (InterruptedException x)
2814 if (instance == null)
2820 SwingUtilities.invokeAndWait(prompter);
2821 } catch (Exception q)
2823 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2829 public void startDialogQueue()
2831 // set the flag so we don't pause waiting for another permit and semaphore
2832 // the current task to begin
2833 dialogPause = false;
2837 protected void snapShotWindow_actionPerformed(ActionEvent e)
2841 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2842 "View of Desktop", getWidth(), getHeight(), of = new File(
2843 "Jalview_snapshot" + System.currentTimeMillis()
2844 + ".eps"), "View of desktop");
2846 paintAll(im.getGraphics());
2848 } catch (Exception q)
2850 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2853 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());