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.AlignmentViewPanel;
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")
338 + "\n" + "Build Date: "
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(
440 Preferences.STRUCT_FROM_PDB, true));
441 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
442 Preferences.USE_RNAVIEW, true));
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(
489 MessageManager.getString("status.refreshing_news"),
491 jvnews.refreshNews();
492 Desktop.instance.setProgressBar(null, instance);
501 * recover the last known dimensions for a jalview window
504 * - empty string is desktop, all other windows have unique prefix
505 * @return null or last known dimensions scaled to current geometry (if last
506 * window geom was known)
508 Rectangle getLastKnownDimensions(String windowName)
510 // TODO: lock aspect ratio for scaling desktop Bug #0058199
511 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
512 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
513 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
514 String width = jalview.bin.Cache.getProperty(windowName
516 String height = jalview.bin.Cache.getProperty(windowName
518 if ((x != null) && (y != null) && (width != null) && (height != null))
520 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
521 .parseInt(width), ih = Integer.parseInt(height);
522 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
524 // attempt #1 - try to cope with change in screen geometry - this
525 // version doesn't preserve original jv aspect ratio.
526 // take ratio of current screen size vs original screen size.
527 double sw = ((1f * screenSize.width) / (1f * Integer
528 .parseInt(jalview.bin.Cache
529 .getProperty("SCREENGEOMETRY_WIDTH"))));
530 double sh = ((1f * screenSize.height) / (1f * Integer
531 .parseInt(jalview.bin.Cache
532 .getProperty("SCREENGEOMETRY_HEIGHT"))));
533 // rescale the bounds depending upon the current screen geometry.
534 ix = (int) (ix * sw);
535 iw = (int) (iw * sw);
536 iy = (int) (iy * sh);
537 ih = (int) (ih * sh);
538 while (ix >= screenSize.width)
540 jalview.bin.Cache.log
541 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
542 ix -= screenSize.width;
544 while (iy >= screenSize.height)
546 jalview.bin.Cache.log
547 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
548 iy -= screenSize.height;
550 jalview.bin.Cache.log.debug("Got last known dimensions for "
551 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
554 // return dimensions for new instance
555 return new Rectangle(ix, iy, iw, ih);
560 private void doVamsasClientCheck()
562 if (jalview.bin.Cache.vamsasJarsPresent())
564 setupVamsasDisconnectedGui();
565 VamsasMenu.setVisible(true);
566 final Desktop us = this;
567 VamsasMenu.addMenuListener(new MenuListener()
569 // this listener remembers when the menu was first selected, and
570 // doesn't rebuild the session list until it has been cleared and
572 boolean refresh = true;
574 public void menuCanceled(MenuEvent e)
579 public void menuDeselected(MenuEvent e)
584 public void menuSelected(MenuEvent e)
588 us.buildVamsasStMenu();
593 vamsasStart.setVisible(true);
597 void showPasteMenu(int x, int y)
599 JPopupMenu popup = new JPopupMenu();
600 JMenuItem item = new JMenuItem(
601 MessageManager.getString("label.paste_new_window"));
602 item.addActionListener(new ActionListener()
604 public void actionPerformed(ActionEvent evt)
611 popup.show(this, x, y);
618 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
619 Transferable contents = c.getContents(this);
621 if (contents != null)
623 String file = (String) contents
624 .getTransferData(DataFlavor.stringFlavor);
626 String format = new IdentifyFile().Identify(file,
627 FormatAdapter.PASTE);
629 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
632 } catch (Exception ex)
635 .println("Unable to paste alignment from system clipboard:\n"
641 * Adds and opens the given frame to the desktop
652 public static synchronized void addInternalFrame(
653 final JInternalFrame frame, String title, int w, int h)
655 addInternalFrame(frame, title, true, w, h, true);
659 * Add an internal frame to the Jalview desktop
666 * When true, display frame immediately, otherwise, caller must call
667 * setVisible themselves.
673 public static synchronized void addInternalFrame(
674 final JInternalFrame frame, String title, boolean makeVisible,
677 addInternalFrame(frame, title, makeVisible, w, h, true);
681 * Add an internal frame to the Jalview desktop and make it visible
694 public static synchronized void addInternalFrame(
695 final JInternalFrame frame, String title, int w, int h,
698 addInternalFrame(frame, title, true, w, h, resizable);
702 * Add an internal frame to the Jalview desktop
709 * When true, display frame immediately, otherwise, caller must call
710 * setVisible themselves.
718 public static synchronized void addInternalFrame(
719 final JInternalFrame frame, String title, boolean makeVisible,
720 int w, int h, boolean resizable)
723 // TODO: allow callers to determine X and Y position of frame (eg. via
725 // TODO: consider fixing method to update entries in the window submenu with
726 // the current window title
728 frame.setTitle(title);
729 if (frame.getWidth() < 1 || frame.getHeight() < 1)
733 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
734 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
735 // IF JALVIEW IS RUNNING HEADLESS
736 // ///////////////////////////////////////////////
738 || (System.getProperty("java.awt.headless") != null && System
739 .getProperty("java.awt.headless").equals("true")))
746 frame.setVisible(makeVisible);
747 frame.setClosable(true);
748 frame.setResizable(resizable);
749 frame.setMaximizable(resizable);
750 frame.setIconifiable(resizable);
751 frame.setFrameIcon(null);
753 if (frame.getX() < 1 && frame.getY() < 1)
755 frame.setLocation(xOffset * openFrameCount, yOffset
756 * ((openFrameCount - 1) % 10) + yOffset);
759 final JMenuItem menuItem = new JMenuItem(title);
760 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
762 public void internalFrameActivated(
763 javax.swing.event.InternalFrameEvent evt)
765 JInternalFrame itf = desktop.getSelectedFrame();
773 public void internalFrameClosed(
774 javax.swing.event.InternalFrameEvent evt)
776 PaintRefresher.RemoveComponent(frame);
778 windowMenu.remove(menuItem);
779 JInternalFrame itf = desktop.getSelectedFrame();
788 menuItem.addActionListener(new ActionListener()
790 public void actionPerformed(ActionEvent e)
794 frame.setSelected(true);
795 frame.setIcon(false);
796 } catch (java.beans.PropertyVetoException ex)
802 menuItem.addMouseListener(new MouseListener()
806 public void mouseReleased(MouseEvent e)
811 public void mousePressed(MouseEvent e)
816 public void mouseExited(MouseEvent e)
820 frame.setSelected(false);
821 } catch (PropertyVetoException e1)
827 public void mouseEntered(MouseEvent e)
831 frame.setSelected(true);
832 } catch (PropertyVetoException e1)
838 public void mouseClicked(MouseEvent e)
844 windowMenu.add(menuItem);
850 frame.setSelected(true);
851 frame.requestFocus();
852 } catch (java.beans.PropertyVetoException ve)
854 } catch (java.lang.ClassCastException cex)
857 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
862 public void lostOwnership(Clipboard clipboard, Transferable contents)
866 Desktop.jalviewClipboard = null;
869 internalCopy = false;
872 public void dragEnter(DropTargetDragEvent evt)
876 public void dragExit(DropTargetEvent evt)
880 public void dragOver(DropTargetDragEvent evt)
884 public void dropActionChanged(DropTargetDragEvent evt)
894 public void drop(DropTargetDropEvent evt)
896 boolean success = true;
897 Transferable t = evt.getTransferable();
898 java.util.List files = null;
899 java.util.List protocols = null;
903 DataFlavor uriListFlavor = new DataFlavor(
904 "text/uri-list;class=java.lang.String");
905 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
907 // Works on Windows and MacOSX
908 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
909 files = (java.util.List) t
910 .getTransferData(DataFlavor.javaFileListFlavor);
912 else if (t.isDataFlavorSupported(uriListFlavor))
914 // This is used by Unix drag system
915 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
916 String data = (String) t.getTransferData(uriListFlavor);
917 files = new java.util.ArrayList(1);
918 protocols = new java.util.ArrayList(1);
919 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
920 data, "\r\n"); st.hasMoreTokens();)
922 String s = st.nextToken();
923 if (s.startsWith("#"))
925 // the line is a comment (as per the RFC 2483)
928 java.net.URI uri = new java.net.URI(s);
929 if (uri.getScheme().toLowerCase().startsWith("http"))
931 protocols.add(FormatAdapter.URL);
932 files.add(uri.toString());
936 // otherwise preserve old behaviour: catch all for file objects
937 java.io.File file = new java.io.File(uri);
938 protocols.add(FormatAdapter.FILE);
939 files.add(file.toString());
943 } catch (Exception e)
952 for (int i = 0; i < files.size(); i++)
954 String file = files.get(i).toString();
955 String protocol = (protocols == null) ? FormatAdapter.FILE
956 : (String) protocols.get(i);
957 String format = null;
959 if (file.endsWith(".jar"))
966 format = new IdentifyFile().Identify(file, protocol);
969 new FileLoader().LoadFile(file, protocol, format);
972 } catch (Exception ex)
977 evt.dropComplete(success); // need this to ensure input focus is properly
978 // transfered to any new windows created
987 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
989 JalviewFileChooser chooser = new JalviewFileChooser(
990 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
991 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
992 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
993 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
995 chooser.setFileView(new JalviewFileView());
996 chooser.setDialogTitle(MessageManager
997 .getString("label.open_local_file"));
998 chooser.setToolTipText(MessageManager.getString("action.open"));
1000 int value = chooser.showOpenDialog(this);
1002 if (value == JalviewFileChooser.APPROVE_OPTION)
1004 String choice = chooser.getSelectedFile().getPath();
1005 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1006 .getSelectedFile().getParent());
1008 String format = null;
1009 if (chooser.getSelectedFormat() != null
1010 && chooser.getSelectedFormat().equals("Jalview"))
1016 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1019 if (viewport != null)
1021 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1026 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1037 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1039 // This construct allows us to have a wider textfield
1041 JLabel label = new JLabel(
1042 MessageManager.getString("label.input_file_url"));
1043 final JComboBox history = new JComboBox();
1045 JPanel panel = new JPanel(new GridLayout(2, 1));
1048 history.setPreferredSize(new Dimension(400, 20));
1049 history.setEditable(true);
1050 history.addItem("http://www.");
1052 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1056 if (historyItems != null)
1058 st = new StringTokenizer(historyItems, "\t");
1060 while (st.hasMoreTokens())
1062 history.addItem(st.nextElement());
1066 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1067 MessageManager.getString("label.input_alignment_from_url"),
1068 JOptionPane.OK_CANCEL_OPTION);
1070 if (reply != JOptionPane.OK_OPTION)
1075 String url = history.getSelectedItem().toString();
1077 if (url.toLowerCase().endsWith(".jar"))
1079 if (viewport != null)
1081 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1086 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1091 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1093 if (format.equals("URL NOT FOUND"))
1095 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1096 MessageManager.formatMessage("label.couldnt_locate",
1098 { url }), MessageManager
1099 .getString("label.url_not_found"),
1100 JOptionPane.WARNING_MESSAGE);
1105 if (viewport != null)
1107 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1111 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1122 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1124 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1125 cap.setForInput(viewport);
1126 Desktop.addInternalFrame(cap,
1127 MessageManager.getString("label.cut_paste_alignmen_file"),
1136 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1138 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1139 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1141 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1142 getBounds().y, getWidth(), getHeight()));
1144 if (jconsole != null)
1146 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1147 jconsole.stopConsole();
1151 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1154 if (dialogExecutor != null)
1156 dialogExecutor.shutdownNow();
1162 private void storeLastKnownDimensions(String string, Rectangle jc)
1164 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1165 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1166 + " height:" + jc.height);
1168 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1169 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1170 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1171 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1180 public void aboutMenuItem_actionPerformed(ActionEvent e)
1182 // StringBuffer message = getAboutMessage(false);
1183 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1185 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1186 new Thread(new Runnable()
1190 new SplashScreen(true);
1195 public StringBuffer getAboutMessage(boolean shortv)
1197 StringBuffer message = new StringBuffer();
1198 message.append("<html>");
1201 message.append("<h1><strong>Version: "
1202 + jalview.bin.Cache.getProperty("VERSION") + "</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: "
1248 .getDefault("AUTHORFNAMES",
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(
1486 "label.saving_jalview_project", new Object[]
1487 { choice.getName() }), choice.hashCode());
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(me, MessageManager.formatMessage(
1505 "label.error_whilst_saving_current_state_to",
1507 { choice.getName() }), MessageManager
1508 .getString("label.couldnt_save_project"),
1509 JOptionPane.WARNING_MESSAGE);
1511 setProgressBar(null, choice.hashCode());
1518 * Request any open, linked Chimera sessions to save their state.
1520 * @param jalviewProjectFilename
1521 * the filename of the Jalview project; Chimera session files should
1522 * be given distinct, but obviously related, names.
1524 public void saveChimeraSessions(String jalviewProjectFilename)
1527 for (JInternalFrame frame : getAllFrames())
1529 if (frame instanceof ChimeraViewFrame)
1532 * Construct a filename for the Chimera session by append _chimera<n>.py
1533 * to the Jalview project file name.
1535 String chimeraPath = jalviewProjectFilename + "_chimera_" + i
1537 ((ChimeraViewFrame) frame).saveSession(chimeraPath);
1543 private void setProjectFile(File choice)
1545 this.projectFile = choice;
1548 public File getProjectFile()
1550 return this.projectFile;
1559 public void loadState_actionPerformed(ActionEvent e)
1561 JalviewFileChooser chooser = new JalviewFileChooser(
1562 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1563 { "jvp", "jar" }, new String[]
1564 { "Jalview Project", "Jalview Project (old)" },
1566 chooser.setFileView(new JalviewFileView());
1567 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1569 int value = chooser.showOpenDialog(this);
1571 if (value == JalviewFileChooser.APPROVE_OPTION)
1573 final File selectedFile = chooser.getSelectedFile();
1574 setProjectFile(selectedFile);
1575 final String choice = selectedFile.getAbsolutePath();
1576 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1577 selectedFile.getParent());
1578 new Thread(new Runnable()
1582 setProgressBar(MessageManager.formatMessage(
1583 "label.loading_jalview_project", new Object[]
1584 { choice }), choice.hashCode());
1587 new Jalview2XML().loadJalviewAlign(choice);
1588 } catch (OutOfMemoryError oom)
1590 new OOMWarning("Whilst loading project from " + choice, oom);
1591 } catch (Exception ex)
1593 Cache.log.error("Problems whilst loading project from "
1595 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1597 "label.error_whilst_loading_project_from",
1599 { choice }), MessageManager
1600 .getString("label.couldnt_load_project"),
1601 JOptionPane.WARNING_MESSAGE);
1603 setProgressBar(null, choice.hashCode());
1609 public void inputSequence_actionPerformed(ActionEvent e)
1611 new SequenceFetcher(this);
1614 JPanel progressPanel;
1616 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1618 public void startLoading(final String fileName)
1620 if (fileLoadingCount == 0)
1622 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1623 "label.loading_file", new Object[]
1629 private JPanel addProgressPanel(String string)
1631 if (progressPanel == null)
1633 progressPanel = new JPanel(new GridLayout(1, 1));
1634 totalProgressCount = 0;
1635 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1637 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1638 JProgressBar progressBar = new JProgressBar();
1639 progressBar.setIndeterminate(true);
1641 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1643 thisprogress.add(progressBar, BorderLayout.CENTER);
1644 progressPanel.add(thisprogress);
1645 ((GridLayout) progressPanel.getLayout())
1646 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1647 ++totalProgressCount;
1648 instance.validate();
1649 return thisprogress;
1652 int totalProgressCount = 0;
1654 private void removeProgressPanel(JPanel progbar)
1656 if (progressPanel != null)
1658 synchronized (progressPanel)
1660 progressPanel.remove(progbar);
1661 GridLayout gl = (GridLayout) progressPanel.getLayout();
1662 gl.setRows(gl.getRows() - 1);
1663 if (--totalProgressCount < 1)
1665 this.getContentPane().remove(progressPanel);
1666 progressPanel = null;
1673 public void stopLoading()
1676 if (fileLoadingCount < 1)
1678 while (fileLoadingPanels.size() > 0)
1680 removeProgressPanel(fileLoadingPanels.remove(0));
1682 fileLoadingPanels.clear();
1683 fileLoadingCount = 0;
1688 public static int getViewCount(String alignmentId)
1690 AlignmentViewport[] aps = getViewports(alignmentId);
1691 return (aps == null) ? 0 : aps.length;
1696 * @param alignmentId
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.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
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 (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1757 if (afr.alignPanels != null)
1759 for (AlignmentPanel ap : afr.alignPanels)
1761 if (sequenceSetId.equals(ap.av.getSequenceSetId()))
1769 viewp.add(afr.getViewport());
1773 if (viewp.size() > 0)
1775 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1782 * Explode the views in the given frame into separate AlignFrame
1786 public void explodeViews(AlignFrame af)
1788 int size = af.alignPanels.size();
1794 for (int i = 0; i < size; i++)
1796 AlignmentPanel ap = af.alignPanels.get(i);
1797 AlignFrame newaf = new AlignFrame(ap);
1798 if (ap.av.explodedPosition != null
1799 && !ap.av.explodedPosition.equals(af.getBounds()))
1801 newaf.setBounds(ap.av.explodedPosition);
1804 ap.av.gatherViewsHere = false;
1806 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1807 AlignFrame.DEFAULT_HEIGHT);
1810 af.alignPanels.clear();
1811 af.closeMenuItem_actionPerformed(true);
1816 * Gather expanded views (separate AlignFrame's) with the same sequence set
1817 * identifier back in to this frame as additional views, and close the
1818 * expanded views. Note the expanded frames may themselves have multiple
1819 * views. We take the lot.
1823 public void gatherViews(AlignFrame source)
1825 source.viewport.gatherViewsHere = true;
1826 source.viewport.explodedPosition = source.getBounds();
1827 JInternalFrame[] frames = desktop.getAllFrames();
1828 String viewId = source.viewport.getSequenceSetId();
1830 for (int t = 0; t < frames.length; t++)
1832 if (frames[t] instanceof AlignFrame && frames[t] != source)
1834 AlignFrame af = (AlignFrame) frames[t];
1835 boolean gatherThis = false;
1836 for (int a = 0; a < af.alignPanels.size(); a++)
1838 AlignmentPanel ap = af.alignPanels.get(a);
1839 if (viewId.equals(ap.av.getSequenceSetId()))
1842 ap.av.gatherViewsHere = false;
1843 ap.av.explodedPosition = af.getBounds();
1844 source.addAlignmentPanel(ap, false);
1850 af.alignPanels.clear();
1851 af.closeMenuItem_actionPerformed(true);
1858 jalview.gui.VamsasApplication v_client = null;
1860 public void vamsasImport_actionPerformed(ActionEvent e)
1862 if (v_client == null)
1864 // Load and try to start a session.
1865 JalviewFileChooser chooser = new JalviewFileChooser(
1866 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1868 chooser.setFileView(new JalviewFileView());
1869 chooser.setDialogTitle(MessageManager
1870 .getString("label.open_saved_vamsas_session"));
1871 chooser.setToolTipText(MessageManager
1872 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1874 int value = chooser.showOpenDialog(this);
1876 if (value == JalviewFileChooser.APPROVE_OPTION)
1878 String fle = chooser.getSelectedFile().toString();
1879 if (!vamsasImport(chooser.getSelectedFile()))
1882 .showInternalMessageDialog(
1884 MessageManager.formatMessage(
1885 "label.couldnt_import_as_vamsas_session",
1889 .getString("label.vamsas_document_import_failed"),
1890 JOptionPane.ERROR_MESSAGE);
1896 jalview.bin.Cache.log
1897 .error("Implementation error - load session from a running session is not supported.");
1902 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1905 * @return true if import was a success and a session was started.
1907 public boolean vamsasImport(URL url)
1909 // TODO: create progress bar
1910 if (v_client != null)
1913 jalview.bin.Cache.log
1914 .error("Implementation error - load session from a running session is not supported.");
1920 // copy the URL content to a temporary local file
1921 // TODO: be a bit cleverer here with nio (?!)
1922 File file = File.createTempFile("vdocfromurl", ".vdj");
1923 FileOutputStream fos = new FileOutputStream(file);
1924 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1925 byte[] buffer = new byte[2048];
1927 while ((ln = bis.read(buffer)) > -1)
1929 fos.write(buffer, 0, ln);
1933 v_client = new jalview.gui.VamsasApplication(this, file,
1934 url.toExternalForm());
1935 } catch (Exception ex)
1937 jalview.bin.Cache.log.error(
1938 "Failed to create new vamsas session from contents of URL "
1942 setupVamsasConnectedGui();
1943 v_client.initial_update(); // TODO: thread ?
1944 return v_client.inSession();
1948 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1951 * @return true if import was a success and a session was started.
1953 public boolean vamsasImport(File file)
1955 if (v_client != null)
1958 jalview.bin.Cache.log
1959 .error("Implementation error - load session from a running session is not supported.");
1963 setProgressBar(MessageManager.formatMessage(
1964 "status.importing_vamsas_session_from", new Object[]
1965 { file.getName() }), file.hashCode());
1968 v_client = new jalview.gui.VamsasApplication(this, file, null);
1969 } catch (Exception ex)
1971 setProgressBar(MessageManager.formatMessage(
1972 "status.importing_vamsas_session_from", new Object[]
1973 { file.getName() }), file.hashCode());
1974 jalview.bin.Cache.log.error(
1975 "New vamsas session from existing session file failed:", ex);
1978 setupVamsasConnectedGui();
1979 v_client.initial_update(); // TODO: thread ?
1980 setProgressBar(MessageManager.formatMessage(
1981 "status.importing_vamsas_session_from", new Object[]
1982 { file.getName() }), file.hashCode());
1983 return v_client.inSession();
1986 public boolean joinVamsasSession(String mysesid)
1988 if (v_client != null)
1992 .getString("error.try_join_vamsas_session_another"));
1994 if (mysesid == null)
1997 MessageManager.getString("error.invalid_vamsas_session_id"));
1999 v_client = new VamsasApplication(this, mysesid);
2000 setupVamsasConnectedGui();
2001 v_client.initial_update();
2002 return (v_client.inSession());
2005 public void vamsasStart_actionPerformed(ActionEvent e)
2007 if (v_client == null)
2010 // we just start a default session for moment.
2012 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2013 * getProperty("LAST_DIRECTORY"));
2015 * chooser.setFileView(new JalviewFileView());
2016 * chooser.setDialogTitle("Load Vamsas file");
2017 * chooser.setToolTipText("Import");
2019 * int value = chooser.showOpenDialog(this);
2021 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2022 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2024 v_client = new VamsasApplication(this);
2025 setupVamsasConnectedGui();
2026 v_client.initial_update(); // TODO: thread ?
2030 // store current data in session.
2031 v_client.push_update(); // TODO: thread
2035 protected void setupVamsasConnectedGui()
2037 vamsasStart.setText(MessageManager.getString("label.session_update"));
2038 vamsasSave.setVisible(true);
2039 vamsasStop.setVisible(true);
2040 vamsasImport.setVisible(false); // Document import to existing session is
2041 // not possible for vamsas-client-1.0.
2044 protected void setupVamsasDisconnectedGui()
2046 vamsasSave.setVisible(false);
2047 vamsasStop.setVisible(false);
2048 vamsasImport.setVisible(true);
2049 vamsasStart.setText(MessageManager
2050 .getString("label.new_vamsas_session"));
2053 public void vamsasStop_actionPerformed(ActionEvent e)
2055 if (v_client != null)
2057 v_client.end_session();
2059 setupVamsasDisconnectedGui();
2063 protected void buildVamsasStMenu()
2065 if (v_client == null)
2067 String[] sess = null;
2070 sess = VamsasApplication.getSessionList();
2071 } catch (Exception e)
2073 jalview.bin.Cache.log.warn(
2074 "Problem getting current sessions list.", e);
2079 jalview.bin.Cache.log.debug("Got current sessions list: "
2080 + sess.length + " entries.");
2081 VamsasStMenu.removeAll();
2082 for (int i = 0; i < sess.length; i++)
2084 JMenuItem sessit = new JMenuItem();
2085 sessit.setText(sess[i]);
2086 sessit.setToolTipText(MessageManager.formatMessage(
2087 "label.connect_to_session", new Object[]
2089 final Desktop dsktp = this;
2090 final String mysesid = sess[i];
2091 sessit.addActionListener(new ActionListener()
2094 public void actionPerformed(ActionEvent e)
2096 if (dsktp.v_client == null)
2098 Thread rthr = new Thread(new Runnable()
2103 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2104 dsktp.setupVamsasConnectedGui();
2105 dsktp.v_client.initial_update();
2113 VamsasStMenu.add(sessit);
2115 // don't show an empty menu.
2116 VamsasStMenu.setVisible(sess.length > 0);
2121 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2122 VamsasStMenu.removeAll();
2123 VamsasStMenu.setVisible(false);
2128 // Not interested in the content. Just hide ourselves.
2129 VamsasStMenu.setVisible(false);
2133 public void vamsasSave_actionPerformed(ActionEvent e)
2135 if (v_client != null)
2137 JalviewFileChooser chooser = new JalviewFileChooser(
2138 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2139 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2141 { "Vamsas Document" }, "Vamsas Document");
2143 chooser.setFileView(new JalviewFileView());
2144 chooser.setDialogTitle(MessageManager
2145 .getString("label.save_vamsas_document_archive"));
2147 int value = chooser.showSaveDialog(this);
2149 if (value == JalviewFileChooser.APPROVE_OPTION)
2151 java.io.File choice = chooser.getSelectedFile();
2152 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2153 "label.saving_vamsas_doc", new Object[]
2154 { choice.getName() }));
2155 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2156 String warnmsg = null;
2157 String warnttl = null;
2160 v_client.vclient.storeDocument(choice);
2163 warnttl = "Serious Problem saving Vamsas Document";
2164 warnmsg = ex.toString();
2165 jalview.bin.Cache.log.error("Error Whilst saving document to "
2168 } catch (Exception ex)
2170 warnttl = "Problem saving Vamsas Document.";
2171 warnmsg = ex.toString();
2172 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2176 removeProgressPanel(progpanel);
2177 if (warnmsg != null)
2179 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2181 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2187 JPanel vamUpdate = null;
2190 * hide vamsas user gui bits when a vamsas document event is being handled.
2193 * true to hide gui, false to reveal gui
2195 public void setVamsasUpdate(boolean b)
2197 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2198 + (b ? "in progress" : "finished"));
2200 if (vamUpdate != null)
2202 this.removeProgressPanel(vamUpdate);
2206 vamUpdate = this.addProgressPanel(MessageManager
2207 .getString("label.updating_vamsas_session"));
2209 vamsasStart.setVisible(!b);
2210 vamsasStop.setVisible(!b);
2211 vamsasSave.setVisible(!b);
2214 public JInternalFrame[] getAllFrames()
2216 return desktop.getAllFrames();
2220 * Checks the given url to see if it gives a response indicating that the user
2221 * should be informed of a new questionnaire.
2225 public void checkForQuestionnaire(String url)
2227 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2228 // javax.swing.SwingUtilities.invokeLater(jvq);
2229 new Thread(jvq).start();
2233 * Proxy class for JDesktopPane which optionally displays the current memory
2234 * usage and highlights the desktop area with a red bar if free memory runs
2239 public class MyDesktopPane extends JDesktopPane implements Runnable
2242 private static final float ONE_MB = 1048576f;
2244 boolean showMemoryUsage = false;
2248 java.text.NumberFormat df;
2250 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2253 public MyDesktopPane(boolean showMemoryUsage)
2255 showMemoryUsage(showMemoryUsage);
2258 public void showMemoryUsage(boolean showMemoryUsage)
2260 this.showMemoryUsage = showMemoryUsage;
2261 if (showMemoryUsage)
2263 Thread worker = new Thread(this);
2268 public boolean isShowMemoryUsage()
2270 return showMemoryUsage;
2275 df = java.text.NumberFormat.getNumberInstance();
2276 df.setMaximumFractionDigits(2);
2277 runtime = Runtime.getRuntime();
2279 while (showMemoryUsage)
2283 maxMemory = runtime.maxMemory() / ONE_MB;
2284 allocatedMemory = runtime.totalMemory() / ONE_MB;
2285 freeMemory = runtime.freeMemory() / ONE_MB;
2286 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2288 percentUsage = (totalFreeMemory / maxMemory) * 100;
2290 // if (percentUsage < 20)
2292 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2294 // instance.set.setBorder(border1);
2297 // sleep after showing usage
2299 } catch (Exception ex)
2301 ex.printStackTrace();
2306 public void paintComponent(Graphics g)
2308 if (showMemoryUsage && g != null && df != null)
2310 if (percentUsage < 20)
2312 g.setColor(Color.red);
2314 FontMetrics fm = g.getFontMetrics();
2317 g.drawString(MessageManager.formatMessage(
2318 "label.memory_stats",
2320 { df.format(totalFreeMemory), df.format(maxMemory),
2321 df.format(percentUsage) }), 10,
2322 getHeight() - fm.getHeight());
2329 * fixes stacking order after a modal dialog to ensure windows that should be
2330 * on top actually are
2332 public void relayerWindows()
2337 protected JMenuItem groovyShell;
2339 public void doGroovyCheck()
2341 if (jalview.bin.Cache.groovyJarsPresent())
2343 groovyShell = new JMenuItem();
2344 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2345 groovyShell.addActionListener(new ActionListener()
2347 public void actionPerformed(ActionEvent e)
2349 groovyShell_actionPerformed(e);
2352 toolsMenu.add(groovyShell);
2353 groovyShell.setVisible(true);
2358 * Accessor method to quickly get all the AlignmentFrames loaded.
2360 * @return an array of AlignFrame, or null if none found
2362 public static AlignFrame[] getAlignFrames()
2364 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2370 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2372 for (int i = frames.length - 1; i > -1; i--)
2374 if (frames[i] instanceof AlignFrame)
2376 avp.add((AlignFrame) frames[i]);
2378 else if (frames[i] instanceof SplitFrame)
2381 * Also check for a split frame containing an AlignFrame
2383 SplitFrame sf = (SplitFrame) frames[i];
2384 if (sf.getTopFrame() instanceof AlignFrame)
2386 avp.add((AlignFrame) sf.getTopFrame());
2388 if (sf.getBottomFrame() instanceof AlignFrame)
2390 avp.add((AlignFrame) sf.getBottomFrame());
2394 if (avp.size() == 0)
2398 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2403 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2407 public GStructureViewer[] getJmols()
2409 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2415 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2417 for (int i = frames.length - 1; i > -1; i--)
2419 if (frames[i] instanceof AppJmol)
2421 GStructureViewer af = (GStructureViewer) frames[i];
2425 if (avp.size() == 0)
2429 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2434 * Add Groovy Support to Jalview
2436 public void groovyShell_actionPerformed(ActionEvent e)
2438 // use reflection to avoid creating compilation dependency.
2439 if (!jalview.bin.Cache.groovyJarsPresent())
2443 .getString("error.implementation_error_cannot_create_groovyshell"));
2447 Class gcClass = Desktop.class.getClassLoader().loadClass(
2448 "groovy.ui.Console");
2449 Constructor gccons = gcClass.getConstructor(null);
2450 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2452 { String.class, Object.class });
2453 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2454 Object gc = gccons.newInstance(null);
2455 setvar.invoke(gc, new Object[]
2456 { "Jalview", this });
2457 run.invoke(gc, null);
2458 } catch (Exception ex)
2460 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2461 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2463 MessageManager.getString("label.couldnt_create_groovy_shell"),
2464 MessageManager.getString("label.groovy_support_failed"),
2465 JOptionPane.ERROR_MESSAGE);
2470 * Progress bars managed by the IProgressIndicator method.
2472 private Hashtable<Long, JPanel> progressBars;
2474 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2479 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2481 public void setProgressBar(String message, long id)
2483 if (progressBars == null)
2485 progressBars = new Hashtable<Long, JPanel>();
2486 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2489 if (progressBars.get(new Long(id)) != null)
2491 JPanel progressPanel = progressBars.remove(new Long(id));
2492 if (progressBarHandlers.contains(new Long(id)))
2494 progressBarHandlers.remove(new Long(id));
2496 removeProgressPanel(progressPanel);
2500 progressBars.put(new Long(id), addProgressPanel(message));
2507 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2508 * jalview.gui.IProgressIndicatorHandler)
2510 public void registerHandler(final long id,
2511 final IProgressIndicatorHandler handler)
2513 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2517 .getString("error.call_setprogressbar_before_registering_handler"));
2519 progressBarHandlers.put(new Long(id), handler);
2520 final JPanel progressPanel = progressBars.get(new Long(id));
2521 if (handler.canCancel())
2523 JButton cancel = new JButton(
2524 MessageManager.getString("action.cancel"));
2525 final IProgressIndicator us = this;
2526 cancel.addActionListener(new ActionListener()
2529 public void actionPerformed(ActionEvent e)
2531 handler.cancelActivity(id);
2532 us.setProgressBar(MessageManager.formatMessage(
2533 "label.cancelled_params", new Object[]
2534 { ((JLabel) progressPanel.getComponent(0)).getText() }),
2538 progressPanel.add(cancel, BorderLayout.EAST);
2544 * @return true if any progress bars are still active
2547 public boolean operationInProgress()
2549 if (progressBars != null && progressBars.size() > 0)
2557 * This will return the first AlignFrame viewing AlignViewport av. It will
2558 * break if there are more than one AlignFrames viewing a particular av.
2561 * @return alignFrame for av
2563 public static AlignFrame getAlignFrameFor(AlignmentViewport av)
2565 if (desktop != null)
2567 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2568 for (int panel = 0; aps != null && panel < aps.length; panel++)
2570 if (aps[panel] != null && aps[panel].av == av)
2572 return aps[panel].alignFrame;
2579 public VamsasApplication getVamsasApplication()
2586 * flag set if jalview GUI is being operated programmatically
2588 private boolean inBatchMode = false;
2591 * check if jalview GUI is being operated programmatically
2593 * @return inBatchMode
2595 public boolean isInBatchMode()
2601 * set flag if jalview GUI is being operated programmatically
2603 * @param inBatchMode
2605 public void setInBatchMode(boolean inBatchMode)
2607 this.inBatchMode = inBatchMode;
2610 public void startServiceDiscovery()
2612 startServiceDiscovery(false);
2615 public void startServiceDiscovery(boolean blocking)
2617 boolean alive = true;
2618 Thread t0 = null, t1 = null, t2 = null;
2619 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2622 // todo: changesupport handlers need to be transferred
2623 if (discoverer == null)
2625 discoverer = new jalview.ws.jws1.Discoverer();
2626 // register PCS handler for desktop.
2627 discoverer.addPropertyChangeListener(changeSupport);
2629 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2630 // until we phase out completely
2631 (t0 = new Thread(discoverer)).start();
2634 // ENFIN services are EOLed as of Jalview 2.8.1 release
2639 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2641 // EnfinEnvision web service menu entries are rebuild every time the
2642 // menu is shown, so no changeSupport events are needed.
2643 jalview.ws.EnfinEnvision2OneWay.getInstance();
2644 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2647 } catch (Exception e)
2650 .info("Exception when trying to launch Envision2 workflow discovery.",
2652 Cache.log.info(e.getStackTrace());
2656 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2658 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2660 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2662 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2668 // TODO: do rest service discovery
2677 } catch (Exception e)
2680 alive = (t1 != null && t1.isAlive())
2681 || (t2 != null && t2.isAlive())
2682 || (t3 != null && t3.isAlive())
2683 || (t0 != null && t0.isAlive());
2689 * called to check if the service discovery process completed successfully.
2693 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2695 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2697 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2698 .getErrorMessages();
2701 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2703 if (serviceChangedDialog == null)
2705 // only run if we aren't already displaying one of these.
2706 addDialogThread(serviceChangedDialog = new Runnable()
2712 * JalviewDialog jd =new JalviewDialog() {
2714 * @Override protected void cancelPressed() { // TODO
2715 * Auto-generated method stub
2717 * }@Override protected void okPressed() { // TODO
2718 * Auto-generated method stub
2720 * }@Override protected void raiseClosed() { // TODO
2721 * Auto-generated method stub
2723 * } }; jd.initDialogFrame(new
2724 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2725 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2726 * + " or mis-configured HTTP proxy settings.<br/>" +
2727 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2729 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2730 * ), true, true, "Web Service Configuration Problem", 450,
2733 * jd.waitForInput();
2739 "<html><table width=\"450\"><tr><td>"
2741 + "</td></tr></table>"
2742 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2743 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2744 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2745 + " Tools->Preferences dialog box to change them.</p></html>"),
2746 "Web Service Configuration Problem",
2747 JOptionPane.DEFAULT_OPTION,
2748 JOptionPane.ERROR_MESSAGE);
2749 serviceChangedDialog = null;
2758 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2765 private Runnable serviceChangedDialog = null;
2768 * start a thread to open a URL in the configured browser. Pops up a warning
2769 * dialog to the user if there is an exception when calling out to the browser
2774 public static void showUrl(final String url)
2776 showUrl(url, Desktop.instance);
2780 * Like showUrl but allows progress handler to be specified
2784 * (null) or object implementing IProgressIndicator
2786 public static void showUrl(final String url,
2787 final IProgressIndicator progress)
2789 new Thread(new Runnable()
2795 if (progress != null)
2797 progress.setProgressBar(MessageManager.formatMessage(
2798 "status.opening_params", new Object[]
2799 { url }), this.hashCode());
2801 jalview.util.BrowserLauncher.openURL(url);
2802 } catch (Exception ex)
2804 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2806 .getString("label.web_browser_not_found_unix"),
2807 MessageManager.getString("label.web_browser_not_found"),
2808 JOptionPane.WARNING_MESSAGE);
2810 ex.printStackTrace();
2812 if (progress != null)
2814 progress.setProgressBar(null, this.hashCode());
2820 public static WsParamSetManager wsparamManager = null;
2822 public static ParamManager getUserParameterStore()
2824 if (wsparamManager == null)
2826 wsparamManager = new WsParamSetManager();
2828 return wsparamManager;
2832 * static hyperlink handler proxy method for use by Jalview's internal windows
2836 public static void hyperlinkUpdate(HyperlinkEvent e)
2838 if (e.getEventType() == EventType.ACTIVATED)
2843 url = e.getURL().toString();
2844 Desktop.showUrl(url);
2845 } catch (Exception x)
2849 if (Cache.log != null)
2851 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2855 System.err.println("Couldn't handle string " + url
2859 // ignore any exceptions due to dud links.
2866 * single thread that handles display of dialogs to user.
2868 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2871 * flag indicating if dialogExecutor should try to acquire a permit
2873 private volatile boolean dialogPause = true;
2878 private java.util.concurrent.Semaphore block = new Semaphore(0);
2881 * add another dialog thread to the queue
2885 public void addDialogThread(final Runnable prompter)
2887 dialogExecutor.submit(new Runnable()
2896 } catch (InterruptedException x)
2901 if (instance == null)
2907 SwingUtilities.invokeAndWait(prompter);
2908 } catch (Exception q)
2910 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2916 public void startDialogQueue()
2918 // set the flag so we don't pause waiting for another permit and semaphore
2919 // the current task to begin
2920 dialogPause = false;
2925 protected void snapShotWindow_actionPerformed(ActionEvent e)
2929 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2930 "View of Desktop", getWidth(), getHeight(), of = new File(
2931 "Jalview_snapshot" + System.currentTimeMillis()
2932 + ".eps"), "View of desktop");
2935 paintAll(im.getGraphics());
2937 } catch (Exception q)
2939 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
2943 Cache.log.info("Successfully written snapshot to file "
2944 + of.getAbsolutePath());
2948 * Explode the views in the given frame into separate AlignFrame
2952 public void explodeViews(SplitFrame sf)
2954 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
2955 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
2956 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
2958 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
2960 int viewCount = topPanels.size();
2967 * Processing in reverse order works, forwards order leaves the first panels
2968 * not visible. I don't know why!
2970 for (int i = viewCount - 1; i >= 0; i--)
2973 * Make new top and bottom frames. These take over the respective
2974 * AlignmentPanel objects, including their AlignmentViewports, so the
2975 * cdna/protein relationships between the viewports is carried over to the
2978 AlignFrame newTopFrame = new AlignFrame(
2979 (AlignmentPanel) topPanels.get(i));
2980 newTopFrame.setVisible(true);
2981 AlignFrame newBottomFrame = new AlignFrame(
2982 (AlignmentPanel) bottomPanels.get(i));
2983 newBottomFrame.setVisible(true);
2984 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
2986 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
2988 // if (ap.av.explodedPosition != null
2989 // && !ap.av.explodedPosition.equals(af.getBounds()))
2991 // newaf.setBounds(ap.av.explodedPosition);
2994 // ap.av.gatherViewsHere = false;
2998 * Clear references to the panels (now relocated in the new SplitFrames)
2999 * before closing the old SplitFrame.
3002 bottomPanels.clear();
3007 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3008 * back into the given SplitFrame as additional views. Note that the gathered
3009 * frames may themselves have multiple views.
3013 public void gatherViews(SplitFrame source)
3015 // source.viewport.gatherViewsHere = true;
3016 // source.viewport.explodedPosition = source.getBounds();
3017 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3018 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3019 String topViewId = myTopFrame.viewport.getSequenceSetId();
3020 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3022 JInternalFrame[] frames = desktop.getAllFrames();
3023 for (JInternalFrame frame : frames)
3025 if (frame instanceof SplitFrame && frame != source)
3027 SplitFrame sf = (SplitFrame) frame;
3028 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3029 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3030 boolean gatherThis = false;
3031 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3033 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3034 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3035 if (topViewId.equals(topPanel.av.getSequenceSetId())
3036 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3039 topPanel.av.gatherViewsHere = false;
3040 bottomPanel.av.gatherViewsHere = false;
3041 // topPanel.av.explodedPosition = af.getBounds();
3042 myTopFrame.addAlignmentPanel(topPanel, false);
3043 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3049 topFrame.getAlignPanels().clear();
3050 bottomFrame.getAlignPanels().clear();
3057 * The dust settles...give focus to the tab we did this from.
3059 myTopFrame.setDisplayedView(myTopFrame.alignPanel);