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.jbgui.GStructureViewer;
30 import jalview.structure.StructureSelectionManager;
31 import jalview.util.ImageMaker;
32 import jalview.util.MessageManager;
33 import jalview.viewmodel.AlignmentViewport;
34 import jalview.ws.params.ParamManager;
36 import java.awt.BorderLayout;
37 import java.awt.Color;
38 import java.awt.Dimension;
39 import java.awt.FontMetrics;
40 import java.awt.Graphics;
41 import java.awt.GridLayout;
42 import java.awt.Point;
43 import java.awt.Rectangle;
44 import java.awt.Toolkit;
45 import java.awt.datatransfer.Clipboard;
46 import java.awt.datatransfer.ClipboardOwner;
47 import java.awt.datatransfer.DataFlavor;
48 import java.awt.datatransfer.Transferable;
49 import java.awt.dnd.DnDConstants;
50 import java.awt.dnd.DropTargetDragEvent;
51 import java.awt.dnd.DropTargetDropEvent;
52 import java.awt.dnd.DropTargetEvent;
53 import java.awt.dnd.DropTargetListener;
54 import java.awt.event.ActionEvent;
55 import java.awt.event.ActionListener;
56 import java.awt.event.FocusEvent;
57 import java.awt.event.FocusListener;
58 import java.awt.event.MouseAdapter;
59 import java.awt.event.MouseEvent;
60 import java.awt.event.MouseListener;
61 import java.awt.event.WindowAdapter;
62 import java.awt.event.WindowEvent;
63 import java.beans.PropertyChangeEvent;
64 import java.beans.PropertyChangeListener;
65 import java.beans.PropertyVetoException;
66 import java.io.BufferedInputStream;
68 import java.io.FileOutputStream;
69 import java.lang.reflect.Constructor;
71 import java.util.ArrayList;
72 import java.util.Hashtable;
73 import java.util.List;
74 import java.util.StringTokenizer;
75 import java.util.Vector;
76 import java.util.concurrent.ExecutorService;
77 import java.util.concurrent.Executors;
78 import java.util.concurrent.Semaphore;
80 import javax.swing.DefaultDesktopManager;
81 import javax.swing.DesktopManager;
82 import javax.swing.JButton;
83 import javax.swing.JComboBox;
84 import javax.swing.JComponent;
85 import javax.swing.JDesktopPane;
86 import javax.swing.JFrame;
87 import javax.swing.JInternalFrame;
88 import javax.swing.JLabel;
89 import javax.swing.JMenuItem;
90 import javax.swing.JOptionPane;
91 import javax.swing.JPanel;
92 import javax.swing.JPopupMenu;
93 import javax.swing.JProgressBar;
94 import javax.swing.SwingUtilities;
95 import javax.swing.event.HyperlinkEvent;
96 import javax.swing.event.HyperlinkEvent.EventType;
97 import javax.swing.event.MenuEvent;
98 import javax.swing.event.MenuListener;
105 * @version $Revision: 1.155 $
107 public class Desktop extends jalview.jbgui.GDesktop implements
108 DropTargetListener, ClipboardOwner, IProgressIndicator,
109 jalview.api.StructureSelectionManagerProvider
112 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
115 * news reader - null if it was never started.
117 private BlogReader jvnews = null;
119 private File projectFile;
123 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
125 public void addJalviewPropertyChangeListener(
126 PropertyChangeListener listener)
128 changeSupport.addJalviewPropertyChangeListener(listener);
132 * @param propertyName
134 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
135 * java.beans.PropertyChangeListener)
137 public void addJalviewPropertyChangeListener(String propertyName,
138 PropertyChangeListener listener)
140 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
144 * @param propertyName
146 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
147 * java.beans.PropertyChangeListener)
149 public void removeJalviewPropertyChangeListener(String propertyName,
150 PropertyChangeListener listener)
152 changeSupport.removeJalviewPropertyChangeListener(propertyName,
156 /** Singleton Desktop instance */
157 public static Desktop instance;
159 public static MyDesktopPane desktop;
161 static int openFrameCount = 0;
163 static final int xOffset = 30;
165 static final int yOffset = 30;
167 private static final int THREE = 3;
169 public static jalview.ws.jws1.Discoverer discoverer;
171 public static Object[] jalviewClipboard;
173 public static boolean internalCopy = false;
175 static int fileLoadingCount = 0;
177 class MyDesktopManager implements DesktopManager
180 private DesktopManager delegate;
182 public MyDesktopManager(DesktopManager delegate)
184 this.delegate = delegate;
187 public void activateFrame(JInternalFrame f)
191 delegate.activateFrame(f);
192 } catch (NullPointerException npe)
194 Point p = getMousePosition();
195 instance.showPasteMenu(p.x, p.y);
199 public void beginDraggingFrame(JComponent f)
201 delegate.beginDraggingFrame(f);
204 public void beginResizingFrame(JComponent f, int direction)
206 delegate.beginResizingFrame(f, direction);
209 public void closeFrame(JInternalFrame f)
211 delegate.closeFrame(f);
214 public void deactivateFrame(JInternalFrame f)
216 delegate.deactivateFrame(f);
219 public void deiconifyFrame(JInternalFrame f)
221 delegate.deiconifyFrame(f);
224 public void dragFrame(JComponent f, int newX, int newY)
230 delegate.dragFrame(f, newX, newY);
233 public void endDraggingFrame(JComponent f)
235 delegate.endDraggingFrame(f);
238 public void endResizingFrame(JComponent f)
240 delegate.endResizingFrame(f);
243 public void iconifyFrame(JInternalFrame f)
245 delegate.iconifyFrame(f);
248 public void maximizeFrame(JInternalFrame f)
250 delegate.maximizeFrame(f);
253 public void minimizeFrame(JInternalFrame f)
255 delegate.minimizeFrame(f);
258 public void openFrame(JInternalFrame f)
260 delegate.openFrame(f);
263 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
266 Rectangle b = desktop.getBounds();
271 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
274 public void setBoundsForFrame(JComponent f, int newX, int newY,
275 int newWidth, int newHeight)
277 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
280 // All other methods, simply delegate
285 * Creates a new Desktop object.
290 * A note to implementors. It is ESSENTIAL that any activities that might
291 * block are spawned off as threads rather than waited for during this
295 doVamsasClientCheck();
297 doConfigureStructurePrefs();
298 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
299 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
300 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
302 boolean showjconsole = jalview.bin.Cache.getDefault(
303 "SHOW_JAVA_CONSOLE", false);
304 desktop = new MyDesktopPane(selmemusage);
305 showMemusage.setSelected(selmemusage);
306 desktop.setBackground(Color.white);
307 getContentPane().setLayout(new BorderLayout());
308 // alternate config - have scrollbars - see notes in JAL-153
309 // JScrollPane sp = new JScrollPane();
310 // sp.getViewport().setView(desktop);
311 // getContentPane().add(sp, BorderLayout.CENTER);
312 getContentPane().add(desktop, BorderLayout.CENTER);
313 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
315 // This line prevents Windows Look&Feel resizing all new windows to maximum
316 // if previous window was maximised
317 desktop.setDesktopManager(new MyDesktopManager(
318 new DefaultDesktopManager()));
320 Rectangle dims = getLastKnownDimensions("");
327 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
328 setBounds((screenSize.width - 900) / 2,
329 (screenSize.height - 650) / 2, 900, 650);
331 jconsole = new Console(this, showjconsole);
332 // add essential build information
333 jconsole.setHeader("Jalview Version: "
334 + jalview.bin.Cache.getProperty("VERSION") + "\n"
335 + "Jalview Installation: "
336 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
339 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
340 + "Java version: " + System.getProperty("java.version") + "\n"
341 + System.getProperty("os.arch") + " "
342 + System.getProperty("os.name") + " "
343 + System.getProperty("os.version"));
345 showConsole(showjconsole);
347 showNews.setVisible(false);
349 this.addWindowListener(new WindowAdapter()
351 public void windowClosing(WindowEvent evt)
358 this.addMouseListener(ma = new MouseAdapter()
360 public void mousePressed(MouseEvent evt)
362 if (SwingUtilities.isRightMouseButton(evt))
364 showPasteMenu(evt.getX(), evt.getY());
368 desktop.addMouseListener(ma);
370 this.addFocusListener(new FocusListener()
374 public void focusLost(FocusEvent e)
376 // TODO Auto-generated method stub
381 public void focusGained(FocusEvent e)
383 Cache.log.debug("Relaying windows after focus gain");
384 // make sure that we sort windows properly after we gain focus
385 instance.relayerWindows();
388 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
389 // Spawn a thread that shows the splashscreen
390 SwingUtilities.invokeLater(new Runnable()
399 // Thread off a new instance of the file chooser - this reduces the time it
400 // takes to open it later on.
401 new Thread(new Runnable()
405 Cache.log.debug("Filechooser init thread started.");
406 JalviewFileChooser chooser = new JalviewFileChooser(
407 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
408 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
409 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
410 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
411 Cache.log.debug("Filechooser init thread finished.");
414 // Add the service change listener
415 changeSupport.addJalviewPropertyChangeListener("services",
416 new PropertyChangeListener()
420 public void propertyChange(PropertyChangeEvent evt)
422 Cache.log.debug("Firing service changed event for "
423 + evt.getNewValue());
424 JalviewServicesChanged(evt);
430 public void doConfigureStructurePrefs()
432 // configure services
433 StructureSelectionManager ssm = StructureSelectionManager
434 .getStructureSelectionManager(this);
435 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
437 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
438 Preferences.ADD_TEMPFACT_ANN, true));
439 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(Preferences.STRUCT_FROM_PDB, true));
440 ssm.setSecStructServices(jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW,
445 ssm.setAddTempFacAnnot(false);
446 ssm.setProcessSecondaryStructure(false);
447 ssm.setSecStructServices(false);
451 public void checkForNews()
453 final Desktop me = this;
454 // Thread off the news reader, in case there are connection problems.
455 addDialogThread(new Runnable()
460 Cache.log.debug("Starting news thread.");
462 jvnews = new BlogReader(me);
463 showNews.setVisible(true);
464 Cache.log.debug("Completed news thread.");
469 protected void showNews_actionPerformed(ActionEvent e)
471 showNews(showNews.isSelected());
474 void showNews(boolean visible)
477 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
478 showNews.setSelected(visible);
479 if (visible && !jvnews.isVisible())
481 new Thread(new Runnable()
486 long instance = System.currentTimeMillis();
487 Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_news"), instance);
488 jvnews.refreshNews();
489 Desktop.instance.setProgressBar(null, instance);
498 * recover the last known dimensions for a jalview window
501 * - empty string is desktop, all other windows have unique prefix
502 * @return null or last known dimensions scaled to current geometry (if last
503 * window geom was known)
505 Rectangle getLastKnownDimensions(String windowName)
507 // TODO: lock aspect ratio for scaling desktop Bug #0058199
508 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
509 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
510 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
511 String width = jalview.bin.Cache.getProperty(windowName
513 String height = jalview.bin.Cache.getProperty(windowName
515 if ((x != null) && (y != null) && (width != null) && (height != null))
517 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
518 .parseInt(width), ih = Integer.parseInt(height);
519 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
521 // attempt #1 - try to cope with change in screen geometry - this
522 // version doesn't preserve original jv aspect ratio.
523 // take ratio of current screen size vs original screen size.
524 double sw = ((1f * screenSize.width) / (1f * Integer
525 .parseInt(jalview.bin.Cache
526 .getProperty("SCREENGEOMETRY_WIDTH"))));
527 double sh = ((1f * screenSize.height) / (1f * Integer
528 .parseInt(jalview.bin.Cache
529 .getProperty("SCREENGEOMETRY_HEIGHT"))));
530 // rescale the bounds depending upon the current screen geometry.
531 ix = (int) (ix * sw);
532 iw = (int) (iw * sw);
533 iy = (int) (iy * sh);
534 ih = (int) (ih * sh);
535 while (ix >= screenSize.width)
537 jalview.bin.Cache.log
538 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
539 ix -= screenSize.width;
541 while (iy >= screenSize.height)
543 jalview.bin.Cache.log
544 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
545 iy -= screenSize.height;
547 jalview.bin.Cache.log.debug("Got last known dimensions for "
548 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
551 // return dimensions for new instance
552 return new Rectangle(ix, iy, iw, ih);
557 private void doVamsasClientCheck()
559 if (jalview.bin.Cache.vamsasJarsPresent())
561 setupVamsasDisconnectedGui();
562 VamsasMenu.setVisible(true);
563 final Desktop us = this;
564 VamsasMenu.addMenuListener(new MenuListener()
566 // this listener remembers when the menu was first selected, and
567 // doesn't rebuild the session list until it has been cleared and
569 boolean refresh = true;
571 public void menuCanceled(MenuEvent e)
576 public void menuDeselected(MenuEvent e)
581 public void menuSelected(MenuEvent e)
585 us.buildVamsasStMenu();
590 vamsasStart.setVisible(true);
594 void showPasteMenu(int x, int y)
596 JPopupMenu popup = new JPopupMenu();
597 JMenuItem item = new JMenuItem(
598 MessageManager.getString("label.paste_new_window"));
599 item.addActionListener(new ActionListener()
601 public void actionPerformed(ActionEvent evt)
608 popup.show(this, x, y);
615 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
616 Transferable contents = c.getContents(this);
618 if (contents != null)
620 String file = (String) contents
621 .getTransferData(DataFlavor.stringFlavor);
623 String format = new IdentifyFile().Identify(file,
624 FormatAdapter.PASTE);
626 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
629 } catch (Exception ex)
632 .println("Unable to paste alignment from system clipboard:\n"
638 * Adds and opens the given frame to the desktop
649 public static synchronized void addInternalFrame(
650 final JInternalFrame frame, String title, int w, int h)
652 addInternalFrame(frame, title, true, w, h, true);
657 * Add an internal frame to the Jalview desktop
664 * When true, display frame immediately, otherwise, caller must call
665 * setVisible themselves.
671 public static synchronized void addInternalFrame(
672 final JInternalFrame frame, String title, boolean makeVisible,
675 addInternalFrame(frame, title, makeVisible, w, h, true);
679 * Add an internal frame to the Jalview desktop and make it visible
692 public static synchronized void addInternalFrame(
693 final JInternalFrame frame, String title, int w, int h,
696 addInternalFrame(frame, title, true, w, h, resizable);
700 * Add an internal frame to the Jalview desktop
707 * When true, display frame immediately, otherwise, caller must call
708 * setVisible themselves.
716 public static synchronized void addInternalFrame(
717 final JInternalFrame frame, String title, boolean makeVisible,
718 int w, int h, boolean resizable)
721 // TODO: allow callers to determine X and Y position of frame (eg. via
723 // TODO: consider fixing method to update entries in the window submenu with
724 // the current window title
726 frame.setTitle(title);
727 if (frame.getWidth() < 1 || frame.getHeight() < 1)
731 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
732 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
733 // IF JALVIEW IS RUNNING HEADLESS
734 // ///////////////////////////////////////////////
736 || (System.getProperty("java.awt.headless") != null && System
737 .getProperty("java.awt.headless").equals("true")))
744 frame.setVisible(makeVisible);
745 frame.setClosable(true);
746 frame.setResizable(resizable);
747 frame.setMaximizable(resizable);
748 frame.setIconifiable(resizable);
749 frame.setFrameIcon(null);
751 if (frame.getX() < 1 && frame.getY() < 1)
753 frame.setLocation(xOffset * openFrameCount, yOffset
754 * ((openFrameCount - 1) % 10) + yOffset);
757 final JMenuItem menuItem = new JMenuItem(title);
758 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
760 public void internalFrameActivated(
761 javax.swing.event.InternalFrameEvent evt)
763 JInternalFrame itf = desktop.getSelectedFrame();
771 public void internalFrameClosed(
772 javax.swing.event.InternalFrameEvent evt)
774 PaintRefresher.RemoveComponent(frame);
776 windowMenu.remove(menuItem);
777 JInternalFrame itf = desktop.getSelectedFrame();
786 menuItem.addActionListener(new ActionListener()
788 public void actionPerformed(ActionEvent e)
792 frame.setSelected(true);
793 frame.setIcon(false);
794 } catch (java.beans.PropertyVetoException ex)
800 menuItem.addMouseListener(new MouseListener()
804 public void mouseReleased(MouseEvent e)
809 public void mousePressed(MouseEvent e)
814 public void mouseExited(MouseEvent e)
818 frame.setSelected(false);
819 } catch (PropertyVetoException e1)
825 public void mouseEntered(MouseEvent e)
829 frame.setSelected(true);
830 } catch (PropertyVetoException e1)
836 public void mouseClicked(MouseEvent e)
842 windowMenu.add(menuItem);
848 frame.setSelected(true);
849 frame.requestFocus();
850 } catch (java.beans.PropertyVetoException ve)
852 } catch (java.lang.ClassCastException cex)
855 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
860 public void lostOwnership(Clipboard clipboard, Transferable contents)
864 Desktop.jalviewClipboard = null;
867 internalCopy = false;
870 public void dragEnter(DropTargetDragEvent evt)
874 public void dragExit(DropTargetEvent evt)
878 public void dragOver(DropTargetDragEvent evt)
882 public void dropActionChanged(DropTargetDragEvent evt)
892 public void drop(DropTargetDropEvent evt)
894 boolean success = true;
895 Transferable t = evt.getTransferable();
896 java.util.List files = null;
897 java.util.List protocols = null;
901 DataFlavor uriListFlavor = new DataFlavor(
902 "text/uri-list;class=java.lang.String");
903 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
905 // Works on Windows and MacOSX
906 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
907 files = (java.util.List) t
908 .getTransferData(DataFlavor.javaFileListFlavor);
910 else if (t.isDataFlavorSupported(uriListFlavor))
912 // This is used by Unix drag system
913 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
914 String data = (String) t.getTransferData(uriListFlavor);
915 files = new java.util.ArrayList(1);
916 protocols = new java.util.ArrayList(1);
917 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
918 data, "\r\n"); st.hasMoreTokens();)
920 String s = st.nextToken();
921 if (s.startsWith("#"))
923 // the line is a comment (as per the RFC 2483)
926 java.net.URI uri = new java.net.URI(s);
927 if (uri.getScheme().toLowerCase().startsWith("http"))
929 protocols.add(FormatAdapter.URL);
930 files.add(uri.toString());
934 // otherwise preserve old behaviour: catch all for file objects
935 java.io.File file = new java.io.File(uri);
936 protocols.add(FormatAdapter.FILE);
937 files.add(file.toString());
941 } catch (Exception e)
950 for (int i = 0; i < files.size(); i++)
952 String file = files.get(i).toString();
953 String protocol = (protocols == null) ? FormatAdapter.FILE
954 : (String) protocols.get(i);
955 String format = null;
957 if (file.endsWith(".jar"))
964 format = new IdentifyFile().Identify(file, protocol);
967 new FileLoader().LoadFile(file, protocol, format);
970 } catch (Exception ex)
975 evt.dropComplete(success); // need this to ensure input focus is properly
976 // transfered to any new windows created
985 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
987 JalviewFileChooser chooser = new JalviewFileChooser(
988 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
989 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
990 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
991 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
993 chooser.setFileView(new JalviewFileView());
994 chooser.setDialogTitle(MessageManager
995 .getString("label.open_local_file"));
996 chooser.setToolTipText(MessageManager.getString("action.open"));
998 int value = chooser.showOpenDialog(this);
1000 if (value == JalviewFileChooser.APPROVE_OPTION)
1002 String choice = chooser.getSelectedFile().getPath();
1003 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1004 .getSelectedFile().getParent());
1006 String format = null;
1007 if (chooser.getSelectedFormat() != null
1008 && chooser.getSelectedFormat().equals("Jalview"))
1014 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1017 if (viewport != null)
1019 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1024 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1035 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1037 // This construct allows us to have a wider textfield
1039 JLabel label = new JLabel(
1040 MessageManager.getString("label.input_file_url"));
1041 final JComboBox history = new JComboBox();
1043 JPanel panel = new JPanel(new GridLayout(2, 1));
1046 history.setPreferredSize(new Dimension(400, 20));
1047 history.setEditable(true);
1048 history.addItem("http://www.");
1050 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1054 if (historyItems != null)
1056 st = new StringTokenizer(historyItems, "\t");
1058 while (st.hasMoreTokens())
1060 history.addItem(st.nextElement());
1064 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1065 MessageManager.getString("label.input_alignment_from_url"),
1066 JOptionPane.OK_CANCEL_OPTION);
1068 if (reply != JOptionPane.OK_OPTION)
1073 String url = history.getSelectedItem().toString();
1075 if (url.toLowerCase().endsWith(".jar"))
1077 if (viewport != null)
1079 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1084 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1089 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1091 if (format.equals("URL NOT FOUND"))
1093 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1094 MessageManager.formatMessage("label.couldnt_locate",
1096 { url }), MessageManager
1097 .getString("label.url_not_found"),
1098 JOptionPane.WARNING_MESSAGE);
1103 if (viewport != null)
1105 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1109 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1120 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1122 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1123 cap.setForInput(viewport);
1124 Desktop.addInternalFrame(cap,
1125 MessageManager.getString("label.cut_paste_alignmen_file"),
1134 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1136 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1137 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1139 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1140 getBounds().y, getWidth(), getHeight()));
1142 if (jconsole != null)
1144 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1145 jconsole.stopConsole();
1149 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1152 if (dialogExecutor != null)
1154 dialogExecutor.shutdownNow();
1160 private void storeLastKnownDimensions(String string, Rectangle jc)
1162 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1163 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1164 + " height:" + jc.height);
1166 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1167 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1168 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1169 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1178 public void aboutMenuItem_actionPerformed(ActionEvent e)
1180 // StringBuffer message = getAboutMessage(false);
1181 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1183 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1184 new Thread(new Runnable()
1188 new SplashScreen(true);
1193 public StringBuffer getAboutMessage(boolean shortv)
1195 StringBuffer message = new StringBuffer();
1196 message.append("<html>");
1199 message.append("<h1><strong>Version: "
1200 + jalview.bin.Cache.getProperty("VERSION")
1201 + "</strong></h1>");
1202 message.append("<strong>Last Updated: <em>"
1203 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1204 + "</em></strong>");
1210 message.append("<strong>Version "
1211 + jalview.bin.Cache.getProperty("VERSION")
1212 + "; last updated: "
1213 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1216 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1219 message.append("<br>...Checking latest version...</br>");
1221 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1222 .equals(jalview.bin.Cache.getProperty("VERSION")))
1224 boolean red = false;
1225 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1226 .indexOf("automated build") == -1)
1229 // Displayed when code version and jnlp version do not match and code
1230 // version is not a development build
1231 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1234 message.append("<br>!! Version "
1235 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1237 + " is available for download from "
1238 + jalview.bin.Cache.getDefault("www.jalview.org",
1239 "http://www.jalview.org") + " !!");
1242 message.append("</div>");
1245 message.append("<br>Authors: "
1249 "The Jalview Authors (See AUTHORS file for current list)")
1250 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1251 + "<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"
1252 + "<br><br>If you use Jalview, please cite:"
1253 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1254 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1255 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1266 public void documentationMenuItem_actionPerformed(ActionEvent e)
1270 Help.showHelpWindow();
1271 } catch (Exception ex)
1276 public void closeAll_actionPerformed(ActionEvent e)
1278 JInternalFrame[] frames = desktop.getAllFrames();
1279 for (int i = 0; i < frames.length; i++)
1283 frames[i].setClosed(true);
1284 } catch (java.beans.PropertyVetoException ex)
1288 System.out.println("ALL CLOSED");
1289 if (v_client != null)
1291 // TODO clear binding to vamsas document objects on close_all
1296 public void raiseRelated_actionPerformed(ActionEvent e)
1298 reorderAssociatedWindows(false, false);
1301 public void minimizeAssociated_actionPerformed(ActionEvent e)
1303 reorderAssociatedWindows(true, false);
1306 void closeAssociatedWindows()
1308 reorderAssociatedWindows(false, true);
1314 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1317 protected void garbageCollect_actionPerformed(ActionEvent e)
1319 // We simply collect the garbage
1320 jalview.bin.Cache.log.debug("Collecting garbage...");
1322 jalview.bin.Cache.log.debug("Finished garbage collection.");
1329 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1332 protected void showMemusage_actionPerformed(ActionEvent e)
1334 desktop.showMemoryUsage(showMemusage.isSelected());
1341 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1344 protected void showConsole_actionPerformed(ActionEvent e)
1346 showConsole(showConsole.isSelected());
1349 Console jconsole = null;
1352 * control whether the java console is visible or not
1356 void showConsole(boolean selected)
1358 showConsole.setSelected(selected);
1359 // TODO: decide if we should update properties file
1360 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1362 jconsole.setVisible(selected);
1365 void reorderAssociatedWindows(boolean minimize, boolean close)
1367 JInternalFrame[] frames = desktop.getAllFrames();
1368 if (frames == null || frames.length < 1)
1373 AlignmentViewport source = null, target = null;
1374 if (frames[0] instanceof AlignFrame)
1376 source = ((AlignFrame) frames[0]).getCurrentView();
1378 else if (frames[0] instanceof TreePanel)
1380 source = ((TreePanel) frames[0]).getViewPort();
1382 else if (frames[0] instanceof PCAPanel)
1384 source = ((PCAPanel) frames[0]).av;
1386 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1388 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1393 for (int i = 0; i < frames.length; i++)
1396 if (frames[i] == null)
1400 if (frames[i] instanceof AlignFrame)
1402 target = ((AlignFrame) frames[i]).getCurrentView();
1404 else if (frames[i] instanceof TreePanel)
1406 target = ((TreePanel) frames[i]).getViewPort();
1408 else if (frames[i] instanceof PCAPanel)
1410 target = ((PCAPanel) frames[i]).av;
1412 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1414 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1417 if (source == target)
1423 frames[i].setClosed(true);
1427 frames[i].setIcon(minimize);
1430 frames[i].toFront();
1434 } catch (java.beans.PropertyVetoException ex)
1448 protected void preferences_actionPerformed(ActionEvent e)
1459 public void saveState_actionPerformed(ActionEvent e)
1461 JalviewFileChooser chooser = new JalviewFileChooser(
1462 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1463 { "jvp" }, new String[]
1464 { "Jalview Project" }, "Jalview Project");
1466 chooser.setFileView(new JalviewFileView());
1467 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1469 int value = chooser.showSaveDialog(this);
1471 if (value == JalviewFileChooser.APPROVE_OPTION)
1473 final Desktop me = this;
1474 final java.io.File choice = chooser.getSelectedFile();
1475 setProjectFile(choice);
1477 // TODO or move inside the new Thread?
1478 saveChimeraSessions(choice.getAbsolutePath());
1480 new Thread(new Runnable()
1485 setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new Object[]{choice.getName()}),
1487 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1488 choice.getParent());
1489 // TODO catch and handle errors for savestate
1490 // TODO prevent user from messing with the Desktop whilst we're saving
1493 new Jalview2XML().saveState(choice);
1494 } catch (OutOfMemoryError oom)
1496 new OOMWarning("Whilst saving current state to "
1497 + choice.getName(), oom);
1498 } catch (Exception ex)
1501 "Problems whilst trying to save to " + choice.getName(),
1503 JOptionPane.showMessageDialog(
1505 MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new Object[]{ choice.getName()}),
1506 MessageManager.getString("label.couldnt_save_project"),
1507 JOptionPane.WARNING_MESSAGE);
1509 setProgressBar(null, choice.hashCode());
1516 * Request any open, linked Chimera sessions to save their state.
1518 * @param jalviewProjectFilename
1519 * the filename of the Jalview project; Chimera session files should
1520 * be given distinct, but obviously related, names.
1522 public void saveChimeraSessions(String jalviewProjectFilename)
1525 for (JInternalFrame frame : getAllFrames())
1527 if (frame instanceof ChimeraViewFrame)
1530 * Construct a filename for the Chimera session by append _chimera<n>.py
1531 * to the Jalview project file name.
1533 String chimeraPath = jalviewProjectFilename + "_chimera_" + i
1535 ((ChimeraViewFrame) frame).saveSession(chimeraPath);
1541 private void setProjectFile(File choice)
1543 this.projectFile = choice;
1546 public File getProjectFile()
1548 return this.projectFile;
1557 public void loadState_actionPerformed(ActionEvent e)
1559 JalviewFileChooser chooser = new JalviewFileChooser(
1560 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1561 { "jvp", "jar" }, new String[]
1562 { "Jalview Project", "Jalview Project (old)" },
1564 chooser.setFileView(new JalviewFileView());
1565 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1567 int value = chooser.showOpenDialog(this);
1569 if (value == JalviewFileChooser.APPROVE_OPTION)
1571 final File selectedFile = chooser.getSelectedFile();
1572 setProjectFile(selectedFile);
1573 final String choice = selectedFile.getAbsolutePath();
1574 jalview.bin.Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
1575 new Thread(new Runnable()
1579 setProgressBar(MessageManager.formatMessage(
1580 "label.loading_jalview_project", new Object[]
1585 new Jalview2XML().loadJalviewAlign(choice);
1586 } catch (OutOfMemoryError oom)
1588 new OOMWarning("Whilst loading project from " + choice, oom);
1589 } catch (Exception ex)
1591 Cache.log.error("Problems whilst loading project from "
1593 JOptionPane.showMessageDialog(Desktop.desktop,
1596 "label.error_whilst_loading_project_from",
1599 MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE);
1601 setProgressBar(null, choice.hashCode());
1607 public void inputSequence_actionPerformed(ActionEvent e)
1609 new SequenceFetcher(this);
1612 JPanel progressPanel;
1614 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1616 public void startLoading(final String fileName)
1618 if (fileLoadingCount == 0)
1620 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1621 "label.loading_file", new Object[]
1627 private JPanel addProgressPanel(String string)
1629 if (progressPanel == null)
1631 progressPanel = new JPanel(new GridLayout(1, 1));
1632 totalProgressCount = 0;
1633 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1635 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1636 JProgressBar progressBar = new JProgressBar();
1637 progressBar.setIndeterminate(true);
1639 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1641 thisprogress.add(progressBar, BorderLayout.CENTER);
1642 progressPanel.add(thisprogress);
1643 ((GridLayout) progressPanel.getLayout())
1644 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1645 ++totalProgressCount;
1646 instance.validate();
1647 return thisprogress;
1650 int totalProgressCount = 0;
1652 private void removeProgressPanel(JPanel progbar)
1654 if (progressPanel != null)
1656 synchronized (progressPanel)
1658 progressPanel.remove(progbar);
1659 GridLayout gl = (GridLayout) progressPanel.getLayout();
1660 gl.setRows(gl.getRows() - 1);
1661 if (--totalProgressCount < 1)
1663 this.getContentPane().remove(progressPanel);
1664 progressPanel = null;
1671 public void stopLoading()
1674 if (fileLoadingCount < 1)
1676 while (fileLoadingPanels.size() > 0)
1678 removeProgressPanel(fileLoadingPanels.remove(0));
1680 fileLoadingPanels.clear();
1681 fileLoadingCount = 0;
1686 public static int getViewCount(String alignmentId)
1688 AlignmentViewport[] aps = getViewports(alignmentId);
1689 return (aps == null) ? 0 : aps.length;
1694 * @param alignmentId
1695 * @return all AlignmentPanels concerning the alignmentId sequence set
1697 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1699 if (Desktop.desktop == null)
1701 // no frames created and in headless mode
1702 // TODO: verify that frames are recoverable when in headless mode
1705 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1706 AlignFrame[] frames = getAlignFrames();
1711 for (AlignFrame af : frames)
1713 for (AlignmentPanel ap : af.alignPanels)
1715 if (alignmentId.equals(ap.av.getSequenceSetId()))
1720 // for (int a = 0; a < af.alignPanels.size(); a++)
1722 // if (alignmentId.equals(af.alignPanels
1723 // .get(a).av.getSequenceSetId()))
1725 // aps.add(af.alignPanels.get(a));
1729 if (aps.size() == 0)
1733 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1738 * get all the viewports on an alignment.
1740 * @param sequenceSetId
1741 * unique alignment id
1742 * @return all viewports on the alignment bound to sequenceSetId
1744 public static AlignmentViewport[] getViewports(String sequenceSetId)
1746 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1747 if (desktop != null)
1749 AlignFrame[] frames = Desktop.getAlignFrames();
1751 for (AlignFrame afr : frames)
1753 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1755 if (afr.alignPanels != null)
1757 for (AlignmentPanel ap : afr.alignPanels)
1759 if (sequenceSetId.equals(ap.av.getSequenceSetId()))
1767 viewp.add(afr.getViewport());
1771 if (viewp.size() > 0)
1773 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1779 public void explodeViews(AlignFrame af)
1781 int size = af.alignPanels.size();
1787 for (int i = 0; i < size; i++)
1789 AlignmentPanel ap = af.alignPanels.get(i);
1790 AlignFrame newaf = new AlignFrame(ap);
1791 if (ap.av.explodedPosition != null
1792 && !ap.av.explodedPosition.equals(af.getBounds()))
1794 newaf.setBounds(ap.av.explodedPosition);
1797 ap.av.gatherViewsHere = false;
1799 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1800 AlignFrame.DEFAULT_HEIGHT);
1803 af.alignPanels.clear();
1804 af.closeMenuItem_actionPerformed(true);
1808 public void gatherViews(AlignFrame source)
1810 source.viewport.gatherViewsHere = true;
1811 source.viewport.explodedPosition = source.getBounds();
1812 JInternalFrame[] frames = desktop.getAllFrames();
1813 String viewId = source.viewport.getSequenceSetId();
1815 for (int t = 0; t < frames.length; t++)
1817 if (frames[t] instanceof AlignFrame && frames[t] != source)
1819 AlignFrame af = (AlignFrame) frames[t];
1820 boolean gatherThis = false;
1821 for (int a = 0; a < af.alignPanels.size(); a++)
1823 AlignmentPanel ap = af.alignPanels.get(a);
1824 if (viewId.equals(ap.av.getSequenceSetId()))
1827 ap.av.gatherViewsHere = false;
1828 ap.av.explodedPosition = af.getBounds();
1829 source.addAlignmentPanel(ap, false);
1835 af.alignPanels.clear();
1836 af.closeMenuItem_actionPerformed(true);
1843 jalview.gui.VamsasApplication v_client = null;
1845 public void vamsasImport_actionPerformed(ActionEvent e)
1847 if (v_client == null)
1849 // Load and try to start a session.
1850 JalviewFileChooser chooser = new JalviewFileChooser(
1851 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1853 chooser.setFileView(new JalviewFileView());
1854 chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
1855 chooser.setToolTipText(MessageManager
1856 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1858 int value = chooser.showOpenDialog(this);
1860 if (value == JalviewFileChooser.APPROVE_OPTION)
1862 String fle = chooser.getSelectedFile().toString();
1863 if (!vamsasImport(chooser.getSelectedFile()))
1866 .showInternalMessageDialog(
1868 MessageManager.formatMessage(
1869 "label.couldnt_import_as_vamsas_session",
1873 .getString("label.vamsas_document_import_failed"),
1874 JOptionPane.ERROR_MESSAGE);
1880 jalview.bin.Cache.log
1881 .error("Implementation error - load session from a running session is not supported.");
1886 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1889 * @return true if import was a success and a session was started.
1891 public boolean vamsasImport(URL url)
1893 // TODO: create progress bar
1894 if (v_client != null)
1897 jalview.bin.Cache.log
1898 .error("Implementation error - load session from a running session is not supported.");
1904 // copy the URL content to a temporary local file
1905 // TODO: be a bit cleverer here with nio (?!)
1906 File file = File.createTempFile("vdocfromurl", ".vdj");
1907 FileOutputStream fos = new FileOutputStream(file);
1908 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1909 byte[] buffer = new byte[2048];
1911 while ((ln = bis.read(buffer)) > -1)
1913 fos.write(buffer, 0, ln);
1917 v_client = new jalview.gui.VamsasApplication(this, file,
1918 url.toExternalForm());
1919 } catch (Exception ex)
1921 jalview.bin.Cache.log.error(
1922 "Failed to create new vamsas session from contents of URL "
1926 setupVamsasConnectedGui();
1927 v_client.initial_update(); // TODO: thread ?
1928 return v_client.inSession();
1932 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1935 * @return true if import was a success and a session was started.
1937 public boolean vamsasImport(File file)
1939 if (v_client != null)
1942 jalview.bin.Cache.log
1943 .error("Implementation error - load session from a running session is not supported.");
1947 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new Object[]{file.getName()}),
1951 v_client = new jalview.gui.VamsasApplication(this, file, null);
1952 } catch (Exception ex)
1954 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new Object[]{file.getName()}),
1956 jalview.bin.Cache.log.error(
1957 "New vamsas session from existing session file failed:", ex);
1960 setupVamsasConnectedGui();
1961 v_client.initial_update(); // TODO: thread ?
1962 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new Object[]{file.getName()}),
1964 return v_client.inSession();
1967 public boolean joinVamsasSession(String mysesid)
1969 if (v_client != null)
1971 throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
1973 if (mysesid == null)
1975 throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
1977 v_client = new VamsasApplication(this, mysesid);
1978 setupVamsasConnectedGui();
1979 v_client.initial_update();
1980 return (v_client.inSession());
1983 public void vamsasStart_actionPerformed(ActionEvent e)
1985 if (v_client == null)
1988 // we just start a default session for moment.
1990 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1991 * getProperty("LAST_DIRECTORY"));
1993 * chooser.setFileView(new JalviewFileView());
1994 * chooser.setDialogTitle("Load Vamsas file");
1995 * chooser.setToolTipText("Import");
1997 * int value = chooser.showOpenDialog(this);
1999 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2000 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2002 v_client = new VamsasApplication(this);
2003 setupVamsasConnectedGui();
2004 v_client.initial_update(); // TODO: thread ?
2008 // store current data in session.
2009 v_client.push_update(); // TODO: thread
2013 protected void setupVamsasConnectedGui()
2015 vamsasStart.setText(MessageManager.getString("label.session_update"));
2016 vamsasSave.setVisible(true);
2017 vamsasStop.setVisible(true);
2018 vamsasImport.setVisible(false); // Document import to existing session is
2019 // not possible for vamsas-client-1.0.
2022 protected void setupVamsasDisconnectedGui()
2024 vamsasSave.setVisible(false);
2025 vamsasStop.setVisible(false);
2026 vamsasImport.setVisible(true);
2027 vamsasStart.setText(MessageManager
2028 .getString("label.new_vamsas_session"));
2031 public void vamsasStop_actionPerformed(ActionEvent e)
2033 if (v_client != null)
2035 v_client.end_session();
2037 setupVamsasDisconnectedGui();
2041 protected void buildVamsasStMenu()
2043 if (v_client == null)
2045 String[] sess = null;
2048 sess = VamsasApplication.getSessionList();
2049 } catch (Exception e)
2051 jalview.bin.Cache.log.warn(
2052 "Problem getting current sessions list.", e);
2057 jalview.bin.Cache.log.debug("Got current sessions list: "
2058 + sess.length + " entries.");
2059 VamsasStMenu.removeAll();
2060 for (int i = 0; i < sess.length; i++)
2062 JMenuItem sessit = new JMenuItem();
2063 sessit.setText(sess[i]);
2064 sessit.setToolTipText(MessageManager.formatMessage(
2065 "label.connect_to_session", new Object[]
2067 final Desktop dsktp = this;
2068 final String mysesid = sess[i];
2069 sessit.addActionListener(new ActionListener()
2072 public void actionPerformed(ActionEvent e)
2074 if (dsktp.v_client == null)
2076 Thread rthr = new Thread(new Runnable()
2081 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2082 dsktp.setupVamsasConnectedGui();
2083 dsktp.v_client.initial_update();
2091 VamsasStMenu.add(sessit);
2093 // don't show an empty menu.
2094 VamsasStMenu.setVisible(sess.length > 0);
2099 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2100 VamsasStMenu.removeAll();
2101 VamsasStMenu.setVisible(false);
2106 // Not interested in the content. Just hide ourselves.
2107 VamsasStMenu.setVisible(false);
2111 public void vamsasSave_actionPerformed(ActionEvent e)
2113 if (v_client != null)
2115 JalviewFileChooser chooser = new JalviewFileChooser(
2116 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2117 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2119 { "Vamsas Document" }, "Vamsas Document");
2121 chooser.setFileView(new JalviewFileView());
2122 chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
2124 int value = chooser.showSaveDialog(this);
2126 if (value == JalviewFileChooser.APPROVE_OPTION)
2128 java.io.File choice = chooser.getSelectedFile();
2129 JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new Object[]{choice.getName()}));
2130 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2131 String warnmsg = null;
2132 String warnttl = null;
2135 v_client.vclient.storeDocument(choice);
2138 warnttl = "Serious Problem saving Vamsas Document";
2139 warnmsg = ex.toString();
2140 jalview.bin.Cache.log.error("Error Whilst saving document to "
2143 } catch (Exception ex)
2145 warnttl = "Problem saving Vamsas Document.";
2146 warnmsg = ex.toString();
2147 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2151 removeProgressPanel(progpanel);
2152 if (warnmsg != null)
2154 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2156 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2162 JPanel vamUpdate = null;
2165 * hide vamsas user gui bits when a vamsas document event is being handled.
2168 * true to hide gui, false to reveal gui
2170 public void setVamsasUpdate(boolean b)
2172 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2173 + (b ? "in progress" : "finished"));
2175 if (vamUpdate != null)
2177 this.removeProgressPanel(vamUpdate);
2181 vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
2183 vamsasStart.setVisible(!b);
2184 vamsasStop.setVisible(!b);
2185 vamsasSave.setVisible(!b);
2188 public JInternalFrame[] getAllFrames()
2190 return desktop.getAllFrames();
2194 * Checks the given url to see if it gives a response indicating that the user
2195 * should be informed of a new questionnaire.
2199 public void checkForQuestionnaire(String url)
2201 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2202 // javax.swing.SwingUtilities.invokeLater(jvq);
2203 new Thread(jvq).start();
2207 * Proxy class for JDesktopPane which optionally displays the current memory
2208 * usage and highlights the desktop area with a red bar if free memory runs
2213 public class MyDesktopPane extends JDesktopPane implements Runnable
2216 private static final float ONE_MB = 1048576f;
2218 boolean showMemoryUsage = false;
2222 java.text.NumberFormat df;
2224 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2227 public MyDesktopPane(boolean showMemoryUsage)
2229 showMemoryUsage(showMemoryUsage);
2232 public void showMemoryUsage(boolean showMemoryUsage)
2234 this.showMemoryUsage = showMemoryUsage;
2235 if (showMemoryUsage)
2237 Thread worker = new Thread(this);
2242 public boolean isShowMemoryUsage()
2244 return showMemoryUsage;
2249 df = java.text.NumberFormat.getNumberInstance();
2250 df.setMaximumFractionDigits(2);
2251 runtime = Runtime.getRuntime();
2253 while (showMemoryUsage)
2257 maxMemory = runtime.maxMemory() / ONE_MB;
2258 allocatedMemory = runtime.totalMemory() / ONE_MB;
2259 freeMemory = runtime.freeMemory() / ONE_MB;
2260 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2262 percentUsage = (totalFreeMemory / maxMemory) * 100;
2264 // if (percentUsage < 20)
2266 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2268 // instance.set.setBorder(border1);
2271 // sleep after showing usage
2273 } catch (Exception ex)
2275 ex.printStackTrace();
2280 public void paintComponent(Graphics g)
2282 if (showMemoryUsage && g != null && df != null)
2284 if (percentUsage < 20)
2286 g.setColor(Color.red);
2288 FontMetrics fm = g.getFontMetrics();
2291 g.drawString(MessageManager.formatMessage(
2292 "label.memory_stats",
2294 { df.format(totalFreeMemory), df.format(maxMemory),
2295 df.format(percentUsage) }), 10,
2296 getHeight() - fm.getHeight());
2303 * fixes stacking order after a modal dialog to ensure windows that should be
2304 * on top actually are
2306 public void relayerWindows()
2311 protected JMenuItem groovyShell;
2313 public void doGroovyCheck()
2315 if (jalview.bin.Cache.groovyJarsPresent())
2317 groovyShell = new JMenuItem();
2318 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2319 groovyShell.addActionListener(new ActionListener()
2321 public void actionPerformed(ActionEvent e)
2323 groovyShell_actionPerformed(e);
2326 toolsMenu.add(groovyShell);
2327 groovyShell.setVisible(true);
2332 * Accessor method to quickly get all the AlignmentFrames loaded.
2334 * @return an array of AlignFrame, or null if none found
2336 public static AlignFrame[] getAlignFrames()
2338 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2344 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2346 for (int i = frames.length - 1; i > -1; i--)
2348 if (frames[i] instanceof AlignFrame)
2350 avp.add((AlignFrame) frames[i]);
2352 else if (frames[i] instanceof SplitFrame)
2355 * Also check for a split frame containing an AlignFrame
2357 SplitFrame sf = (SplitFrame) frames[i];
2358 if (sf.getTopComponent() instanceof AlignFrame)
2360 avp.add((AlignFrame) sf.getTopComponent());
2362 if (sf.getBottomComponent() instanceof AlignFrame)
2364 avp.add((AlignFrame) sf.getBottomComponent());
2368 if (avp.size() == 0)
2372 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2377 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2381 public GStructureViewer[] getJmols()
2383 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2389 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2391 for (int i = frames.length - 1; i > -1; i--)
2393 if (frames[i] instanceof AppJmol)
2395 GStructureViewer af = (GStructureViewer) frames[i];
2399 if (avp.size() == 0)
2403 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2408 * Add Groovy Support to Jalview
2410 public void groovyShell_actionPerformed(ActionEvent e)
2412 // use reflection to avoid creating compilation dependency.
2413 if (!jalview.bin.Cache.groovyJarsPresent())
2415 throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
2419 Class gcClass = Desktop.class.getClassLoader().loadClass(
2420 "groovy.ui.Console");
2421 Constructor gccons = gcClass.getConstructor(null);
2422 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2424 { String.class, Object.class });
2425 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2426 Object gc = gccons.newInstance(null);
2427 setvar.invoke(gc, new Object[]
2428 { "Jalview", this });
2429 run.invoke(gc, null);
2430 } catch (Exception ex)
2432 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2434 .showInternalMessageDialog(
2437 MessageManager.getString("label.couldnt_create_groovy_shell"),
2438 MessageManager.getString("label.groovy_support_failed"),
2439 JOptionPane.ERROR_MESSAGE);
2444 * Progress bars managed by the IProgressIndicator method.
2446 private Hashtable<Long, JPanel> progressBars;
2448 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2453 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2455 public void setProgressBar(String message, long id)
2457 if (progressBars == null)
2459 progressBars = new Hashtable<Long, JPanel>();
2460 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2463 if (progressBars.get(new Long(id)) != null)
2465 JPanel progressPanel = progressBars.remove(new Long(id));
2466 if (progressBarHandlers.contains(new Long(id)))
2468 progressBarHandlers.remove(new Long(id));
2470 removeProgressPanel(progressPanel);
2474 progressBars.put(new Long(id), addProgressPanel(message));
2481 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2482 * jalview.gui.IProgressIndicatorHandler)
2484 public void registerHandler(final long id,
2485 final IProgressIndicatorHandler handler)
2487 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2489 throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
2491 progressBarHandlers.put(new Long(id), handler);
2492 final JPanel progressPanel = progressBars.get(new Long(id));
2493 if (handler.canCancel())
2495 JButton cancel = new JButton(
2496 MessageManager.getString("action.cancel"));
2497 final IProgressIndicator us = this;
2498 cancel.addActionListener(new ActionListener()
2501 public void actionPerformed(ActionEvent e)
2503 handler.cancelActivity(id);
2504 us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new Object[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
2507 progressPanel.add(cancel, BorderLayout.EAST);
2513 * @return true if any progress bars are still active
2516 public boolean operationInProgress()
2518 if (progressBars != null && progressBars.size() > 0)
2526 * This will return the first AlignFrame viewing AlignViewport av. It will
2527 * break if there are more than one AlignFrames viewing a particular av.
2530 * @return alignFrame for av
2532 public static AlignFrame getAlignFrameFor(AlignmentViewport av)
2534 if (desktop != null)
2536 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2537 for (int panel = 0; aps != null && panel < aps.length; panel++)
2539 if (aps[panel] != null && aps[panel].av == av)
2541 return aps[panel].alignFrame;
2548 public VamsasApplication getVamsasApplication()
2555 * flag set if jalview GUI is being operated programmatically
2557 private boolean inBatchMode = false;
2560 * check if jalview GUI is being operated programmatically
2562 * @return inBatchMode
2564 public boolean isInBatchMode()
2570 * set flag if jalview GUI is being operated programmatically
2572 * @param inBatchMode
2574 public void setInBatchMode(boolean inBatchMode)
2576 this.inBatchMode = inBatchMode;
2579 public void startServiceDiscovery()
2581 startServiceDiscovery(false);
2584 public void startServiceDiscovery(boolean blocking)
2586 boolean alive = true;
2587 Thread t0 = null, t1 = null, t2 = null;
2588 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2591 // todo: changesupport handlers need to be transferred
2592 if (discoverer == null)
2594 discoverer = new jalview.ws.jws1.Discoverer();
2595 // register PCS handler for desktop.
2596 discoverer.addPropertyChangeListener(changeSupport);
2598 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2599 // until we phase out completely
2600 (t0 = new Thread(discoverer)).start();
2603 // ENFIN services are EOLed as of Jalview 2.8.1 release
2608 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2610 // EnfinEnvision web service menu entries are rebuild every time the
2611 // menu is shown, so no changeSupport events are needed.
2612 jalview.ws.EnfinEnvision2OneWay.getInstance();
2613 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2616 } catch (Exception e)
2619 .info("Exception when trying to launch Envision2 workflow discovery.",
2621 Cache.log.info(e.getStackTrace());
2625 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2627 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2629 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2631 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2637 // TODO: do rest service discovery
2646 } catch (Exception e)
2649 alive = (t1 != null && t1.isAlive())
2650 || (t2 != null && t2.isAlive())
2651 || (t3 != null && t3.isAlive())
2652 || (t0 != null && t0.isAlive());
2658 * called to check if the service discovery process completed successfully.
2662 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2664 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2666 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2667 .getErrorMessages();
2670 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2672 if (serviceChangedDialog == null)
2674 // only run if we aren't already displaying one of these.
2675 addDialogThread(serviceChangedDialog = new Runnable()
2681 * JalviewDialog jd =new JalviewDialog() {
2683 * @Override protected void cancelPressed() { // TODO
2684 * Auto-generated method stub
2686 * }@Override protected void okPressed() { // TODO
2687 * Auto-generated method stub
2689 * }@Override protected void raiseClosed() { // TODO
2690 * Auto-generated method stub
2692 * } }; jd.initDialogFrame(new
2693 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2694 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2695 * + " or mis-configured HTTP proxy settings.<br/>" +
2696 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2698 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2699 * ), true, true, "Web Service Configuration Problem", 450,
2702 * jd.waitForInput();
2708 "<html><table width=\"450\"><tr><td>"
2710 + "</td></tr></table>"
2711 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2712 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2713 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2714 + " Tools->Preferences dialog box to change them.</p></html>"),
2715 "Web Service Configuration Problem",
2716 JOptionPane.DEFAULT_OPTION,
2717 JOptionPane.ERROR_MESSAGE);
2718 serviceChangedDialog = null;
2727 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2734 private Runnable serviceChangedDialog = null;
2737 * start a thread to open a URL in the configured browser. Pops up a warning
2738 * dialog to the user if there is an exception when calling out to the browser
2743 public static void showUrl(final String url)
2745 showUrl(url, Desktop.instance);
2749 * Like showUrl but allows progress handler to be specified
2753 * (null) or object implementing IProgressIndicator
2755 public static void showUrl(final String url,
2756 final IProgressIndicator progress)
2758 new Thread(new Runnable()
2764 if (progress != null)
2766 progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new Object[]{url}), this.hashCode());
2768 jalview.util.BrowserLauncher.openURL(url);
2769 } catch (Exception ex)
2772 .showInternalMessageDialog(
2774 MessageManager.getString("label.web_browser_not_found_unix"),
2775 MessageManager.getString("label.web_browser_not_found"),
2776 JOptionPane.WARNING_MESSAGE);
2778 ex.printStackTrace();
2780 if (progress != null)
2782 progress.setProgressBar(null, this.hashCode());
2788 public static WsParamSetManager wsparamManager = null;
2790 public static ParamManager getUserParameterStore()
2792 if (wsparamManager == null)
2794 wsparamManager = new WsParamSetManager();
2796 return wsparamManager;
2800 * static hyperlink handler proxy method for use by Jalview's internal windows
2804 public static void hyperlinkUpdate(HyperlinkEvent e)
2806 if (e.getEventType() == EventType.ACTIVATED)
2811 url = e.getURL().toString();
2812 Desktop.showUrl(url);
2813 } catch (Exception x)
2817 if (Cache.log != null)
2819 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2823 System.err.println("Couldn't handle string " + url
2827 // ignore any exceptions due to dud links.
2834 * single thread that handles display of dialogs to user.
2836 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2839 * flag indicating if dialogExecutor should try to acquire a permit
2841 private volatile boolean dialogPause = true;
2846 private java.util.concurrent.Semaphore block = new Semaphore(0);
2849 * add another dialog thread to the queue
2853 public void addDialogThread(final Runnable prompter)
2855 dialogExecutor.submit(new Runnable()
2864 } catch (InterruptedException x)
2869 if (instance == null)
2875 SwingUtilities.invokeAndWait(prompter);
2876 } catch (Exception q)
2878 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2884 public void startDialogQueue()
2886 // set the flag so we don't pause waiting for another permit and semaphore
2887 // the current task to begin
2888 dialogPause = false;
2892 protected void snapShotWindow_actionPerformed(ActionEvent e)
2896 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2897 "View of Desktop", getWidth(), getHeight(), of = new File(
2898 "Jalview_snapshot" + System.currentTimeMillis()
2899 + ".eps"), "View of desktop");
2901 paintAll(im.getGraphics());
2903 } catch (Exception q)
2905 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2908 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());