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.api.AlignViewportI;
24 import jalview.bin.Cache;
25 import jalview.io.FileLoader;
26 import jalview.io.FormatAdapter;
27 import jalview.io.IdentifyFile;
28 import jalview.io.JalviewFileChooser;
29 import jalview.io.JalviewFileView;
30 import jalview.jbgui.GStructureViewer;
31 import jalview.structure.StructureSelectionManager;
32 import jalview.util.ImageMaker;
33 import jalview.util.MessageManager;
34 import jalview.viewmodel.AlignmentViewport;
35 import jalview.ws.params.ParamManager;
37 import java.awt.BorderLayout;
38 import java.awt.Color;
39 import java.awt.Dimension;
40 import java.awt.FontMetrics;
41 import java.awt.Graphics;
42 import java.awt.GridLayout;
43 import java.awt.Point;
44 import java.awt.Rectangle;
45 import java.awt.Toolkit;
46 import java.awt.datatransfer.Clipboard;
47 import java.awt.datatransfer.ClipboardOwner;
48 import java.awt.datatransfer.DataFlavor;
49 import java.awt.datatransfer.Transferable;
50 import java.awt.dnd.DnDConstants;
51 import java.awt.dnd.DropTargetDragEvent;
52 import java.awt.dnd.DropTargetDropEvent;
53 import java.awt.dnd.DropTargetEvent;
54 import java.awt.dnd.DropTargetListener;
55 import java.awt.event.ActionEvent;
56 import java.awt.event.ActionListener;
57 import java.awt.event.FocusEvent;
58 import java.awt.event.FocusListener;
59 import java.awt.event.MouseAdapter;
60 import java.awt.event.MouseEvent;
61 import java.awt.event.MouseListener;
62 import java.awt.event.WindowAdapter;
63 import java.awt.event.WindowEvent;
64 import java.beans.PropertyChangeEvent;
65 import java.beans.PropertyChangeListener;
66 import java.beans.PropertyVetoException;
67 import java.io.BufferedInputStream;
69 import java.io.FileOutputStream;
70 import java.lang.reflect.Constructor;
72 import java.util.ArrayList;
73 import java.util.Hashtable;
74 import java.util.List;
75 import java.util.StringTokenizer;
76 import java.util.Vector;
77 import java.util.concurrent.ExecutorService;
78 import java.util.concurrent.Executors;
79 import java.util.concurrent.Semaphore;
81 import javax.swing.DefaultDesktopManager;
82 import javax.swing.DesktopManager;
83 import javax.swing.JButton;
84 import javax.swing.JComboBox;
85 import javax.swing.JComponent;
86 import javax.swing.JDesktopPane;
87 import javax.swing.JFrame;
88 import javax.swing.JInternalFrame;
89 import javax.swing.JLabel;
90 import javax.swing.JMenuItem;
91 import javax.swing.JOptionPane;
92 import javax.swing.JPanel;
93 import javax.swing.JPopupMenu;
94 import javax.swing.JProgressBar;
95 import javax.swing.SwingUtilities;
96 import javax.swing.event.HyperlinkEvent;
97 import javax.swing.event.HyperlinkEvent.EventType;
98 import javax.swing.event.MenuEvent;
99 import javax.swing.event.MenuListener;
106 * @version $Revision: 1.155 $
108 public class Desktop extends jalview.jbgui.GDesktop implements
109 DropTargetListener, ClipboardOwner, IProgressIndicator,
110 jalview.api.StructureSelectionManagerProvider
113 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
116 * news reader - null if it was never started.
118 private BlogReader jvnews = null;
120 private File projectFile;
124 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
126 public void addJalviewPropertyChangeListener(
127 PropertyChangeListener listener)
129 changeSupport.addJalviewPropertyChangeListener(listener);
133 * @param propertyName
135 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
136 * java.beans.PropertyChangeListener)
138 public void addJalviewPropertyChangeListener(String propertyName,
139 PropertyChangeListener listener)
141 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
145 * @param propertyName
147 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
148 * java.beans.PropertyChangeListener)
150 public void removeJalviewPropertyChangeListener(String propertyName,
151 PropertyChangeListener listener)
153 changeSupport.removeJalviewPropertyChangeListener(propertyName,
157 /** Singleton Desktop instance */
158 public static Desktop instance;
160 public static MyDesktopPane desktop;
162 static int openFrameCount = 0;
164 static final int xOffset = 30;
166 static final int yOffset = 30;
168 private static final int THREE = 3;
170 public static jalview.ws.jws1.Discoverer discoverer;
172 public static Object[] jalviewClipboard;
174 public static boolean internalCopy = false;
176 static int fileLoadingCount = 0;
178 class MyDesktopManager implements DesktopManager
181 private DesktopManager delegate;
183 public MyDesktopManager(DesktopManager delegate)
185 this.delegate = delegate;
188 public void activateFrame(JInternalFrame f)
192 delegate.activateFrame(f);
193 } catch (NullPointerException npe)
195 Point p = getMousePosition();
196 instance.showPasteMenu(p.x, p.y);
200 public void beginDraggingFrame(JComponent f)
202 delegate.beginDraggingFrame(f);
205 public void beginResizingFrame(JComponent f, int direction)
207 delegate.beginResizingFrame(f, direction);
210 public void closeFrame(JInternalFrame f)
212 delegate.closeFrame(f);
215 public void deactivateFrame(JInternalFrame f)
217 delegate.deactivateFrame(f);
220 public void deiconifyFrame(JInternalFrame f)
222 delegate.deiconifyFrame(f);
225 public void dragFrame(JComponent f, int newX, int newY)
231 delegate.dragFrame(f, newX, newY);
234 public void endDraggingFrame(JComponent f)
236 delegate.endDraggingFrame(f);
239 public void endResizingFrame(JComponent f)
241 delegate.endResizingFrame(f);
244 public void iconifyFrame(JInternalFrame f)
246 delegate.iconifyFrame(f);
249 public void maximizeFrame(JInternalFrame f)
251 delegate.maximizeFrame(f);
254 public void minimizeFrame(JInternalFrame f)
256 delegate.minimizeFrame(f);
259 public void openFrame(JInternalFrame f)
261 delegate.openFrame(f);
264 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
267 Rectangle b = desktop.getBounds();
272 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
275 public void setBoundsForFrame(JComponent f, int newX, int newY,
276 int newWidth, int newHeight)
278 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
281 // All other methods, simply delegate
286 * Creates a new Desktop object.
291 * A note to implementors. It is ESSENTIAL that any activities that might
292 * block are spawned off as threads rather than waited for during this
296 doVamsasClientCheck();
298 doConfigureStructurePrefs();
299 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
300 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
301 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
303 boolean showjconsole = jalview.bin.Cache.getDefault(
304 "SHOW_JAVA_CONSOLE", false);
305 desktop = new MyDesktopPane(selmemusage);
306 showMemusage.setSelected(selmemusage);
307 desktop.setBackground(Color.white);
308 getContentPane().setLayout(new BorderLayout());
309 // alternate config - have scrollbars - see notes in JAL-153
310 // JScrollPane sp = new JScrollPane();
311 // sp.getViewport().setView(desktop);
312 // getContentPane().add(sp, BorderLayout.CENTER);
313 getContentPane().add(desktop, BorderLayout.CENTER);
314 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
316 // This line prevents Windows Look&Feel resizing all new windows to maximum
317 // if previous window was maximised
318 desktop.setDesktopManager(new MyDesktopManager(
319 new DefaultDesktopManager()));
321 Rectangle dims = getLastKnownDimensions("");
328 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
329 setBounds((screenSize.width - 900) / 2,
330 (screenSize.height - 650) / 2, 900, 650);
332 jconsole = new Console(this, showjconsole);
333 // add essential build information
334 jconsole.setHeader("Jalview Version: "
335 + jalview.bin.Cache.getProperty("VERSION") + "\n"
336 + "Jalview Installation: "
337 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
340 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
341 + "Java version: " + System.getProperty("java.version") + "\n"
342 + System.getProperty("os.arch") + " "
343 + System.getProperty("os.name") + " "
344 + System.getProperty("os.version"));
346 showConsole(showjconsole);
348 showNews.setVisible(false);
350 this.addWindowListener(new WindowAdapter()
352 public void windowClosing(WindowEvent evt)
359 this.addMouseListener(ma = new MouseAdapter()
361 public void mousePressed(MouseEvent evt)
363 if (SwingUtilities.isRightMouseButton(evt))
365 showPasteMenu(evt.getX(), evt.getY());
369 desktop.addMouseListener(ma);
371 this.addFocusListener(new FocusListener()
375 public void focusLost(FocusEvent e)
377 // TODO Auto-generated method stub
382 public void focusGained(FocusEvent e)
384 Cache.log.debug("Relaying windows after focus gain");
385 // make sure that we sort windows properly after we gain focus
386 instance.relayerWindows();
389 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
390 // Spawn a thread that shows the splashscreen
391 SwingUtilities.invokeLater(new Runnable()
400 // Thread off a new instance of the file chooser - this reduces the time it
401 // takes to open it later on.
402 new Thread(new Runnable()
406 Cache.log.debug("Filechooser init thread started.");
407 JalviewFileChooser chooser = new JalviewFileChooser(
408 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
409 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
410 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
411 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
412 Cache.log.debug("Filechooser init thread finished.");
415 // Add the service change listener
416 changeSupport.addJalviewPropertyChangeListener("services",
417 new PropertyChangeListener()
421 public void propertyChange(PropertyChangeEvent evt)
423 Cache.log.debug("Firing service changed event for "
424 + evt.getNewValue());
425 JalviewServicesChanged(evt);
431 public void doConfigureStructurePrefs()
433 // configure services
434 StructureSelectionManager ssm = StructureSelectionManager
435 .getStructureSelectionManager(this);
436 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
438 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
439 Preferences.ADD_TEMPFACT_ANN, true));
440 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(Preferences.STRUCT_FROM_PDB, true));
441 ssm.setSecStructServices(jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW,
446 ssm.setAddTempFacAnnot(false);
447 ssm.setProcessSecondaryStructure(false);
448 ssm.setSecStructServices(false);
452 public void checkForNews()
454 final Desktop me = this;
455 // Thread off the news reader, in case there are connection problems.
456 addDialogThread(new Runnable()
461 Cache.log.debug("Starting news thread.");
463 jvnews = new BlogReader(me);
464 showNews.setVisible(true);
465 Cache.log.debug("Completed news thread.");
470 protected void showNews_actionPerformed(ActionEvent e)
472 showNews(showNews.isSelected());
475 void showNews(boolean visible)
478 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
479 showNews.setSelected(visible);
480 if (visible && !jvnews.isVisible())
482 new Thread(new Runnable()
487 long instance = System.currentTimeMillis();
488 Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_news"), instance);
489 jvnews.refreshNews();
490 Desktop.instance.setProgressBar(null, instance);
499 * recover the last known dimensions for a jalview window
502 * - empty string is desktop, all other windows have unique prefix
503 * @return null or last known dimensions scaled to current geometry (if last
504 * window geom was known)
506 Rectangle getLastKnownDimensions(String windowName)
508 // TODO: lock aspect ratio for scaling desktop Bug #0058199
509 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
510 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
511 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
512 String width = jalview.bin.Cache.getProperty(windowName
514 String height = jalview.bin.Cache.getProperty(windowName
516 if ((x != null) && (y != null) && (width != null) && (height != null))
518 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
519 .parseInt(width), ih = Integer.parseInt(height);
520 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
522 // attempt #1 - try to cope with change in screen geometry - this
523 // version doesn't preserve original jv aspect ratio.
524 // take ratio of current screen size vs original screen size.
525 double sw = ((1f * screenSize.width) / (1f * Integer
526 .parseInt(jalview.bin.Cache
527 .getProperty("SCREENGEOMETRY_WIDTH"))));
528 double sh = ((1f * screenSize.height) / (1f * Integer
529 .parseInt(jalview.bin.Cache
530 .getProperty("SCREENGEOMETRY_HEIGHT"))));
531 // rescale the bounds depending upon the current screen geometry.
532 ix = (int) (ix * sw);
533 iw = (int) (iw * sw);
534 iy = (int) (iy * sh);
535 ih = (int) (ih * sh);
536 while (ix >= screenSize.width)
538 jalview.bin.Cache.log
539 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
540 ix -= screenSize.width;
542 while (iy >= screenSize.height)
544 jalview.bin.Cache.log
545 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
546 iy -= screenSize.height;
548 jalview.bin.Cache.log.debug("Got last known dimensions for "
549 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
552 // return dimensions for new instance
553 return new Rectangle(ix, iy, iw, ih);
558 private void doVamsasClientCheck()
560 if (jalview.bin.Cache.vamsasJarsPresent())
562 setupVamsasDisconnectedGui();
563 VamsasMenu.setVisible(true);
564 final Desktop us = this;
565 VamsasMenu.addMenuListener(new MenuListener()
567 // this listener remembers when the menu was first selected, and
568 // doesn't rebuild the session list until it has been cleared and
570 boolean refresh = true;
572 public void menuCanceled(MenuEvent e)
577 public void menuDeselected(MenuEvent e)
582 public void menuSelected(MenuEvent e)
586 us.buildVamsasStMenu();
591 vamsasStart.setVisible(true);
595 void showPasteMenu(int x, int y)
597 JPopupMenu popup = new JPopupMenu();
598 JMenuItem item = new JMenuItem(
599 MessageManager.getString("label.paste_new_window"));
600 item.addActionListener(new ActionListener()
602 public void actionPerformed(ActionEvent evt)
609 popup.show(this, x, y);
616 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
617 Transferable contents = c.getContents(this);
619 if (contents != null)
621 String file = (String) contents
622 .getTransferData(DataFlavor.stringFlavor);
624 String format = new IdentifyFile().Identify(file,
625 FormatAdapter.PASTE);
627 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
630 } catch (Exception ex)
633 .println("Unable to paste alignment from system clipboard:\n"
639 * Adds and opens the given frame to the desktop
650 public static synchronized void addInternalFrame(
651 final JInternalFrame frame, String title, int w, int h)
653 addInternalFrame(frame, title, true, w, h, true);
658 * Add an internal frame to the Jalview desktop
665 * When true, display frame immediately, otherwise, caller must call
666 * setVisible themselves.
672 public static synchronized void addInternalFrame(
673 final JInternalFrame frame, String title, boolean makeVisible,
676 addInternalFrame(frame, title, makeVisible, w, h, true);
680 * Add an internal frame to the Jalview desktop and make it visible
693 public static synchronized void addInternalFrame(
694 final JInternalFrame frame, String title, int w, int h,
697 addInternalFrame(frame, title, true, w, h, resizable);
701 * Add an internal frame to the Jalview desktop
708 * When true, display frame immediately, otherwise, caller must call
709 * setVisible themselves.
717 public static synchronized void addInternalFrame(
718 final JInternalFrame frame, String title, boolean makeVisible,
719 int w, int h, boolean resizable)
722 // TODO: allow callers to determine X and Y position of frame (eg. via
724 // TODO: consider fixing method to update entries in the window submenu with
725 // the current window title
727 frame.setTitle(title);
728 if (frame.getWidth() < 1 || frame.getHeight() < 1)
732 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
733 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
734 // IF JALVIEW IS RUNNING HEADLESS
735 // ///////////////////////////////////////////////
737 || (System.getProperty("java.awt.headless") != null && System
738 .getProperty("java.awt.headless").equals("true")))
745 frame.setVisible(makeVisible);
746 frame.setClosable(true);
747 frame.setResizable(resizable);
748 frame.setMaximizable(resizable);
749 frame.setIconifiable(resizable);
750 frame.setFrameIcon(null);
752 if (frame.getX() < 1 && frame.getY() < 1)
754 frame.setLocation(xOffset * openFrameCount, yOffset
755 * ((openFrameCount - 1) % 10) + yOffset);
758 final JMenuItem menuItem = new JMenuItem(title);
759 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
761 public void internalFrameActivated(
762 javax.swing.event.InternalFrameEvent evt)
764 JInternalFrame itf = desktop.getSelectedFrame();
772 public void internalFrameClosed(
773 javax.swing.event.InternalFrameEvent evt)
775 PaintRefresher.RemoveComponent(frame);
777 windowMenu.remove(menuItem);
778 JInternalFrame itf = desktop.getSelectedFrame();
787 menuItem.addActionListener(new ActionListener()
789 public void actionPerformed(ActionEvent e)
793 frame.setSelected(true);
794 frame.setIcon(false);
795 } catch (java.beans.PropertyVetoException ex)
801 menuItem.addMouseListener(new MouseListener()
805 public void mouseReleased(MouseEvent e)
810 public void mousePressed(MouseEvent e)
815 public void mouseExited(MouseEvent e)
819 frame.setSelected(false);
820 } catch (PropertyVetoException e1)
826 public void mouseEntered(MouseEvent e)
830 frame.setSelected(true);
831 } catch (PropertyVetoException e1)
837 public void mouseClicked(MouseEvent e)
843 windowMenu.add(menuItem);
849 frame.setSelected(true);
850 frame.requestFocus();
851 } catch (java.beans.PropertyVetoException ve)
853 } catch (java.lang.ClassCastException cex)
856 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
861 public void lostOwnership(Clipboard clipboard, Transferable contents)
865 Desktop.jalviewClipboard = null;
868 internalCopy = false;
871 public void dragEnter(DropTargetDragEvent evt)
875 public void dragExit(DropTargetEvent evt)
879 public void dragOver(DropTargetDragEvent evt)
883 public void dropActionChanged(DropTargetDragEvent evt)
893 public void drop(DropTargetDropEvent evt)
895 boolean success = true;
896 Transferable t = evt.getTransferable();
897 java.util.List files = null;
898 java.util.List protocols = null;
902 DataFlavor uriListFlavor = new DataFlavor(
903 "text/uri-list;class=java.lang.String");
904 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
906 // Works on Windows and MacOSX
907 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
908 files = (java.util.List) t
909 .getTransferData(DataFlavor.javaFileListFlavor);
911 else if (t.isDataFlavorSupported(uriListFlavor))
913 // This is used by Unix drag system
914 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
915 String data = (String) t.getTransferData(uriListFlavor);
916 files = new java.util.ArrayList(1);
917 protocols = new java.util.ArrayList(1);
918 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
919 data, "\r\n"); st.hasMoreTokens();)
921 String s = st.nextToken();
922 if (s.startsWith("#"))
924 // the line is a comment (as per the RFC 2483)
927 java.net.URI uri = new java.net.URI(s);
928 if (uri.getScheme().toLowerCase().startsWith("http"))
930 protocols.add(FormatAdapter.URL);
931 files.add(uri.toString());
935 // otherwise preserve old behaviour: catch all for file objects
936 java.io.File file = new java.io.File(uri);
937 protocols.add(FormatAdapter.FILE);
938 files.add(file.toString());
942 } catch (Exception e)
951 for (int i = 0; i < files.size(); i++)
953 String file = files.get(i).toString();
954 String protocol = (protocols == null) ? FormatAdapter.FILE
955 : (String) protocols.get(i);
956 String format = null;
958 if (file.endsWith(".jar"))
965 format = new IdentifyFile().Identify(file, protocol);
968 new FileLoader().LoadFile(file, protocol, format);
971 } catch (Exception ex)
976 evt.dropComplete(success); // need this to ensure input focus is properly
977 // transfered to any new windows created
986 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
988 JalviewFileChooser chooser = new JalviewFileChooser(
989 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
990 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
991 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
992 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
994 chooser.setFileView(new JalviewFileView());
995 chooser.setDialogTitle(MessageManager
996 .getString("label.open_local_file"));
997 chooser.setToolTipText(MessageManager.getString("action.open"));
999 int value = chooser.showOpenDialog(this);
1001 if (value == JalviewFileChooser.APPROVE_OPTION)
1003 String choice = chooser.getSelectedFile().getPath();
1004 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1005 .getSelectedFile().getParent());
1007 String format = null;
1008 if (chooser.getSelectedFormat() != null
1009 && chooser.getSelectedFormat().equals("Jalview"))
1015 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1018 if (viewport != null)
1020 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1025 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1036 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1038 // This construct allows us to have a wider textfield
1040 JLabel label = new JLabel(
1041 MessageManager.getString("label.input_file_url"));
1042 final JComboBox history = new JComboBox();
1044 JPanel panel = new JPanel(new GridLayout(2, 1));
1047 history.setPreferredSize(new Dimension(400, 20));
1048 history.setEditable(true);
1049 history.addItem("http://www.");
1051 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1055 if (historyItems != null)
1057 st = new StringTokenizer(historyItems, "\t");
1059 while (st.hasMoreTokens())
1061 history.addItem(st.nextElement());
1065 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1066 MessageManager.getString("label.input_alignment_from_url"),
1067 JOptionPane.OK_CANCEL_OPTION);
1069 if (reply != JOptionPane.OK_OPTION)
1074 String url = history.getSelectedItem().toString();
1076 if (url.toLowerCase().endsWith(".jar"))
1078 if (viewport != null)
1080 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1085 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1090 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1092 if (format.equals("URL NOT FOUND"))
1094 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1095 MessageManager.formatMessage("label.couldnt_locate",
1097 { url }), MessageManager
1098 .getString("label.url_not_found"),
1099 JOptionPane.WARNING_MESSAGE);
1104 if (viewport != null)
1106 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1110 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1121 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1123 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1124 cap.setForInput(viewport);
1125 Desktop.addInternalFrame(cap,
1126 MessageManager.getString("label.cut_paste_alignmen_file"),
1135 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1137 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1138 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1140 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1141 getBounds().y, getWidth(), getHeight()));
1143 if (jconsole != null)
1145 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1146 jconsole.stopConsole();
1150 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1153 if (dialogExecutor != null)
1155 dialogExecutor.shutdownNow();
1161 private void storeLastKnownDimensions(String string, Rectangle jc)
1163 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1164 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1165 + " height:" + jc.height);
1167 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1168 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1169 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1170 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1179 public void aboutMenuItem_actionPerformed(ActionEvent e)
1181 // StringBuffer message = getAboutMessage(false);
1182 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1184 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1185 new Thread(new Runnable()
1189 new SplashScreen(true);
1194 public StringBuffer getAboutMessage(boolean shortv)
1196 StringBuffer message = new StringBuffer();
1197 message.append("<html>");
1200 message.append("<h1><strong>Version: "
1201 + jalview.bin.Cache.getProperty("VERSION")
1202 + "</strong></h1>");
1203 message.append("<strong>Last Updated: <em>"
1204 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1205 + "</em></strong>");
1211 message.append("<strong>Version "
1212 + jalview.bin.Cache.getProperty("VERSION")
1213 + "; last updated: "
1214 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1217 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1220 message.append("<br>...Checking latest version...</br>");
1222 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1223 .equals(jalview.bin.Cache.getProperty("VERSION")))
1225 boolean red = false;
1226 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1227 .indexOf("automated build") == -1)
1230 // Displayed when code version and jnlp version do not match and code
1231 // version is not a development build
1232 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1235 message.append("<br>!! Version "
1236 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1238 + " is available for download from "
1239 + jalview.bin.Cache.getDefault("www.jalview.org",
1240 "http://www.jalview.org") + " !!");
1243 message.append("</div>");
1246 message.append("<br>Authors: "
1250 "The Jalview Authors (See AUTHORS file for current list)")
1251 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1252 + "<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"
1253 + "<br><br>If you use Jalview, please cite:"
1254 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1255 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1256 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1267 public void documentationMenuItem_actionPerformed(ActionEvent e)
1271 Help.showHelpWindow();
1272 } catch (Exception ex)
1277 public void closeAll_actionPerformed(ActionEvent e)
1279 JInternalFrame[] frames = desktop.getAllFrames();
1280 for (int i = 0; i < frames.length; i++)
1284 frames[i].setClosed(true);
1285 } catch (java.beans.PropertyVetoException ex)
1289 System.out.println("ALL CLOSED");
1290 if (v_client != null)
1292 // TODO clear binding to vamsas document objects on close_all
1297 public void raiseRelated_actionPerformed(ActionEvent e)
1299 reorderAssociatedWindows(false, false);
1302 public void minimizeAssociated_actionPerformed(ActionEvent e)
1304 reorderAssociatedWindows(true, false);
1307 void closeAssociatedWindows()
1309 reorderAssociatedWindows(false, true);
1315 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1318 protected void garbageCollect_actionPerformed(ActionEvent e)
1320 // We simply collect the garbage
1321 jalview.bin.Cache.log.debug("Collecting garbage...");
1323 jalview.bin.Cache.log.debug("Finished garbage collection.");
1330 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1333 protected void showMemusage_actionPerformed(ActionEvent e)
1335 desktop.showMemoryUsage(showMemusage.isSelected());
1342 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1345 protected void showConsole_actionPerformed(ActionEvent e)
1347 showConsole(showConsole.isSelected());
1350 Console jconsole = null;
1353 * control whether the java console is visible or not
1357 void showConsole(boolean selected)
1359 showConsole.setSelected(selected);
1360 // TODO: decide if we should update properties file
1361 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1363 jconsole.setVisible(selected);
1366 void reorderAssociatedWindows(boolean minimize, boolean close)
1368 JInternalFrame[] frames = desktop.getAllFrames();
1369 if (frames == null || frames.length < 1)
1374 AlignmentViewport source = null, target = null;
1375 if (frames[0] instanceof AlignFrame)
1377 source = ((AlignFrame) frames[0]).getCurrentView();
1379 else if (frames[0] instanceof TreePanel)
1381 source = ((TreePanel) frames[0]).getViewPort();
1383 else if (frames[0] instanceof PCAPanel)
1385 source = ((PCAPanel) frames[0]).av;
1387 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1389 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1394 for (int i = 0; i < frames.length; i++)
1397 if (frames[i] == null)
1401 if (frames[i] instanceof AlignFrame)
1403 target = ((AlignFrame) frames[i]).getCurrentView();
1405 else if (frames[i] instanceof TreePanel)
1407 target = ((TreePanel) frames[i]).getViewPort();
1409 else if (frames[i] instanceof PCAPanel)
1411 target = ((PCAPanel) frames[i]).av;
1413 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1415 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1418 if (source == target)
1424 frames[i].setClosed(true);
1428 frames[i].setIcon(minimize);
1431 frames[i].toFront();
1435 } catch (java.beans.PropertyVetoException ex)
1449 protected void preferences_actionPerformed(ActionEvent e)
1460 public void saveState_actionPerformed(ActionEvent e)
1462 JalviewFileChooser chooser = new JalviewFileChooser(
1463 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1464 { "jvp" }, new String[]
1465 { "Jalview Project" }, "Jalview Project");
1467 chooser.setFileView(new JalviewFileView());
1468 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1470 int value = chooser.showSaveDialog(this);
1472 if (value == JalviewFileChooser.APPROVE_OPTION)
1474 final Desktop me = this;
1475 final java.io.File choice = chooser.getSelectedFile();
1476 setProjectFile(choice);
1478 // TODO or move inside the new Thread?
1479 saveChimeraSessions(choice.getAbsolutePath());
1481 new Thread(new Runnable()
1486 setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new Object[]{choice.getName()}),
1488 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1489 choice.getParent());
1490 // TODO catch and handle errors for savestate
1491 // TODO prevent user from messing with the Desktop whilst we're saving
1494 new Jalview2XML().saveState(choice);
1495 } catch (OutOfMemoryError oom)
1497 new OOMWarning("Whilst saving current state to "
1498 + choice.getName(), oom);
1499 } catch (Exception ex)
1502 "Problems whilst trying to save to " + choice.getName(),
1504 JOptionPane.showMessageDialog(
1506 MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new Object[]{ choice.getName()}),
1507 MessageManager.getString("label.couldnt_save_project"),
1508 JOptionPane.WARNING_MESSAGE);
1510 setProgressBar(null, choice.hashCode());
1517 * Request any open, linked Chimera sessions to save their state.
1519 * @param jalviewProjectFilename
1520 * the filename of the Jalview project; Chimera session files should
1521 * be given distinct, but obviously related, names.
1523 public void saveChimeraSessions(String jalviewProjectFilename)
1526 for (JInternalFrame frame : getAllFrames())
1528 if (frame instanceof ChimeraViewFrame)
1531 * Construct a filename for the Chimera session by append _chimera<n>.py
1532 * to the Jalview project file name.
1534 String chimeraPath = jalviewProjectFilename + "_chimera_" + i
1536 ((ChimeraViewFrame) frame).saveSession(chimeraPath);
1542 private void setProjectFile(File choice)
1544 this.projectFile = choice;
1547 public File getProjectFile()
1549 return this.projectFile;
1558 public void loadState_actionPerformed(ActionEvent e)
1560 JalviewFileChooser chooser = new JalviewFileChooser(
1561 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1562 { "jvp", "jar" }, new String[]
1563 { "Jalview Project", "Jalview Project (old)" },
1565 chooser.setFileView(new JalviewFileView());
1566 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1568 int value = chooser.showOpenDialog(this);
1570 if (value == JalviewFileChooser.APPROVE_OPTION)
1572 final File selectedFile = chooser.getSelectedFile();
1573 setProjectFile(selectedFile);
1574 final String choice = selectedFile.getAbsolutePath();
1575 jalview.bin.Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
1576 new Thread(new Runnable()
1580 setProgressBar(MessageManager.formatMessage(
1581 "label.loading_jalview_project", new Object[]
1586 new Jalview2XML().loadJalviewAlign(choice);
1587 } catch (OutOfMemoryError oom)
1589 new OOMWarning("Whilst loading project from " + choice, oom);
1590 } catch (Exception ex)
1592 Cache.log.error("Problems whilst loading project from "
1594 JOptionPane.showMessageDialog(Desktop.desktop,
1597 "label.error_whilst_loading_project_from",
1600 MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE);
1602 setProgressBar(null, choice.hashCode());
1608 public void inputSequence_actionPerformed(ActionEvent e)
1610 new SequenceFetcher(this);
1613 JPanel progressPanel;
1615 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1617 public void startLoading(final String fileName)
1619 if (fileLoadingCount == 0)
1621 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1622 "label.loading_file", new Object[]
1628 private JPanel addProgressPanel(String string)
1630 if (progressPanel == null)
1632 progressPanel = new JPanel(new GridLayout(1, 1));
1633 totalProgressCount = 0;
1634 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1636 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1637 JProgressBar progressBar = new JProgressBar();
1638 progressBar.setIndeterminate(true);
1640 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1642 thisprogress.add(progressBar, BorderLayout.CENTER);
1643 progressPanel.add(thisprogress);
1644 ((GridLayout) progressPanel.getLayout())
1645 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1646 ++totalProgressCount;
1647 instance.validate();
1648 return thisprogress;
1651 int totalProgressCount = 0;
1653 private void removeProgressPanel(JPanel progbar)
1655 if (progressPanel != null)
1657 synchronized (progressPanel)
1659 progressPanel.remove(progbar);
1660 GridLayout gl = (GridLayout) progressPanel.getLayout();
1661 gl.setRows(gl.getRows() - 1);
1662 if (--totalProgressCount < 1)
1664 this.getContentPane().remove(progressPanel);
1665 progressPanel = null;
1672 public void stopLoading()
1675 if (fileLoadingCount < 1)
1677 while (fileLoadingPanels.size() > 0)
1679 removeProgressPanel(fileLoadingPanels.remove(0));
1681 fileLoadingPanels.clear();
1682 fileLoadingCount = 0;
1687 public static int getViewCount(String alignmentId)
1689 AlignmentViewport[] aps = getViewports(alignmentId);
1690 return (aps == null) ? 0 : aps.length;
1695 * @param alignmentId
1696 * - if null, all sets are returned
1697 * @return all AlignmentPanels concerning the alignmentId sequence set
1699 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1701 if (Desktop.desktop == null)
1703 // no frames created and in headless mode
1704 // TODO: verify that frames are recoverable when in headless mode
1707 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1708 AlignFrame[] frames = getAlignFrames();
1713 for (AlignFrame af : frames)
1715 for (AlignmentPanel ap : af.alignPanels)
1717 if (alignmentId==null || alignmentId.equals(ap.av.getSequenceSetId()))
1722 // for (int a = 0; a < af.alignPanels.size(); a++)
1724 // if (alignmentId.equals(af.alignPanels
1725 // .get(a).av.getSequenceSetId()))
1727 // aps.add(af.alignPanels.get(a));
1731 if (aps.size() == 0)
1735 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1740 * get all the viewports on an alignment.
1742 * @param sequenceSetId
1743 * unique alignment id (may be null - all viewports returned in that
1745 * @return all viewports on the alignment bound to sequenceSetId
1747 public static AlignmentViewport[] getViewports(String sequenceSetId)
1749 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1750 if (desktop != null)
1752 AlignFrame[] frames = Desktop.getAlignFrames();
1754 for (AlignFrame afr : frames)
1756 if (sequenceSetId==null || afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1758 if (afr.alignPanels != null)
1760 for (AlignmentPanel ap : afr.alignPanels)
1762 if (sequenceSetId == null
1763 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1771 viewp.add(afr.getViewport());
1775 if (viewp.size() > 0)
1777 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1783 public void explodeViews(AlignFrame af)
1785 int size = af.alignPanels.size();
1791 for (int i = 0; i < size; i++)
1793 AlignmentPanel ap = af.alignPanels.get(i);
1794 AlignFrame newaf = new AlignFrame(ap);
1795 if (ap.av.explodedPosition != null
1796 && !ap.av.explodedPosition.equals(af.getBounds()))
1798 newaf.setBounds(ap.av.explodedPosition);
1801 ap.av.gatherViewsHere = false;
1803 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1804 AlignFrame.DEFAULT_HEIGHT);
1807 af.alignPanels.clear();
1808 af.closeMenuItem_actionPerformed(true);
1812 public void gatherViews(AlignFrame source)
1814 source.viewport.gatherViewsHere = true;
1815 source.viewport.explodedPosition = source.getBounds();
1816 JInternalFrame[] frames = desktop.getAllFrames();
1817 String viewId = source.viewport.getSequenceSetId();
1819 for (int t = 0; t < frames.length; t++)
1821 if (frames[t] instanceof AlignFrame && frames[t] != source)
1823 AlignFrame af = (AlignFrame) frames[t];
1824 boolean gatherThis = false;
1825 for (int a = 0; a < af.alignPanels.size(); a++)
1827 AlignmentPanel ap = af.alignPanels.get(a);
1828 if (viewId.equals(ap.av.getSequenceSetId()))
1831 ap.av.gatherViewsHere = false;
1832 ap.av.explodedPosition = af.getBounds();
1833 source.addAlignmentPanel(ap, false);
1839 af.alignPanels.clear();
1840 af.closeMenuItem_actionPerformed(true);
1847 jalview.gui.VamsasApplication v_client = null;
1849 public void vamsasImport_actionPerformed(ActionEvent e)
1851 if (v_client == null)
1853 // Load and try to start a session.
1854 JalviewFileChooser chooser = new JalviewFileChooser(
1855 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1857 chooser.setFileView(new JalviewFileView());
1858 chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
1859 chooser.setToolTipText(MessageManager
1860 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1862 int value = chooser.showOpenDialog(this);
1864 if (value == JalviewFileChooser.APPROVE_OPTION)
1866 String fle = chooser.getSelectedFile().toString();
1867 if (!vamsasImport(chooser.getSelectedFile()))
1870 .showInternalMessageDialog(
1872 MessageManager.formatMessage(
1873 "label.couldnt_import_as_vamsas_session",
1877 .getString("label.vamsas_document_import_failed"),
1878 JOptionPane.ERROR_MESSAGE);
1884 jalview.bin.Cache.log
1885 .error("Implementation error - load session from a running session is not supported.");
1890 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1893 * @return true if import was a success and a session was started.
1895 public boolean vamsasImport(URL url)
1897 // TODO: create progress bar
1898 if (v_client != null)
1901 jalview.bin.Cache.log
1902 .error("Implementation error - load session from a running session is not supported.");
1908 // copy the URL content to a temporary local file
1909 // TODO: be a bit cleverer here with nio (?!)
1910 File file = File.createTempFile("vdocfromurl", ".vdj");
1911 FileOutputStream fos = new FileOutputStream(file);
1912 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1913 byte[] buffer = new byte[2048];
1915 while ((ln = bis.read(buffer)) > -1)
1917 fos.write(buffer, 0, ln);
1921 v_client = new jalview.gui.VamsasApplication(this, file,
1922 url.toExternalForm());
1923 } catch (Exception ex)
1925 jalview.bin.Cache.log.error(
1926 "Failed to create new vamsas session from contents of URL "
1930 setupVamsasConnectedGui();
1931 v_client.initial_update(); // TODO: thread ?
1932 return v_client.inSession();
1936 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1939 * @return true if import was a success and a session was started.
1941 public boolean vamsasImport(File file)
1943 if (v_client != null)
1946 jalview.bin.Cache.log
1947 .error("Implementation error - load session from a running session is not supported.");
1951 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new Object[]{file.getName()}),
1955 v_client = new jalview.gui.VamsasApplication(this, file, null);
1956 } catch (Exception ex)
1958 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new Object[]{file.getName()}),
1960 jalview.bin.Cache.log.error(
1961 "New vamsas session from existing session file failed:", ex);
1964 setupVamsasConnectedGui();
1965 v_client.initial_update(); // TODO: thread ?
1966 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new Object[]{file.getName()}),
1968 return v_client.inSession();
1971 public boolean joinVamsasSession(String mysesid)
1973 if (v_client != null)
1975 throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
1977 if (mysesid == null)
1979 throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
1981 v_client = new VamsasApplication(this, mysesid);
1982 setupVamsasConnectedGui();
1983 v_client.initial_update();
1984 return (v_client.inSession());
1987 public void vamsasStart_actionPerformed(ActionEvent e)
1989 if (v_client == null)
1992 // we just start a default session for moment.
1994 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1995 * getProperty("LAST_DIRECTORY"));
1997 * chooser.setFileView(new JalviewFileView());
1998 * chooser.setDialogTitle("Load Vamsas file");
1999 * chooser.setToolTipText("Import");
2001 * int value = chooser.showOpenDialog(this);
2003 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2004 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2006 v_client = new VamsasApplication(this);
2007 setupVamsasConnectedGui();
2008 v_client.initial_update(); // TODO: thread ?
2012 // store current data in session.
2013 v_client.push_update(); // TODO: thread
2017 protected void setupVamsasConnectedGui()
2019 vamsasStart.setText(MessageManager.getString("label.session_update"));
2020 vamsasSave.setVisible(true);
2021 vamsasStop.setVisible(true);
2022 vamsasImport.setVisible(false); // Document import to existing session is
2023 // not possible for vamsas-client-1.0.
2026 protected void setupVamsasDisconnectedGui()
2028 vamsasSave.setVisible(false);
2029 vamsasStop.setVisible(false);
2030 vamsasImport.setVisible(true);
2031 vamsasStart.setText(MessageManager
2032 .getString("label.new_vamsas_session"));
2035 public void vamsasStop_actionPerformed(ActionEvent e)
2037 if (v_client != null)
2039 v_client.end_session();
2041 setupVamsasDisconnectedGui();
2045 protected void buildVamsasStMenu()
2047 if (v_client == null)
2049 String[] sess = null;
2052 sess = VamsasApplication.getSessionList();
2053 } catch (Exception e)
2055 jalview.bin.Cache.log.warn(
2056 "Problem getting current sessions list.", e);
2061 jalview.bin.Cache.log.debug("Got current sessions list: "
2062 + sess.length + " entries.");
2063 VamsasStMenu.removeAll();
2064 for (int i = 0; i < sess.length; i++)
2066 JMenuItem sessit = new JMenuItem();
2067 sessit.setText(sess[i]);
2068 sessit.setToolTipText(MessageManager.formatMessage(
2069 "label.connect_to_session", new Object[]
2071 final Desktop dsktp = this;
2072 final String mysesid = sess[i];
2073 sessit.addActionListener(new ActionListener()
2076 public void actionPerformed(ActionEvent e)
2078 if (dsktp.v_client == null)
2080 Thread rthr = new Thread(new Runnable()
2085 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2086 dsktp.setupVamsasConnectedGui();
2087 dsktp.v_client.initial_update();
2095 VamsasStMenu.add(sessit);
2097 // don't show an empty menu.
2098 VamsasStMenu.setVisible(sess.length > 0);
2103 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2104 VamsasStMenu.removeAll();
2105 VamsasStMenu.setVisible(false);
2110 // Not interested in the content. Just hide ourselves.
2111 VamsasStMenu.setVisible(false);
2115 public void vamsasSave_actionPerformed(ActionEvent e)
2117 if (v_client != null)
2119 JalviewFileChooser chooser = new JalviewFileChooser(
2120 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2121 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2123 { "Vamsas Document" }, "Vamsas Document");
2125 chooser.setFileView(new JalviewFileView());
2126 chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
2128 int value = chooser.showSaveDialog(this);
2130 if (value == JalviewFileChooser.APPROVE_OPTION)
2132 java.io.File choice = chooser.getSelectedFile();
2133 JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new Object[]{choice.getName()}));
2134 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2135 String warnmsg = null;
2136 String warnttl = null;
2139 v_client.vclient.storeDocument(choice);
2142 warnttl = "Serious Problem saving Vamsas Document";
2143 warnmsg = ex.toString();
2144 jalview.bin.Cache.log.error("Error Whilst saving document to "
2147 } catch (Exception ex)
2149 warnttl = "Problem saving Vamsas Document.";
2150 warnmsg = ex.toString();
2151 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2155 removeProgressPanel(progpanel);
2156 if (warnmsg != null)
2158 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2160 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2166 JPanel vamUpdate = null;
2169 * hide vamsas user gui bits when a vamsas document event is being handled.
2172 * true to hide gui, false to reveal gui
2174 public void setVamsasUpdate(boolean b)
2176 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2177 + (b ? "in progress" : "finished"));
2179 if (vamUpdate != null)
2181 this.removeProgressPanel(vamUpdate);
2185 vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
2187 vamsasStart.setVisible(!b);
2188 vamsasStop.setVisible(!b);
2189 vamsasSave.setVisible(!b);
2192 public JInternalFrame[] getAllFrames()
2194 return desktop.getAllFrames();
2198 * Checks the given url to see if it gives a response indicating that the user
2199 * should be informed of a new questionnaire.
2203 public void checkForQuestionnaire(String url)
2205 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2206 // javax.swing.SwingUtilities.invokeLater(jvq);
2207 new Thread(jvq).start();
2211 * Proxy class for JDesktopPane which optionally displays the current memory
2212 * usage and highlights the desktop area with a red bar if free memory runs
2217 public class MyDesktopPane extends JDesktopPane implements Runnable
2220 private static final float ONE_MB = 1048576f;
2222 boolean showMemoryUsage = false;
2226 java.text.NumberFormat df;
2228 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2231 public MyDesktopPane(boolean showMemoryUsage)
2233 showMemoryUsage(showMemoryUsage);
2236 public void showMemoryUsage(boolean showMemoryUsage)
2238 this.showMemoryUsage = showMemoryUsage;
2239 if (showMemoryUsage)
2241 Thread worker = new Thread(this);
2246 public boolean isShowMemoryUsage()
2248 return showMemoryUsage;
2253 df = java.text.NumberFormat.getNumberInstance();
2254 df.setMaximumFractionDigits(2);
2255 runtime = Runtime.getRuntime();
2257 while (showMemoryUsage)
2261 maxMemory = runtime.maxMemory() / ONE_MB;
2262 allocatedMemory = runtime.totalMemory() / ONE_MB;
2263 freeMemory = runtime.freeMemory() / ONE_MB;
2264 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2266 percentUsage = (totalFreeMemory / maxMemory) * 100;
2268 // if (percentUsage < 20)
2270 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2272 // instance.set.setBorder(border1);
2275 // sleep after showing usage
2277 } catch (Exception ex)
2279 ex.printStackTrace();
2284 public void paintComponent(Graphics g)
2286 if (showMemoryUsage && g != null && df != null)
2288 if (percentUsage < 20)
2290 g.setColor(Color.red);
2292 FontMetrics fm = g.getFontMetrics();
2295 g.drawString(MessageManager.formatMessage(
2296 "label.memory_stats",
2298 { df.format(totalFreeMemory), df.format(maxMemory),
2299 df.format(percentUsage) }), 10,
2300 getHeight() - fm.getHeight());
2307 * fixes stacking order after a modal dialog to ensure windows that should be
2308 * on top actually are
2310 public void relayerWindows()
2315 protected JMenuItem groovyShell;
2317 public void doGroovyCheck()
2319 if (jalview.bin.Cache.groovyJarsPresent())
2321 groovyShell = new JMenuItem();
2322 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2323 groovyShell.addActionListener(new ActionListener()
2325 public void actionPerformed(ActionEvent e)
2327 groovyShell_actionPerformed(e);
2330 toolsMenu.add(groovyShell);
2331 groovyShell.setVisible(true);
2336 * Accessor method to quickly get all the AlignmentFrames loaded.
2338 * @return an array of AlignFrame, or null if none found
2340 public static AlignFrame[] getAlignFrames()
2342 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2348 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2350 for (int i = frames.length - 1; i > -1; i--)
2352 if (frames[i] instanceof AlignFrame)
2354 avp.add((AlignFrame) frames[i]);
2356 else if (frames[i] instanceof SplitFrame)
2359 * Also check for a split frame containing an AlignFrame
2361 SplitFrame sf = (SplitFrame) frames[i];
2362 if (sf.getTopComponent() instanceof AlignFrame)
2364 avp.add((AlignFrame) sf.getTopComponent());
2366 if (sf.getBottomComponent() instanceof AlignFrame)
2368 avp.add((AlignFrame) sf.getBottomComponent());
2372 if (avp.size() == 0)
2376 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2381 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2385 public GStructureViewer[] getJmols()
2387 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2393 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2395 for (int i = frames.length - 1; i > -1; i--)
2397 if (frames[i] instanceof AppJmol)
2399 GStructureViewer af = (GStructureViewer) frames[i];
2403 if (avp.size() == 0)
2407 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2412 * Add Groovy Support to Jalview
2414 public void groovyShell_actionPerformed(ActionEvent e)
2416 // use reflection to avoid creating compilation dependency.
2417 if (!jalview.bin.Cache.groovyJarsPresent())
2419 throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
2423 Class gcClass = Desktop.class.getClassLoader().loadClass(
2424 "groovy.ui.Console");
2425 Constructor gccons = gcClass.getConstructor(null);
2426 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2428 { String.class, Object.class });
2429 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2430 Object gc = gccons.newInstance(null);
2431 setvar.invoke(gc, new Object[]
2432 { "Jalview", this });
2433 run.invoke(gc, null);
2434 } catch (Exception ex)
2436 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2438 .showInternalMessageDialog(
2441 MessageManager.getString("label.couldnt_create_groovy_shell"),
2442 MessageManager.getString("label.groovy_support_failed"),
2443 JOptionPane.ERROR_MESSAGE);
2448 * Progress bars managed by the IProgressIndicator method.
2450 private Hashtable<Long, JPanel> progressBars;
2452 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2457 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2459 public void setProgressBar(String message, long id)
2461 if (progressBars == null)
2463 progressBars = new Hashtable<Long, JPanel>();
2464 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2467 if (progressBars.get(new Long(id)) != null)
2469 JPanel progressPanel = progressBars.remove(new Long(id));
2470 if (progressBarHandlers.contains(new Long(id)))
2472 progressBarHandlers.remove(new Long(id));
2474 removeProgressPanel(progressPanel);
2478 progressBars.put(new Long(id), addProgressPanel(message));
2485 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2486 * jalview.gui.IProgressIndicatorHandler)
2488 public void registerHandler(final long id,
2489 final IProgressIndicatorHandler handler)
2491 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2493 throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
2495 progressBarHandlers.put(new Long(id), handler);
2496 final JPanel progressPanel = progressBars.get(new Long(id));
2497 if (handler.canCancel())
2499 JButton cancel = new JButton(
2500 MessageManager.getString("action.cancel"));
2501 final IProgressIndicator us = this;
2502 cancel.addActionListener(new ActionListener()
2505 public void actionPerformed(ActionEvent e)
2507 handler.cancelActivity(id);
2508 us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new Object[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
2511 progressPanel.add(cancel, BorderLayout.EAST);
2517 * @return true if any progress bars are still active
2520 public boolean operationInProgress()
2522 if (progressBars != null && progressBars.size() > 0)
2530 * This will return the AlignFrame holding the given viewport instance. It
2531 * will break if there are more than one AlignFrames viewing a particular av.
2534 * @return alignFrame for viewport
2536 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2538 if (desktop != null)
2540 AlignmentPanel[] aps = getAlignmentPanels(viewport
2541 .getSequenceSetId());
2542 for (int panel = 0; aps != null && panel < aps.length; panel++)
2544 if (aps[panel] != null && aps[panel].av == viewport)
2546 return aps[panel].alignFrame;
2553 public VamsasApplication getVamsasApplication()
2560 * flag set if jalview GUI is being operated programmatically
2562 private boolean inBatchMode = false;
2565 * check if jalview GUI is being operated programmatically
2567 * @return inBatchMode
2569 public boolean isInBatchMode()
2575 * set flag if jalview GUI is being operated programmatically
2577 * @param inBatchMode
2579 public void setInBatchMode(boolean inBatchMode)
2581 this.inBatchMode = inBatchMode;
2584 public void startServiceDiscovery()
2586 startServiceDiscovery(false);
2589 public void startServiceDiscovery(boolean blocking)
2591 boolean alive = true;
2592 Thread t0 = null, t1 = null, t2 = null;
2593 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2596 // todo: changesupport handlers need to be transferred
2597 if (discoverer == null)
2599 discoverer = new jalview.ws.jws1.Discoverer();
2600 // register PCS handler for desktop.
2601 discoverer.addPropertyChangeListener(changeSupport);
2603 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2604 // until we phase out completely
2605 (t0 = new Thread(discoverer)).start();
2608 // ENFIN services are EOLed as of Jalview 2.8.1 release
2613 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2615 // EnfinEnvision web service menu entries are rebuild every time the
2616 // menu is shown, so no changeSupport events are needed.
2617 jalview.ws.EnfinEnvision2OneWay.getInstance();
2618 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2621 } catch (Exception e)
2624 .info("Exception when trying to launch Envision2 workflow discovery.",
2626 Cache.log.info(e.getStackTrace());
2630 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2632 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2634 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2636 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2642 // TODO: do rest service discovery
2651 } catch (Exception e)
2654 alive = (t1 != null && t1.isAlive())
2655 || (t2 != null && t2.isAlive())
2656 || (t3 != null && t3.isAlive())
2657 || (t0 != null && t0.isAlive());
2663 * called to check if the service discovery process completed successfully.
2667 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2669 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2671 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2672 .getErrorMessages();
2675 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2677 if (serviceChangedDialog == null)
2679 // only run if we aren't already displaying one of these.
2680 addDialogThread(serviceChangedDialog = new Runnable()
2686 * JalviewDialog jd =new JalviewDialog() {
2688 * @Override protected void cancelPressed() { // TODO
2689 * Auto-generated method stub
2691 * }@Override protected void okPressed() { // TODO
2692 * Auto-generated method stub
2694 * }@Override protected void raiseClosed() { // TODO
2695 * Auto-generated method stub
2697 * } }; jd.initDialogFrame(new
2698 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2699 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2700 * + " or mis-configured HTTP proxy settings.<br/>" +
2701 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2703 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2704 * ), true, true, "Web Service Configuration Problem", 450,
2707 * jd.waitForInput();
2713 "<html><table width=\"450\"><tr><td>"
2715 + "</td></tr></table>"
2716 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2717 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2718 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2719 + " Tools->Preferences dialog box to change them.</p></html>"),
2720 "Web Service Configuration Problem",
2721 JOptionPane.DEFAULT_OPTION,
2722 JOptionPane.ERROR_MESSAGE);
2723 serviceChangedDialog = null;
2732 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2739 private Runnable serviceChangedDialog = null;
2742 * start a thread to open a URL in the configured browser. Pops up a warning
2743 * dialog to the user if there is an exception when calling out to the browser
2748 public static void showUrl(final String url)
2750 showUrl(url, Desktop.instance);
2754 * Like showUrl but allows progress handler to be specified
2758 * (null) or object implementing IProgressIndicator
2760 public static void showUrl(final String url,
2761 final IProgressIndicator progress)
2763 new Thread(new Runnable()
2769 if (progress != null)
2771 progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new Object[]{url}), this.hashCode());
2773 jalview.util.BrowserLauncher.openURL(url);
2774 } catch (Exception ex)
2777 .showInternalMessageDialog(
2779 MessageManager.getString("label.web_browser_not_found_unix"),
2780 MessageManager.getString("label.web_browser_not_found"),
2781 JOptionPane.WARNING_MESSAGE);
2783 ex.printStackTrace();
2785 if (progress != null)
2787 progress.setProgressBar(null, this.hashCode());
2793 public static WsParamSetManager wsparamManager = null;
2795 public static ParamManager getUserParameterStore()
2797 if (wsparamManager == null)
2799 wsparamManager = new WsParamSetManager();
2801 return wsparamManager;
2805 * static hyperlink handler proxy method for use by Jalview's internal windows
2809 public static void hyperlinkUpdate(HyperlinkEvent e)
2811 if (e.getEventType() == EventType.ACTIVATED)
2816 url = e.getURL().toString();
2817 Desktop.showUrl(url);
2818 } catch (Exception x)
2822 if (Cache.log != null)
2824 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2828 System.err.println("Couldn't handle string " + url
2832 // ignore any exceptions due to dud links.
2839 * single thread that handles display of dialogs to user.
2841 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2844 * flag indicating if dialogExecutor should try to acquire a permit
2846 private volatile boolean dialogPause = true;
2851 private java.util.concurrent.Semaphore block = new Semaphore(0);
2854 * add another dialog thread to the queue
2858 public void addDialogThread(final Runnable prompter)
2860 dialogExecutor.submit(new Runnable()
2869 } catch (InterruptedException x)
2874 if (instance == null)
2880 SwingUtilities.invokeAndWait(prompter);
2881 } catch (Exception q)
2883 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2889 public void startDialogQueue()
2891 // set the flag so we don't pause waiting for another permit and semaphore
2892 // the current task to begin
2893 dialogPause = false;
2897 protected void snapShotWindow_actionPerformed(ActionEvent e)
2901 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2902 "View of Desktop", getWidth(), getHeight(), of = new File(
2903 "Jalview_snapshot" + System.currentTimeMillis()
2904 + ".eps"), "View of desktop");
2906 paintAll(im.getGraphics());
2908 } catch (Exception q)
2910 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2913 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());