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 * - if null, all sets are returned
1696 * @return all AlignmentPanels concerning the alignmentId sequence set
1698 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1700 if (Desktop.desktop == null)
1702 // no frames created and in headless mode
1703 // TODO: verify that frames are recoverable when in headless mode
1706 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1707 AlignFrame[] frames = getAlignFrames();
1712 for (AlignFrame af : frames)
1714 for (AlignmentPanel ap : af.alignPanels)
1716 if (alignmentId==null || alignmentId.equals(ap.av.getSequenceSetId()))
1721 // for (int a = 0; a < af.alignPanels.size(); a++)
1723 // if (alignmentId.equals(af.alignPanels
1724 // .get(a).av.getSequenceSetId()))
1726 // aps.add(af.alignPanels.get(a));
1730 if (aps.size() == 0)
1734 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1739 * get all the viewports on an alignment.
1741 * @param sequenceSetId
1742 * unique alignment id (may be null - all viewports returned in that
1744 * @return all viewports on the alignment bound to sequenceSetId
1746 public static AlignmentViewport[] getViewports(String sequenceSetId)
1748 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1749 if (desktop != null)
1751 AlignFrame[] frames = Desktop.getAlignFrames();
1753 for (AlignFrame afr : frames)
1755 if (sequenceSetId==null || afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1757 if (afr.alignPanels != null)
1759 for (AlignmentPanel ap : afr.alignPanels)
1761 if (sequenceSetId == null
1762 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1770 viewp.add(afr.getViewport());
1774 if (viewp.size() > 0)
1776 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1782 public void explodeViews(AlignFrame af)
1784 int size = af.alignPanels.size();
1790 for (int i = 0; i < size; i++)
1792 AlignmentPanel ap = af.alignPanels.get(i);
1793 AlignFrame newaf = new AlignFrame(ap);
1794 if (ap.av.explodedPosition != null
1795 && !ap.av.explodedPosition.equals(af.getBounds()))
1797 newaf.setBounds(ap.av.explodedPosition);
1800 ap.av.gatherViewsHere = false;
1802 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1803 AlignFrame.DEFAULT_HEIGHT);
1806 af.alignPanels.clear();
1807 af.closeMenuItem_actionPerformed(true);
1811 public void gatherViews(AlignFrame source)
1813 source.viewport.gatherViewsHere = true;
1814 source.viewport.explodedPosition = source.getBounds();
1815 JInternalFrame[] frames = desktop.getAllFrames();
1816 String viewId = source.viewport.getSequenceSetId();
1818 for (int t = 0; t < frames.length; t++)
1820 if (frames[t] instanceof AlignFrame && frames[t] != source)
1822 AlignFrame af = (AlignFrame) frames[t];
1823 boolean gatherThis = false;
1824 for (int a = 0; a < af.alignPanels.size(); a++)
1826 AlignmentPanel ap = af.alignPanels.get(a);
1827 if (viewId.equals(ap.av.getSequenceSetId()))
1830 ap.av.gatherViewsHere = false;
1831 ap.av.explodedPosition = af.getBounds();
1832 source.addAlignmentPanel(ap, false);
1838 af.alignPanels.clear();
1839 af.closeMenuItem_actionPerformed(true);
1846 jalview.gui.VamsasApplication v_client = null;
1848 public void vamsasImport_actionPerformed(ActionEvent e)
1850 if (v_client == null)
1852 // Load and try to start a session.
1853 JalviewFileChooser chooser = new JalviewFileChooser(
1854 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1856 chooser.setFileView(new JalviewFileView());
1857 chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
1858 chooser.setToolTipText(MessageManager
1859 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1861 int value = chooser.showOpenDialog(this);
1863 if (value == JalviewFileChooser.APPROVE_OPTION)
1865 String fle = chooser.getSelectedFile().toString();
1866 if (!vamsasImport(chooser.getSelectedFile()))
1869 .showInternalMessageDialog(
1871 MessageManager.formatMessage(
1872 "label.couldnt_import_as_vamsas_session",
1876 .getString("label.vamsas_document_import_failed"),
1877 JOptionPane.ERROR_MESSAGE);
1883 jalview.bin.Cache.log
1884 .error("Implementation error - load session from a running session is not supported.");
1889 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1892 * @return true if import was a success and a session was started.
1894 public boolean vamsasImport(URL url)
1896 // TODO: create progress bar
1897 if (v_client != null)
1900 jalview.bin.Cache.log
1901 .error("Implementation error - load session from a running session is not supported.");
1907 // copy the URL content to a temporary local file
1908 // TODO: be a bit cleverer here with nio (?!)
1909 File file = File.createTempFile("vdocfromurl", ".vdj");
1910 FileOutputStream fos = new FileOutputStream(file);
1911 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1912 byte[] buffer = new byte[2048];
1914 while ((ln = bis.read(buffer)) > -1)
1916 fos.write(buffer, 0, ln);
1920 v_client = new jalview.gui.VamsasApplication(this, file,
1921 url.toExternalForm());
1922 } catch (Exception ex)
1924 jalview.bin.Cache.log.error(
1925 "Failed to create new vamsas session from contents of URL "
1929 setupVamsasConnectedGui();
1930 v_client.initial_update(); // TODO: thread ?
1931 return v_client.inSession();
1935 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1938 * @return true if import was a success and a session was started.
1940 public boolean vamsasImport(File file)
1942 if (v_client != null)
1945 jalview.bin.Cache.log
1946 .error("Implementation error - load session from a running session is not supported.");
1950 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new Object[]{file.getName()}),
1954 v_client = new jalview.gui.VamsasApplication(this, file, null);
1955 } catch (Exception ex)
1957 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new Object[]{file.getName()}),
1959 jalview.bin.Cache.log.error(
1960 "New vamsas session from existing session file failed:", ex);
1963 setupVamsasConnectedGui();
1964 v_client.initial_update(); // TODO: thread ?
1965 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new Object[]{file.getName()}),
1967 return v_client.inSession();
1970 public boolean joinVamsasSession(String mysesid)
1972 if (v_client != null)
1974 throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
1976 if (mysesid == null)
1978 throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
1980 v_client = new VamsasApplication(this, mysesid);
1981 setupVamsasConnectedGui();
1982 v_client.initial_update();
1983 return (v_client.inSession());
1986 public void vamsasStart_actionPerformed(ActionEvent e)
1988 if (v_client == null)
1991 // we just start a default session for moment.
1993 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1994 * getProperty("LAST_DIRECTORY"));
1996 * chooser.setFileView(new JalviewFileView());
1997 * chooser.setDialogTitle("Load Vamsas file");
1998 * chooser.setToolTipText("Import");
2000 * int value = chooser.showOpenDialog(this);
2002 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2003 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2005 v_client = new VamsasApplication(this);
2006 setupVamsasConnectedGui();
2007 v_client.initial_update(); // TODO: thread ?
2011 // store current data in session.
2012 v_client.push_update(); // TODO: thread
2016 protected void setupVamsasConnectedGui()
2018 vamsasStart.setText(MessageManager.getString("label.session_update"));
2019 vamsasSave.setVisible(true);
2020 vamsasStop.setVisible(true);
2021 vamsasImport.setVisible(false); // Document import to existing session is
2022 // not possible for vamsas-client-1.0.
2025 protected void setupVamsasDisconnectedGui()
2027 vamsasSave.setVisible(false);
2028 vamsasStop.setVisible(false);
2029 vamsasImport.setVisible(true);
2030 vamsasStart.setText(MessageManager
2031 .getString("label.new_vamsas_session"));
2034 public void vamsasStop_actionPerformed(ActionEvent e)
2036 if (v_client != null)
2038 v_client.end_session();
2040 setupVamsasDisconnectedGui();
2044 protected void buildVamsasStMenu()
2046 if (v_client == null)
2048 String[] sess = null;
2051 sess = VamsasApplication.getSessionList();
2052 } catch (Exception e)
2054 jalview.bin.Cache.log.warn(
2055 "Problem getting current sessions list.", e);
2060 jalview.bin.Cache.log.debug("Got current sessions list: "
2061 + sess.length + " entries.");
2062 VamsasStMenu.removeAll();
2063 for (int i = 0; i < sess.length; i++)
2065 JMenuItem sessit = new JMenuItem();
2066 sessit.setText(sess[i]);
2067 sessit.setToolTipText(MessageManager.formatMessage(
2068 "label.connect_to_session", new Object[]
2070 final Desktop dsktp = this;
2071 final String mysesid = sess[i];
2072 sessit.addActionListener(new ActionListener()
2075 public void actionPerformed(ActionEvent e)
2077 if (dsktp.v_client == null)
2079 Thread rthr = new Thread(new Runnable()
2084 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2085 dsktp.setupVamsasConnectedGui();
2086 dsktp.v_client.initial_update();
2094 VamsasStMenu.add(sessit);
2096 // don't show an empty menu.
2097 VamsasStMenu.setVisible(sess.length > 0);
2102 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2103 VamsasStMenu.removeAll();
2104 VamsasStMenu.setVisible(false);
2109 // Not interested in the content. Just hide ourselves.
2110 VamsasStMenu.setVisible(false);
2114 public void vamsasSave_actionPerformed(ActionEvent e)
2116 if (v_client != null)
2118 JalviewFileChooser chooser = new JalviewFileChooser(
2119 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2120 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2122 { "Vamsas Document" }, "Vamsas Document");
2124 chooser.setFileView(new JalviewFileView());
2125 chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
2127 int value = chooser.showSaveDialog(this);
2129 if (value == JalviewFileChooser.APPROVE_OPTION)
2131 java.io.File choice = chooser.getSelectedFile();
2132 JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new Object[]{choice.getName()}));
2133 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2134 String warnmsg = null;
2135 String warnttl = null;
2138 v_client.vclient.storeDocument(choice);
2141 warnttl = "Serious Problem saving Vamsas Document";
2142 warnmsg = ex.toString();
2143 jalview.bin.Cache.log.error("Error Whilst saving document to "
2146 } catch (Exception ex)
2148 warnttl = "Problem saving Vamsas Document.";
2149 warnmsg = ex.toString();
2150 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2154 removeProgressPanel(progpanel);
2155 if (warnmsg != null)
2157 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2159 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2165 JPanel vamUpdate = null;
2168 * hide vamsas user gui bits when a vamsas document event is being handled.
2171 * true to hide gui, false to reveal gui
2173 public void setVamsasUpdate(boolean b)
2175 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2176 + (b ? "in progress" : "finished"));
2178 if (vamUpdate != null)
2180 this.removeProgressPanel(vamUpdate);
2184 vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
2186 vamsasStart.setVisible(!b);
2187 vamsasStop.setVisible(!b);
2188 vamsasSave.setVisible(!b);
2191 public JInternalFrame[] getAllFrames()
2193 return desktop.getAllFrames();
2197 * Checks the given url to see if it gives a response indicating that the user
2198 * should be informed of a new questionnaire.
2202 public void checkForQuestionnaire(String url)
2204 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2205 // javax.swing.SwingUtilities.invokeLater(jvq);
2206 new Thread(jvq).start();
2210 * Proxy class for JDesktopPane which optionally displays the current memory
2211 * usage and highlights the desktop area with a red bar if free memory runs
2216 public class MyDesktopPane extends JDesktopPane implements Runnable
2219 private static final float ONE_MB = 1048576f;
2221 boolean showMemoryUsage = false;
2225 java.text.NumberFormat df;
2227 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2230 public MyDesktopPane(boolean showMemoryUsage)
2232 showMemoryUsage(showMemoryUsage);
2235 public void showMemoryUsage(boolean showMemoryUsage)
2237 this.showMemoryUsage = showMemoryUsage;
2238 if (showMemoryUsage)
2240 Thread worker = new Thread(this);
2245 public boolean isShowMemoryUsage()
2247 return showMemoryUsage;
2252 df = java.text.NumberFormat.getNumberInstance();
2253 df.setMaximumFractionDigits(2);
2254 runtime = Runtime.getRuntime();
2256 while (showMemoryUsage)
2260 maxMemory = runtime.maxMemory() / ONE_MB;
2261 allocatedMemory = runtime.totalMemory() / ONE_MB;
2262 freeMemory = runtime.freeMemory() / ONE_MB;
2263 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2265 percentUsage = (totalFreeMemory / maxMemory) * 100;
2267 // if (percentUsage < 20)
2269 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2271 // instance.set.setBorder(border1);
2274 // sleep after showing usage
2276 } catch (Exception ex)
2278 ex.printStackTrace();
2283 public void paintComponent(Graphics g)
2285 if (showMemoryUsage && g != null && df != null)
2287 if (percentUsage < 20)
2289 g.setColor(Color.red);
2291 FontMetrics fm = g.getFontMetrics();
2294 g.drawString(MessageManager.formatMessage(
2295 "label.memory_stats",
2297 { df.format(totalFreeMemory), df.format(maxMemory),
2298 df.format(percentUsage) }), 10,
2299 getHeight() - fm.getHeight());
2306 * fixes stacking order after a modal dialog to ensure windows that should be
2307 * on top actually are
2309 public void relayerWindows()
2314 protected JMenuItem groovyShell;
2316 public void doGroovyCheck()
2318 if (jalview.bin.Cache.groovyJarsPresent())
2320 groovyShell = new JMenuItem();
2321 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2322 groovyShell.addActionListener(new ActionListener()
2324 public void actionPerformed(ActionEvent e)
2326 groovyShell_actionPerformed(e);
2329 toolsMenu.add(groovyShell);
2330 groovyShell.setVisible(true);
2335 * Accessor method to quickly get all the AlignmentFrames loaded.
2337 * @return an array of AlignFrame, or null if none found
2339 public static AlignFrame[] getAlignFrames()
2341 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2347 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2349 for (int i = frames.length - 1; i > -1; i--)
2351 if (frames[i] instanceof AlignFrame)
2353 avp.add((AlignFrame) frames[i]);
2355 else if (frames[i] instanceof SplitFrame)
2358 * Also check for a split frame containing an AlignFrame
2360 SplitFrame sf = (SplitFrame) frames[i];
2361 if (sf.getTopComponent() instanceof AlignFrame)
2363 avp.add((AlignFrame) sf.getTopComponent());
2365 if (sf.getBottomComponent() instanceof AlignFrame)
2367 avp.add((AlignFrame) sf.getBottomComponent());
2371 if (avp.size() == 0)
2375 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2380 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2384 public GStructureViewer[] getJmols()
2386 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2392 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2394 for (int i = frames.length - 1; i > -1; i--)
2396 if (frames[i] instanceof AppJmol)
2398 GStructureViewer af = (GStructureViewer) frames[i];
2402 if (avp.size() == 0)
2406 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2411 * Add Groovy Support to Jalview
2413 public void groovyShell_actionPerformed(ActionEvent e)
2415 // use reflection to avoid creating compilation dependency.
2416 if (!jalview.bin.Cache.groovyJarsPresent())
2418 throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
2422 Class gcClass = Desktop.class.getClassLoader().loadClass(
2423 "groovy.ui.Console");
2424 Constructor gccons = gcClass.getConstructor(null);
2425 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2427 { String.class, Object.class });
2428 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2429 Object gc = gccons.newInstance(null);
2430 setvar.invoke(gc, new Object[]
2431 { "Jalview", this });
2432 run.invoke(gc, null);
2433 } catch (Exception ex)
2435 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2437 .showInternalMessageDialog(
2440 MessageManager.getString("label.couldnt_create_groovy_shell"),
2441 MessageManager.getString("label.groovy_support_failed"),
2442 JOptionPane.ERROR_MESSAGE);
2447 * Progress bars managed by the IProgressIndicator method.
2449 private Hashtable<Long, JPanel> progressBars;
2451 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2456 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2458 public void setProgressBar(String message, long id)
2460 if (progressBars == null)
2462 progressBars = new Hashtable<Long, JPanel>();
2463 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2466 if (progressBars.get(new Long(id)) != null)
2468 JPanel progressPanel = progressBars.remove(new Long(id));
2469 if (progressBarHandlers.contains(new Long(id)))
2471 progressBarHandlers.remove(new Long(id));
2473 removeProgressPanel(progressPanel);
2477 progressBars.put(new Long(id), addProgressPanel(message));
2484 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2485 * jalview.gui.IProgressIndicatorHandler)
2487 public void registerHandler(final long id,
2488 final IProgressIndicatorHandler handler)
2490 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2492 throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
2494 progressBarHandlers.put(new Long(id), handler);
2495 final JPanel progressPanel = progressBars.get(new Long(id));
2496 if (handler.canCancel())
2498 JButton cancel = new JButton(
2499 MessageManager.getString("action.cancel"));
2500 final IProgressIndicator us = this;
2501 cancel.addActionListener(new ActionListener()
2504 public void actionPerformed(ActionEvent e)
2506 handler.cancelActivity(id);
2507 us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new Object[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
2510 progressPanel.add(cancel, BorderLayout.EAST);
2516 * @return true if any progress bars are still active
2519 public boolean operationInProgress()
2521 if (progressBars != null && progressBars.size() > 0)
2529 * This will return the first AlignFrame viewing AlignViewport av. It will
2530 * break if there are more than one AlignFrames viewing a particular av.
2533 * @return alignFrame for av
2535 public static AlignFrame getAlignFrameFor(AlignmentViewport av)
2537 if (desktop != null)
2539 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2540 for (int panel = 0; aps != null && panel < aps.length; panel++)
2542 if (aps[panel] != null && aps[panel].av == av)
2544 return aps[panel].alignFrame;
2551 public VamsasApplication getVamsasApplication()
2558 * flag set if jalview GUI is being operated programmatically
2560 private boolean inBatchMode = false;
2563 * check if jalview GUI is being operated programmatically
2565 * @return inBatchMode
2567 public boolean isInBatchMode()
2573 * set flag if jalview GUI is being operated programmatically
2575 * @param inBatchMode
2577 public void setInBatchMode(boolean inBatchMode)
2579 this.inBatchMode = inBatchMode;
2582 public void startServiceDiscovery()
2584 startServiceDiscovery(false);
2587 public void startServiceDiscovery(boolean blocking)
2589 boolean alive = true;
2590 Thread t0 = null, t1 = null, t2 = null;
2591 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2594 // todo: changesupport handlers need to be transferred
2595 if (discoverer == null)
2597 discoverer = new jalview.ws.jws1.Discoverer();
2598 // register PCS handler for desktop.
2599 discoverer.addPropertyChangeListener(changeSupport);
2601 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2602 // until we phase out completely
2603 (t0 = new Thread(discoverer)).start();
2606 // ENFIN services are EOLed as of Jalview 2.8.1 release
2611 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2613 // EnfinEnvision web service menu entries are rebuild every time the
2614 // menu is shown, so no changeSupport events are needed.
2615 jalview.ws.EnfinEnvision2OneWay.getInstance();
2616 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2619 } catch (Exception e)
2622 .info("Exception when trying to launch Envision2 workflow discovery.",
2624 Cache.log.info(e.getStackTrace());
2628 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2630 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2632 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2634 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2640 // TODO: do rest service discovery
2649 } catch (Exception e)
2652 alive = (t1 != null && t1.isAlive())
2653 || (t2 != null && t2.isAlive())
2654 || (t3 != null && t3.isAlive())
2655 || (t0 != null && t0.isAlive());
2661 * called to check if the service discovery process completed successfully.
2665 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2667 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2669 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2670 .getErrorMessages();
2673 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2675 if (serviceChangedDialog == null)
2677 // only run if we aren't already displaying one of these.
2678 addDialogThread(serviceChangedDialog = new Runnable()
2684 * JalviewDialog jd =new JalviewDialog() {
2686 * @Override protected void cancelPressed() { // TODO
2687 * Auto-generated method stub
2689 * }@Override protected void okPressed() { // TODO
2690 * Auto-generated method stub
2692 * }@Override protected void raiseClosed() { // TODO
2693 * Auto-generated method stub
2695 * } }; jd.initDialogFrame(new
2696 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2697 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2698 * + " or mis-configured HTTP proxy settings.<br/>" +
2699 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2701 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2702 * ), true, true, "Web Service Configuration Problem", 450,
2705 * jd.waitForInput();
2711 "<html><table width=\"450\"><tr><td>"
2713 + "</td></tr></table>"
2714 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2715 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2716 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2717 + " Tools->Preferences dialog box to change them.</p></html>"),
2718 "Web Service Configuration Problem",
2719 JOptionPane.DEFAULT_OPTION,
2720 JOptionPane.ERROR_MESSAGE);
2721 serviceChangedDialog = null;
2730 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2737 private Runnable serviceChangedDialog = null;
2740 * start a thread to open a URL in the configured browser. Pops up a warning
2741 * dialog to the user if there is an exception when calling out to the browser
2746 public static void showUrl(final String url)
2748 showUrl(url, Desktop.instance);
2752 * Like showUrl but allows progress handler to be specified
2756 * (null) or object implementing IProgressIndicator
2758 public static void showUrl(final String url,
2759 final IProgressIndicator progress)
2761 new Thread(new Runnable()
2767 if (progress != null)
2769 progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new Object[]{url}), this.hashCode());
2771 jalview.util.BrowserLauncher.openURL(url);
2772 } catch (Exception ex)
2775 .showInternalMessageDialog(
2777 MessageManager.getString("label.web_browser_not_found_unix"),
2778 MessageManager.getString("label.web_browser_not_found"),
2779 JOptionPane.WARNING_MESSAGE);
2781 ex.printStackTrace();
2783 if (progress != null)
2785 progress.setProgressBar(null, this.hashCode());
2791 public static WsParamSetManager wsparamManager = null;
2793 public static ParamManager getUserParameterStore()
2795 if (wsparamManager == null)
2797 wsparamManager = new WsParamSetManager();
2799 return wsparamManager;
2803 * static hyperlink handler proxy method for use by Jalview's internal windows
2807 public static void hyperlinkUpdate(HyperlinkEvent e)
2809 if (e.getEventType() == EventType.ACTIVATED)
2814 url = e.getURL().toString();
2815 Desktop.showUrl(url);
2816 } catch (Exception x)
2820 if (Cache.log != null)
2822 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2826 System.err.println("Couldn't handle string " + url
2830 // ignore any exceptions due to dud links.
2837 * single thread that handles display of dialogs to user.
2839 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2842 * flag indicating if dialogExecutor should try to acquire a permit
2844 private volatile boolean dialogPause = true;
2849 private java.util.concurrent.Semaphore block = new Semaphore(0);
2852 * add another dialog thread to the queue
2856 public void addDialogThread(final Runnable prompter)
2858 dialogExecutor.submit(new Runnable()
2867 } catch (InterruptedException x)
2872 if (instance == null)
2878 SwingUtilities.invokeAndWait(prompter);
2879 } catch (Exception q)
2881 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2887 public void startDialogQueue()
2889 // set the flag so we don't pause waiting for another permit and semaphore
2890 // the current task to begin
2891 dialogPause = false;
2895 protected void snapShotWindow_actionPerformed(ActionEvent e)
2899 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2900 "View of Desktop", getWidth(), getHeight(), of = new File(
2901 "Jalview_snapshot" + System.currentTimeMillis()
2902 + ".eps"), "View of desktop");
2904 paintAll(im.getGraphics());
2906 } catch (Exception q)
2908 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2911 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());