2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ 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 java.awt.BorderLayout;
24 import java.awt.Color;
25 import java.awt.Dimension;
26 import java.awt.FontMetrics;
27 import java.awt.Graphics;
28 import java.awt.GridLayout;
29 import java.awt.Point;
30 import java.awt.Rectangle;
31 import java.awt.Toolkit;
32 import java.awt.datatransfer.Clipboard;
33 import java.awt.datatransfer.ClipboardOwner;
34 import java.awt.datatransfer.DataFlavor;
35 import java.awt.datatransfer.Transferable;
36 import java.awt.dnd.DnDConstants;
37 import java.awt.dnd.DropTargetDragEvent;
38 import java.awt.dnd.DropTargetDropEvent;
39 import java.awt.dnd.DropTargetEvent;
40 import java.awt.dnd.DropTargetListener;
41 import java.awt.event.ActionEvent;
42 import java.awt.event.ActionListener;
43 import java.awt.event.FocusEvent;
44 import java.awt.event.FocusListener;
45 import java.awt.event.MouseAdapter;
46 import java.awt.event.MouseEvent;
47 import java.awt.event.MouseListener;
48 import java.awt.event.WindowAdapter;
49 import java.awt.event.WindowEvent;
50 import java.beans.PropertyChangeEvent;
51 import java.beans.PropertyChangeListener;
52 import java.beans.PropertyVetoException;
53 import java.io.BufferedInputStream;
55 import java.io.FileOutputStream;
56 import java.lang.reflect.Constructor;
58 import java.util.ArrayList;
59 import java.util.Hashtable;
60 import java.util.List;
61 import java.util.StringTokenizer;
62 import java.util.Vector;
63 import java.util.concurrent.ExecutorService;
64 import java.util.concurrent.Executors;
65 import java.util.concurrent.Semaphore;
67 import javax.swing.DefaultDesktopManager;
68 import javax.swing.DesktopManager;
69 import javax.swing.JButton;
70 import javax.swing.JComboBox;
71 import javax.swing.JComponent;
72 import javax.swing.JDesktopPane;
73 import javax.swing.JFrame;
74 import javax.swing.JInternalFrame;
75 import javax.swing.JLabel;
76 import javax.swing.JMenuItem;
77 import javax.swing.JOptionPane;
78 import javax.swing.JPanel;
79 import javax.swing.JPopupMenu;
80 import javax.swing.JProgressBar;
81 import javax.swing.SwingUtilities;
82 import javax.swing.event.HyperlinkEvent;
83 import javax.swing.event.HyperlinkEvent.EventType;
84 import javax.swing.event.MenuEvent;
85 import javax.swing.event.MenuListener;
87 import jalview.api.AlignViewportI;
88 import jalview.api.AlignmentViewPanel;
89 import jalview.bin.Cache;
90 import jalview.io.FileLoader;
91 import jalview.io.FormatAdapter;
92 import jalview.io.IdentifyFile;
93 import jalview.io.JalviewFileChooser;
94 import jalview.io.JalviewFileView;
95 import jalview.jbgui.GSplitFrame;
96 import jalview.jbgui.GStructureViewer;
97 import jalview.structure.StructureSelectionManager;
98 import jalview.util.ImageMaker;
99 import jalview.util.MessageManager;
100 import jalview.viewmodel.AlignmentViewport;
101 import jalview.ws.params.ParamManager;
108 * @version $Revision: 1.155 $
110 public class Desktop extends jalview.jbgui.GDesktop implements
111 DropTargetListener, ClipboardOwner, IProgressIndicator,
112 jalview.api.StructureSelectionManagerProvider
115 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
118 * news reader - null if it was never started.
120 private BlogReader jvnews = null;
122 private File projectFile;
126 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
128 public void addJalviewPropertyChangeListener(
129 PropertyChangeListener listener)
131 changeSupport.addJalviewPropertyChangeListener(listener);
135 * @param propertyName
137 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
138 * java.beans.PropertyChangeListener)
140 public void addJalviewPropertyChangeListener(String propertyName,
141 PropertyChangeListener listener)
143 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
147 * @param propertyName
149 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
150 * java.beans.PropertyChangeListener)
152 public void removeJalviewPropertyChangeListener(String propertyName,
153 PropertyChangeListener listener)
155 changeSupport.removeJalviewPropertyChangeListener(propertyName,
159 /** Singleton Desktop instance */
160 public static Desktop instance;
162 public static MyDesktopPane desktop;
164 static int openFrameCount = 0;
166 static final int xOffset = 30;
168 static final int yOffset = 30;
170 private static final int THREE = 3;
172 private static AlignFrame currentAlignFrame;
174 public static jalview.ws.jws1.Discoverer discoverer;
176 public static Object[] jalviewClipboard;
178 public static boolean internalCopy = false;
180 static int fileLoadingCount = 0;
182 class MyDesktopManager implements DesktopManager
185 private DesktopManager delegate;
187 public MyDesktopManager(DesktopManager delegate)
189 this.delegate = delegate;
192 public void activateFrame(JInternalFrame f)
196 delegate.activateFrame(f);
197 } catch (NullPointerException npe)
199 Point p = getMousePosition();
200 instance.showPasteMenu(p.x, p.y);
204 public void beginDraggingFrame(JComponent f)
206 delegate.beginDraggingFrame(f);
209 public void beginResizingFrame(JComponent f, int direction)
211 delegate.beginResizingFrame(f, direction);
214 public void closeFrame(JInternalFrame f)
216 delegate.closeFrame(f);
219 public void deactivateFrame(JInternalFrame f)
221 delegate.deactivateFrame(f);
224 public void deiconifyFrame(JInternalFrame f)
226 delegate.deiconifyFrame(f);
229 public void dragFrame(JComponent f, int newX, int newY)
235 delegate.dragFrame(f, newX, newY);
238 public void endDraggingFrame(JComponent f)
240 delegate.endDraggingFrame(f);
243 public void endResizingFrame(JComponent f)
245 delegate.endResizingFrame(f);
248 public void iconifyFrame(JInternalFrame f)
250 delegate.iconifyFrame(f);
253 public void maximizeFrame(JInternalFrame f)
255 delegate.maximizeFrame(f);
258 public void minimizeFrame(JInternalFrame f)
260 delegate.minimizeFrame(f);
263 public void openFrame(JInternalFrame f)
265 delegate.openFrame(f);
268 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
271 Rectangle b = desktop.getBounds();
276 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
279 public void setBoundsForFrame(JComponent f, int newX, int newY,
280 int newWidth, int newHeight)
282 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
285 // All other methods, simply delegate
290 * Creates a new Desktop object.
295 * A note to implementors. It is ESSENTIAL that any activities that might
296 * block are spawned off as threads rather than waited for during this
300 doVamsasClientCheck();
302 doConfigureStructurePrefs();
303 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
304 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
305 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
307 boolean showjconsole = jalview.bin.Cache.getDefault(
308 "SHOW_JAVA_CONSOLE", false);
309 desktop = new MyDesktopPane(selmemusage);
310 showMemusage.setSelected(selmemusage);
311 desktop.setBackground(Color.white);
312 getContentPane().setLayout(new BorderLayout());
313 // alternate config - have scrollbars - see notes in JAL-153
314 // JScrollPane sp = new JScrollPane();
315 // sp.getViewport().setView(desktop);
316 // getContentPane().add(sp, BorderLayout.CENTER);
317 getContentPane().add(desktop, BorderLayout.CENTER);
318 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
320 // This line prevents Windows Look&Feel resizing all new windows to maximum
321 // if previous window was maximised
322 desktop.setDesktopManager(new MyDesktopManager(
323 new DefaultDesktopManager()));
325 Rectangle dims = getLastKnownDimensions("");
332 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
333 setBounds((screenSize.width - 900) / 2,
334 (screenSize.height - 650) / 2, 900, 650);
336 jconsole = new Console(this, showjconsole);
337 // add essential build information
338 jconsole.setHeader("Jalview Version: "
339 + jalview.bin.Cache.getProperty("VERSION") + "\n"
340 + "Jalview Installation: "
341 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
342 + "\n" + "Build Date: "
343 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
344 + "Java version: " + System.getProperty("java.version") + "\n"
345 + System.getProperty("os.arch") + " "
346 + System.getProperty("os.name") + " "
347 + System.getProperty("os.version"));
349 showConsole(showjconsole);
351 showNews.setVisible(false);
353 this.addWindowListener(new WindowAdapter()
355 public void windowClosing(WindowEvent evt)
362 this.addMouseListener(ma = new MouseAdapter()
364 public void mousePressed(MouseEvent evt)
366 if (SwingUtilities.isRightMouseButton(evt))
368 showPasteMenu(evt.getX(), evt.getY());
372 desktop.addMouseListener(ma);
374 this.addFocusListener(new FocusListener()
378 public void focusLost(FocusEvent e)
380 // TODO Auto-generated method stub
385 public void focusGained(FocusEvent e)
387 Cache.log.debug("Relaying windows after focus gain");
388 // make sure that we sort windows properly after we gain focus
389 instance.relayerWindows();
392 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
393 // Spawn a thread that shows the splashscreen
394 SwingUtilities.invokeLater(new Runnable()
403 // Thread off a new instance of the file chooser - this reduces the time it
404 // takes to open it later on.
405 new Thread(new Runnable()
409 Cache.log.debug("Filechooser init thread started.");
410 JalviewFileChooser chooser = new JalviewFileChooser(
411 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
412 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
413 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
414 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
415 Cache.log.debug("Filechooser init thread finished.");
418 // Add the service change listener
419 changeSupport.addJalviewPropertyChangeListener("services",
420 new PropertyChangeListener()
424 public void propertyChange(PropertyChangeEvent evt)
426 Cache.log.debug("Firing service changed event for "
427 + evt.getNewValue());
428 JalviewServicesChanged(evt);
434 public void doConfigureStructurePrefs()
436 // configure services
437 StructureSelectionManager ssm = StructureSelectionManager
438 .getStructureSelectionManager(this);
439 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
441 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
442 Preferences.ADD_TEMPFACT_ANN, true));
443 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
444 Preferences.STRUCT_FROM_PDB, true));
445 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
446 Preferences.USE_RNAVIEW, true));
450 ssm.setAddTempFacAnnot(false);
451 ssm.setProcessSecondaryStructure(false);
452 ssm.setSecStructServices(false);
456 public void checkForNews()
458 final Desktop me = this;
459 // Thread off the news reader, in case there are connection problems.
460 addDialogThread(new Runnable()
465 Cache.log.debug("Starting news thread.");
467 jvnews = new BlogReader(me);
468 showNews.setVisible(true);
469 Cache.log.debug("Completed news thread.");
474 protected void showNews_actionPerformed(ActionEvent e)
476 showNews(showNews.isSelected());
479 void showNews(boolean visible)
482 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
483 showNews.setSelected(visible);
484 if (visible && !jvnews.isVisible())
486 new Thread(new Runnable()
491 long instance = System.currentTimeMillis();
492 Desktop.instance.setProgressBar(
493 MessageManager.getString("status.refreshing_news"),
495 jvnews.refreshNews();
496 Desktop.instance.setProgressBar(null, instance);
505 * recover the last known dimensions for a jalview window
508 * - empty string is desktop, all other windows have unique prefix
509 * @return null or last known dimensions scaled to current geometry (if last
510 * window geom was known)
512 Rectangle getLastKnownDimensions(String windowName)
514 // TODO: lock aspect ratio for scaling desktop Bug #0058199
515 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
516 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
517 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
518 String width = jalview.bin.Cache.getProperty(windowName
520 String height = jalview.bin.Cache.getProperty(windowName
522 if ((x != null) && (y != null) && (width != null) && (height != null))
524 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
525 .parseInt(width), ih = Integer.parseInt(height);
526 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
528 // attempt #1 - try to cope with change in screen geometry - this
529 // version doesn't preserve original jv aspect ratio.
530 // take ratio of current screen size vs original screen size.
531 double sw = ((1f * screenSize.width) / (1f * Integer
532 .parseInt(jalview.bin.Cache
533 .getProperty("SCREENGEOMETRY_WIDTH"))));
534 double sh = ((1f * screenSize.height) / (1f * Integer
535 .parseInt(jalview.bin.Cache
536 .getProperty("SCREENGEOMETRY_HEIGHT"))));
537 // rescale the bounds depending upon the current screen geometry.
538 ix = (int) (ix * sw);
539 iw = (int) (iw * sw);
540 iy = (int) (iy * sh);
541 ih = (int) (ih * sh);
542 while (ix >= screenSize.width)
544 jalview.bin.Cache.log
545 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
546 ix -= screenSize.width;
548 while (iy >= screenSize.height)
550 jalview.bin.Cache.log
551 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
552 iy -= screenSize.height;
554 jalview.bin.Cache.log.debug("Got last known dimensions for "
555 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
558 // return dimensions for new instance
559 return new Rectangle(ix, iy, iw, ih);
564 private void doVamsasClientCheck()
566 if (jalview.bin.Cache.vamsasJarsPresent())
568 setupVamsasDisconnectedGui();
569 VamsasMenu.setVisible(true);
570 final Desktop us = this;
571 VamsasMenu.addMenuListener(new MenuListener()
573 // this listener remembers when the menu was first selected, and
574 // doesn't rebuild the session list until it has been cleared and
576 boolean refresh = true;
578 public void menuCanceled(MenuEvent e)
583 public void menuDeselected(MenuEvent e)
588 public void menuSelected(MenuEvent e)
592 us.buildVamsasStMenu();
597 vamsasStart.setVisible(true);
601 void showPasteMenu(int x, int y)
603 JPopupMenu popup = new JPopupMenu();
604 JMenuItem item = new JMenuItem(
605 MessageManager.getString("label.paste_new_window"));
606 item.addActionListener(new ActionListener()
608 public void actionPerformed(ActionEvent evt)
615 popup.show(this, x, y);
622 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
623 Transferable contents = c.getContents(this);
625 if (contents != null)
627 String file = (String) contents
628 .getTransferData(DataFlavor.stringFlavor);
630 String format = new IdentifyFile().Identify(file,
631 FormatAdapter.PASTE);
633 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
636 } catch (Exception ex)
639 .println("Unable to paste alignment from system clipboard:\n"
645 * Adds and opens the given frame to the desktop
656 public static synchronized void addInternalFrame(
657 final JInternalFrame frame, String title, int w, int h)
659 addInternalFrame(frame, title, true, w, h, true);
663 * Add an internal frame to the Jalview desktop
670 * When true, display frame immediately, otherwise, caller must call
671 * setVisible themselves.
677 public static synchronized void addInternalFrame(
678 final JInternalFrame frame, String title, boolean makeVisible,
681 addInternalFrame(frame, title, makeVisible, w, h, true);
685 * Add an internal frame to the Jalview desktop and make it visible
698 public static synchronized void addInternalFrame(
699 final JInternalFrame frame, String title, int w, int h,
702 addInternalFrame(frame, title, true, w, h, resizable);
706 * Add an internal frame to the Jalview desktop
713 * When true, display frame immediately, otherwise, caller must call
714 * setVisible themselves.
722 public static synchronized void addInternalFrame(
723 final JInternalFrame frame, String title, boolean makeVisible,
724 int w, int h, boolean resizable)
727 // TODO: allow callers to determine X and Y position of frame (eg. via
729 // TODO: consider fixing method to update entries in the window submenu with
730 // the current window title
732 frame.setTitle(title);
733 if (frame.getWidth() < 1 || frame.getHeight() < 1)
737 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
738 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
739 // IF JALVIEW IS RUNNING HEADLESS
740 // ///////////////////////////////////////////////
742 || (System.getProperty("java.awt.headless") != null && System
743 .getProperty("java.awt.headless").equals("true")))
750 frame.setVisible(makeVisible);
751 frame.setClosable(true);
752 frame.setResizable(resizable);
753 frame.setMaximizable(resizable);
754 frame.setIconifiable(resizable);
755 frame.setFrameIcon(null);
757 if (frame.getX() < 1 && frame.getY() < 1)
759 frame.setLocation(xOffset * openFrameCount, yOffset
760 * ((openFrameCount - 1) % 10) + yOffset);
763 final JMenuItem menuItem = new JMenuItem(title);
764 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
766 public void internalFrameActivated(
767 javax.swing.event.InternalFrameEvent evt)
769 JInternalFrame itf = desktop.getSelectedFrame();
777 public void internalFrameClosed(
778 javax.swing.event.InternalFrameEvent evt)
780 PaintRefresher.RemoveComponent(frame);
782 windowMenu.remove(menuItem);
783 JInternalFrame itf = desktop.getSelectedFrame();
792 menuItem.addActionListener(new ActionListener()
794 public void actionPerformed(ActionEvent e)
798 frame.setSelected(true);
799 frame.setIcon(false);
800 } catch (java.beans.PropertyVetoException ex)
806 menuItem.addMouseListener(new MouseListener()
810 public void mouseReleased(MouseEvent e)
815 public void mousePressed(MouseEvent e)
820 public void mouseExited(MouseEvent e)
824 frame.setSelected(false);
825 } catch (PropertyVetoException e1)
831 public void mouseEntered(MouseEvent e)
835 frame.setSelected(true);
836 } catch (PropertyVetoException e1)
842 public void mouseClicked(MouseEvent e)
848 windowMenu.add(menuItem);
854 frame.setSelected(true);
855 frame.requestFocus();
856 } catch (java.beans.PropertyVetoException ve)
858 } catch (java.lang.ClassCastException cex)
861 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
866 public void lostOwnership(Clipboard clipboard, Transferable contents)
870 Desktop.jalviewClipboard = null;
873 internalCopy = false;
876 public void dragEnter(DropTargetDragEvent evt)
880 public void dragExit(DropTargetEvent evt)
884 public void dragOver(DropTargetDragEvent evt)
888 public void dropActionChanged(DropTargetDragEvent evt)
898 public void drop(DropTargetDropEvent evt)
900 boolean success = true;
901 Transferable t = evt.getTransferable();
902 java.util.List files = null;
903 java.util.List protocols = null;
907 DataFlavor uriListFlavor = new DataFlavor(
908 "text/uri-list;class=java.lang.String");
909 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
911 // Works on Windows and MacOSX
912 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
913 files = (java.util.List) t
914 .getTransferData(DataFlavor.javaFileListFlavor);
916 else if (t.isDataFlavorSupported(uriListFlavor))
918 // This is used by Unix drag system
919 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
920 String data = (String) t.getTransferData(uriListFlavor);
921 files = new java.util.ArrayList(1);
922 protocols = new java.util.ArrayList(1);
923 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
924 data, "\r\n"); st.hasMoreTokens();)
926 String s = st.nextToken();
927 if (s.startsWith("#"))
929 // the line is a comment (as per the RFC 2483)
932 java.net.URI uri = new java.net.URI(s);
933 if (uri.getScheme().toLowerCase().startsWith("http"))
935 protocols.add(FormatAdapter.URL);
936 files.add(uri.toString());
940 // otherwise preserve old behaviour: catch all for file objects
941 java.io.File file = new java.io.File(uri);
942 protocols.add(FormatAdapter.FILE);
943 files.add(file.toString());
947 } catch (Exception e)
956 for (int i = 0; i < files.size(); i++)
958 String file = files.get(i).toString();
959 String protocol = (protocols == null) ? FormatAdapter.FILE
960 : (String) protocols.get(i);
961 String format = null;
963 if (file.endsWith(".jar"))
970 format = new IdentifyFile().Identify(file, protocol);
973 new FileLoader().LoadFile(file, protocol, format);
976 } catch (Exception ex)
981 evt.dropComplete(success); // need this to ensure input focus is properly
982 // transfered to any new windows created
991 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
993 JalviewFileChooser chooser = new JalviewFileChooser(
994 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
995 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
996 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
997 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
999 chooser.setFileView(new JalviewFileView());
1000 chooser.setDialogTitle(MessageManager
1001 .getString("label.open_local_file"));
1002 chooser.setToolTipText(MessageManager.getString("action.open"));
1004 int value = chooser.showOpenDialog(this);
1006 if (value == JalviewFileChooser.APPROVE_OPTION)
1008 String choice = chooser.getSelectedFile().getPath();
1009 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1010 .getSelectedFile().getParent());
1012 String format = null;
1013 if (chooser.getSelectedFormat() != null
1014 && chooser.getSelectedFormat().equals("Jalview"))
1020 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1023 if (viewport != null)
1025 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1027 // viewport.setShowSequenceFeatures(JSONFile.isSeqFeaturesEnabled());
1028 // AlignFrame af = viewport.getAlignPanel().alignFrame;
1031 // af.changeColour(JSONFile.getColourScheme());
1032 // af.setMenusForViewport();
1037 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1048 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1050 // This construct allows us to have a wider textfield
1052 JLabel label = new JLabel(
1053 MessageManager.getString("label.input_file_url"));
1054 final JComboBox history = new JComboBox();
1056 JPanel panel = new JPanel(new GridLayout(2, 1));
1059 history.setPreferredSize(new Dimension(400, 20));
1060 history.setEditable(true);
1061 history.addItem("http://www.");
1063 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1067 if (historyItems != null)
1069 st = new StringTokenizer(historyItems, "\t");
1071 while (st.hasMoreTokens())
1073 history.addItem(st.nextElement());
1077 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1078 MessageManager.getString("label.input_alignment_from_url"),
1079 JOptionPane.OK_CANCEL_OPTION);
1081 if (reply != JOptionPane.OK_OPTION)
1086 String url = history.getSelectedItem().toString();
1088 if (url.toLowerCase().endsWith(".jar"))
1090 if (viewport != null)
1092 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1097 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1102 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1104 if (format.equals("URL NOT FOUND"))
1106 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1107 MessageManager.formatMessage("label.couldnt_locate",
1109 { url }), MessageManager
1110 .getString("label.url_not_found"),
1111 JOptionPane.WARNING_MESSAGE);
1116 if (viewport != null)
1118 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1122 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1133 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1135 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1136 cap.setForInput(viewport);
1137 Desktop.addInternalFrame(cap,
1138 MessageManager.getString("label.cut_paste_alignmen_file"),
1147 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1149 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1150 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1152 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1153 getBounds().y, getWidth(), getHeight()));
1155 if (jconsole != null)
1157 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1158 jconsole.stopConsole();
1162 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1165 if (dialogExecutor != null)
1167 dialogExecutor.shutdownNow();
1169 closeAll_actionPerformed(null);
1173 private void storeLastKnownDimensions(String string, Rectangle jc)
1175 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1176 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1177 + " height:" + jc.height);
1179 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1180 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1181 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1182 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1191 public void aboutMenuItem_actionPerformed(ActionEvent e)
1193 // StringBuffer message = getAboutMessage(false);
1194 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1196 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1197 new Thread(new Runnable()
1201 new SplashScreen(true);
1206 public StringBuffer getAboutMessage(boolean shortv)
1208 StringBuffer message = new StringBuffer();
1209 message.append("<html>");
1212 message.append("<h1><strong>Version: "
1213 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1214 message.append("<strong>Last Updated: <em>"
1215 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1216 + "</em></strong>");
1222 message.append("<strong>Version "
1223 + jalview.bin.Cache.getProperty("VERSION")
1224 + "; last updated: "
1225 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1228 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1231 message.append("<br>...Checking latest version...</br>");
1233 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1234 .equals(jalview.bin.Cache.getProperty("VERSION")))
1236 boolean red = false;
1237 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1238 .indexOf("automated build") == -1)
1241 // Displayed when code version and jnlp version do not match and code
1242 // version is not a development build
1243 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1246 message.append("<br>!! Version "
1247 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1249 + " is available for download from "
1250 + jalview.bin.Cache.getDefault("www.jalview.org",
1251 "http://www.jalview.org") + " !!");
1254 message.append("</div>");
1257 message.append("<br>Authors: "
1259 .getDefault("AUTHORFNAMES",
1260 "The Jalview Authors (See AUTHORS file for current list)")
1261 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1262 + "<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"
1263 + "<br><br>If you use Jalview, please cite:"
1264 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1265 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1266 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1277 public void documentationMenuItem_actionPerformed(ActionEvent e)
1281 Help.showHelpWindow();
1282 } catch (Exception ex)
1287 public void closeAll_actionPerformed(ActionEvent e)
1289 JInternalFrame[] frames = desktop.getAllFrames();
1290 for (int i = 0; i < frames.length; i++)
1294 frames[i].setClosed(true);
1295 } catch (java.beans.PropertyVetoException ex)
1299 System.out.println("ALL CLOSED");
1300 if (v_client != null)
1302 // TODO clear binding to vamsas document objects on close_all
1307 public void raiseRelated_actionPerformed(ActionEvent e)
1309 reorderAssociatedWindows(false, false);
1312 public void minimizeAssociated_actionPerformed(ActionEvent e)
1314 reorderAssociatedWindows(true, false);
1317 void closeAssociatedWindows()
1319 reorderAssociatedWindows(false, true);
1325 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1328 protected void garbageCollect_actionPerformed(ActionEvent e)
1330 // We simply collect the garbage
1331 jalview.bin.Cache.log.debug("Collecting garbage...");
1333 jalview.bin.Cache.log.debug("Finished garbage collection.");
1340 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1343 protected void showMemusage_actionPerformed(ActionEvent e)
1345 desktop.showMemoryUsage(showMemusage.isSelected());
1352 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1355 protected void showConsole_actionPerformed(ActionEvent e)
1357 showConsole(showConsole.isSelected());
1360 Console jconsole = null;
1363 * control whether the java console is visible or not
1367 void showConsole(boolean selected)
1369 showConsole.setSelected(selected);
1370 // TODO: decide if we should update properties file
1371 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1373 jconsole.setVisible(selected);
1376 void reorderAssociatedWindows(boolean minimize, boolean close)
1378 JInternalFrame[] frames = desktop.getAllFrames();
1379 if (frames == null || frames.length < 1)
1384 AlignmentViewport source = null, target = null;
1385 if (frames[0] instanceof AlignFrame)
1387 source = ((AlignFrame) frames[0]).getCurrentView();
1389 else if (frames[0] instanceof TreePanel)
1391 source = ((TreePanel) frames[0]).getViewPort();
1393 else if (frames[0] instanceof PCAPanel)
1395 source = ((PCAPanel) frames[0]).av;
1397 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1399 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1404 for (int i = 0; i < frames.length; i++)
1407 if (frames[i] == null)
1411 if (frames[i] instanceof AlignFrame)
1413 target = ((AlignFrame) frames[i]).getCurrentView();
1415 else if (frames[i] instanceof TreePanel)
1417 target = ((TreePanel) frames[i]).getViewPort();
1419 else if (frames[i] instanceof PCAPanel)
1421 target = ((PCAPanel) frames[i]).av;
1423 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1425 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1428 if (source == target)
1434 frames[i].setClosed(true);
1438 frames[i].setIcon(minimize);
1441 frames[i].toFront();
1445 } catch (java.beans.PropertyVetoException ex)
1459 protected void preferences_actionPerformed(ActionEvent e)
1470 public void saveState_actionPerformed(ActionEvent e)
1472 JalviewFileChooser chooser = new JalviewFileChooser(
1473 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1474 { "jvp" }, new String[]
1475 { "Jalview Project" }, "Jalview Project");
1477 chooser.setFileView(new JalviewFileView());
1478 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1480 int value = chooser.showSaveDialog(this);
1482 if (value == JalviewFileChooser.APPROVE_OPTION)
1484 final Desktop me = this;
1485 final java.io.File choice = chooser.getSelectedFile();
1486 setProjectFile(choice);
1488 new Thread(new Runnable()
1493 setProgressBar(MessageManager.formatMessage(
1494 "label.saving_jalview_project", new Object[]
1495 { choice.getName() }), choice.hashCode());
1496 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1497 choice.getParent());
1498 // TODO catch and handle errors for savestate
1499 // TODO prevent user from messing with the Desktop whilst we're saving
1502 new Jalview2XML().saveState(choice);
1503 } catch (OutOfMemoryError oom)
1505 new OOMWarning("Whilst saving current state to "
1506 + choice.getName(), oom);
1507 } catch (Exception ex)
1510 "Problems whilst trying to save to " + choice.getName(),
1512 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1513 "label.error_whilst_saving_current_state_to",
1515 { choice.getName() }), MessageManager
1516 .getString("label.couldnt_save_project"),
1517 JOptionPane.WARNING_MESSAGE);
1519 setProgressBar(null, choice.hashCode());
1525 private void setProjectFile(File choice)
1527 this.projectFile = choice;
1530 public File getProjectFile()
1532 return this.projectFile;
1541 public void loadState_actionPerformed(ActionEvent e)
1543 JalviewFileChooser chooser = new JalviewFileChooser(
1544 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1545 { "jvp", "jar" }, new String[]
1546 { "Jalview Project", "Jalview Project (old)" },
1548 chooser.setFileView(new JalviewFileView());
1549 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1551 int value = chooser.showOpenDialog(this);
1553 if (value == JalviewFileChooser.APPROVE_OPTION)
1555 final File selectedFile = chooser.getSelectedFile();
1556 setProjectFile(selectedFile);
1557 final String choice = selectedFile.getAbsolutePath();
1558 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1559 selectedFile.getParent());
1560 new Thread(new Runnable()
1564 setProgressBar(MessageManager.formatMessage(
1565 "label.loading_jalview_project", new Object[]
1566 { choice }), choice.hashCode());
1569 new Jalview2XML().loadJalviewAlign(choice);
1570 } catch (OutOfMemoryError oom)
1572 new OOMWarning("Whilst loading project from " + choice, oom);
1573 } catch (Exception ex)
1575 Cache.log.error("Problems whilst loading project from "
1577 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1579 "label.error_whilst_loading_project_from",
1581 { choice }), MessageManager
1582 .getString("label.couldnt_load_project"),
1583 JOptionPane.WARNING_MESSAGE);
1585 setProgressBar(null, choice.hashCode());
1591 public void inputSequence_actionPerformed(ActionEvent e)
1593 new SequenceFetcher(this);
1596 JPanel progressPanel;
1598 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1600 public void startLoading(final String fileName)
1602 if (fileLoadingCount == 0)
1604 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1605 "label.loading_file", new Object[]
1611 private JPanel addProgressPanel(String string)
1613 if (progressPanel == null)
1615 progressPanel = new JPanel(new GridLayout(1, 1));
1616 totalProgressCount = 0;
1617 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1619 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1620 JProgressBar progressBar = new JProgressBar();
1621 progressBar.setIndeterminate(true);
1623 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1625 thisprogress.add(progressBar, BorderLayout.CENTER);
1626 progressPanel.add(thisprogress);
1627 ((GridLayout) progressPanel.getLayout())
1628 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1629 ++totalProgressCount;
1630 instance.validate();
1631 return thisprogress;
1634 int totalProgressCount = 0;
1636 private void removeProgressPanel(JPanel progbar)
1638 if (progressPanel != null)
1640 synchronized (progressPanel)
1642 progressPanel.remove(progbar);
1643 GridLayout gl = (GridLayout) progressPanel.getLayout();
1644 gl.setRows(gl.getRows() - 1);
1645 if (--totalProgressCount < 1)
1647 this.getContentPane().remove(progressPanel);
1648 progressPanel = null;
1655 public void stopLoading()
1658 if (fileLoadingCount < 1)
1660 while (fileLoadingPanels.size() > 0)
1662 removeProgressPanel(fileLoadingPanels.remove(0));
1664 fileLoadingPanels.clear();
1665 fileLoadingCount = 0;
1670 public static int getViewCount(String alignmentId)
1672 AlignmentViewport[] aps = getViewports(alignmentId);
1673 return (aps == null) ? 0 : aps.length;
1678 * @param alignmentId
1679 * - if null, all sets are returned
1680 * @return all AlignmentPanels concerning the alignmentId sequence set
1682 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1684 if (Desktop.desktop == null)
1686 // no frames created and in headless mode
1687 // TODO: verify that frames are recoverable when in headless mode
1690 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1691 AlignFrame[] frames = getAlignFrames();
1696 for (AlignFrame af : frames)
1698 for (AlignmentPanel ap : af.alignPanels)
1700 if (alignmentId==null || alignmentId.equals(ap.av.getSequenceSetId()))
1706 if (aps.size() == 0)
1710 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1715 * get all the viewports on an alignment.
1717 * @param sequenceSetId
1718 * unique alignment id (may be null - all viewports returned in that
1720 * @return all viewports on the alignment bound to sequenceSetId
1722 public static AlignmentViewport[] getViewports(String sequenceSetId)
1724 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1725 if (desktop != null)
1727 AlignFrame[] frames = Desktop.getAlignFrames();
1729 for (AlignFrame afr : frames)
1731 if (sequenceSetId==null || afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1733 if (afr.alignPanels != null)
1735 for (AlignmentPanel ap : afr.alignPanels)
1737 if (sequenceSetId == null
1738 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1746 viewp.add(afr.getViewport());
1750 if (viewp.size() > 0)
1752 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1759 * Explode the views in the given frame into separate AlignFrame
1763 public void explodeViews(AlignFrame af)
1765 int size = af.alignPanels.size();
1771 for (int i = 0; i < size; i++)
1773 AlignmentPanel ap = af.alignPanels.get(i);
1774 AlignFrame newaf = new AlignFrame(ap);
1777 * Restore the view's last exploded frame geometry if known. Multiple
1778 * views from one exploded frame share and restore the same (frame)
1779 * position and size.
1781 Rectangle geometry = ap.av.getExplodedGeometry();
1782 if (geometry != null)
1784 newaf.setBounds(geometry);
1787 ap.av.setGatherViewsHere(false);
1789 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1790 AlignFrame.DEFAULT_HEIGHT);
1793 af.alignPanels.clear();
1794 af.closeMenuItem_actionPerformed(true);
1799 * Gather expanded views (separate AlignFrame's) with the same sequence set
1800 * identifier back in to this frame as additional views, and close the
1801 * expanded views. Note the expanded frames may themselves have multiple
1802 * views. We take the lot.
1806 public void gatherViews(AlignFrame source)
1808 source.viewport.setGatherViewsHere(true);
1809 source.viewport.setExplodedGeometry(source.getBounds());
1810 JInternalFrame[] frames = desktop.getAllFrames();
1811 String viewId = source.viewport.getSequenceSetId();
1813 for (int t = 0; t < frames.length; t++)
1815 if (frames[t] instanceof AlignFrame && frames[t] != source)
1817 AlignFrame af = (AlignFrame) frames[t];
1818 boolean gatherThis = false;
1819 for (int a = 0; a < af.alignPanels.size(); a++)
1821 AlignmentPanel ap = af.alignPanels.get(a);
1822 if (viewId.equals(ap.av.getSequenceSetId()))
1825 ap.av.setGatherViewsHere(false);
1826 ap.av.setExplodedGeometry(af.getBounds());
1827 source.addAlignmentPanel(ap, false);
1833 af.alignPanels.clear();
1834 af.closeMenuItem_actionPerformed(true);
1841 jalview.gui.VamsasApplication v_client = null;
1843 public void vamsasImport_actionPerformed(ActionEvent e)
1845 if (v_client == null)
1847 // Load and try to start a session.
1848 JalviewFileChooser chooser = new JalviewFileChooser(
1849 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1851 chooser.setFileView(new JalviewFileView());
1852 chooser.setDialogTitle(MessageManager
1853 .getString("label.open_saved_vamsas_session"));
1854 chooser.setToolTipText(MessageManager
1855 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1857 int value = chooser.showOpenDialog(this);
1859 if (value == JalviewFileChooser.APPROVE_OPTION)
1861 String fle = chooser.getSelectedFile().toString();
1862 if (!vamsasImport(chooser.getSelectedFile()))
1865 .showInternalMessageDialog(
1867 MessageManager.formatMessage(
1868 "label.couldnt_import_as_vamsas_session",
1872 .getString("label.vamsas_document_import_failed"),
1873 JOptionPane.ERROR_MESSAGE);
1879 jalview.bin.Cache.log
1880 .error("Implementation error - load session from a running session is not supported.");
1885 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1888 * @return true if import was a success and a session was started.
1890 public boolean vamsasImport(URL url)
1892 // TODO: create progress bar
1893 if (v_client != null)
1896 jalview.bin.Cache.log
1897 .error("Implementation error - load session from a running session is not supported.");
1903 // copy the URL content to a temporary local file
1904 // TODO: be a bit cleverer here with nio (?!)
1905 File file = File.createTempFile("vdocfromurl", ".vdj");
1906 FileOutputStream fos = new FileOutputStream(file);
1907 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1908 byte[] buffer = new byte[2048];
1910 while ((ln = bis.read(buffer)) > -1)
1912 fos.write(buffer, 0, ln);
1916 v_client = new jalview.gui.VamsasApplication(this, file,
1917 url.toExternalForm());
1918 } catch (Exception ex)
1920 jalview.bin.Cache.log.error(
1921 "Failed to create new vamsas session from contents of URL "
1925 setupVamsasConnectedGui();
1926 v_client.initial_update(); // TODO: thread ?
1927 return v_client.inSession();
1931 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1934 * @return true if import was a success and a session was started.
1936 public boolean vamsasImport(File file)
1938 if (v_client != null)
1941 jalview.bin.Cache.log
1942 .error("Implementation error - load session from a running session is not supported.");
1946 setProgressBar(MessageManager.formatMessage(
1947 "status.importing_vamsas_session_from", new Object[]
1948 { file.getName() }), file.hashCode());
1951 v_client = new jalview.gui.VamsasApplication(this, file, null);
1952 } catch (Exception ex)
1954 setProgressBar(MessageManager.formatMessage(
1955 "status.importing_vamsas_session_from", new Object[]
1956 { file.getName() }), file.hashCode());
1957 jalview.bin.Cache.log.error(
1958 "New vamsas session from existing session file failed:", ex);
1961 setupVamsasConnectedGui();
1962 v_client.initial_update(); // TODO: thread ?
1963 setProgressBar(MessageManager.formatMessage(
1964 "status.importing_vamsas_session_from", new Object[]
1965 { file.getName() }), file.hashCode());
1966 return v_client.inSession();
1969 public boolean joinVamsasSession(String mysesid)
1971 if (v_client != null)
1975 .getString("error.try_join_vamsas_session_another"));
1977 if (mysesid == null)
1980 MessageManager.getString("error.invalid_vamsas_session_id"));
1982 v_client = new VamsasApplication(this, mysesid);
1983 setupVamsasConnectedGui();
1984 v_client.initial_update();
1985 return (v_client.inSession());
1988 public void vamsasStart_actionPerformed(ActionEvent e)
1990 if (v_client == null)
1993 // we just start a default session for moment.
1995 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1996 * getProperty("LAST_DIRECTORY"));
1998 * chooser.setFileView(new JalviewFileView());
1999 * chooser.setDialogTitle("Load Vamsas file");
2000 * chooser.setToolTipText("Import");
2002 * int value = chooser.showOpenDialog(this);
2004 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2005 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2007 v_client = new VamsasApplication(this);
2008 setupVamsasConnectedGui();
2009 v_client.initial_update(); // TODO: thread ?
2013 // store current data in session.
2014 v_client.push_update(); // TODO: thread
2018 protected void setupVamsasConnectedGui()
2020 vamsasStart.setText(MessageManager.getString("label.session_update"));
2021 vamsasSave.setVisible(true);
2022 vamsasStop.setVisible(true);
2023 vamsasImport.setVisible(false); // Document import to existing session is
2024 // not possible for vamsas-client-1.0.
2027 protected void setupVamsasDisconnectedGui()
2029 vamsasSave.setVisible(false);
2030 vamsasStop.setVisible(false);
2031 vamsasImport.setVisible(true);
2032 vamsasStart.setText(MessageManager
2033 .getString("label.new_vamsas_session"));
2036 public void vamsasStop_actionPerformed(ActionEvent e)
2038 if (v_client != null)
2040 v_client.end_session();
2042 setupVamsasDisconnectedGui();
2046 protected void buildVamsasStMenu()
2048 if (v_client == null)
2050 String[] sess = null;
2053 sess = VamsasApplication.getSessionList();
2054 } catch (Exception e)
2056 jalview.bin.Cache.log.warn(
2057 "Problem getting current sessions list.", e);
2062 jalview.bin.Cache.log.debug("Got current sessions list: "
2063 + sess.length + " entries.");
2064 VamsasStMenu.removeAll();
2065 for (int i = 0; i < sess.length; i++)
2067 JMenuItem sessit = new JMenuItem();
2068 sessit.setText(sess[i]);
2069 sessit.setToolTipText(MessageManager.formatMessage(
2070 "label.connect_to_session", new Object[]
2072 final Desktop dsktp = this;
2073 final String mysesid = sess[i];
2074 sessit.addActionListener(new ActionListener()
2077 public void actionPerformed(ActionEvent e)
2079 if (dsktp.v_client == null)
2081 Thread rthr = new Thread(new Runnable()
2086 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2087 dsktp.setupVamsasConnectedGui();
2088 dsktp.v_client.initial_update();
2096 VamsasStMenu.add(sessit);
2098 // don't show an empty menu.
2099 VamsasStMenu.setVisible(sess.length > 0);
2104 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2105 VamsasStMenu.removeAll();
2106 VamsasStMenu.setVisible(false);
2111 // Not interested in the content. Just hide ourselves.
2112 VamsasStMenu.setVisible(false);
2116 public void vamsasSave_actionPerformed(ActionEvent e)
2118 if (v_client != null)
2120 JalviewFileChooser chooser = new JalviewFileChooser(
2121 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2122 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2124 { "Vamsas Document" }, "Vamsas Document");
2126 chooser.setFileView(new JalviewFileView());
2127 chooser.setDialogTitle(MessageManager
2128 .getString("label.save_vamsas_document_archive"));
2130 int value = chooser.showSaveDialog(this);
2132 if (value == JalviewFileChooser.APPROVE_OPTION)
2134 java.io.File choice = chooser.getSelectedFile();
2135 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2136 "label.saving_vamsas_doc", new Object[]
2137 { choice.getName() }));
2138 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2139 String warnmsg = null;
2140 String warnttl = null;
2143 v_client.vclient.storeDocument(choice);
2146 warnttl = "Serious Problem saving Vamsas Document";
2147 warnmsg = ex.toString();
2148 jalview.bin.Cache.log.error("Error Whilst saving document to "
2151 } catch (Exception ex)
2153 warnttl = "Problem saving Vamsas Document.";
2154 warnmsg = ex.toString();
2155 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2159 removeProgressPanel(progpanel);
2160 if (warnmsg != null)
2162 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2164 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2170 JPanel vamUpdate = null;
2173 * hide vamsas user gui bits when a vamsas document event is being handled.
2176 * true to hide gui, false to reveal gui
2178 public void setVamsasUpdate(boolean b)
2180 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2181 + (b ? "in progress" : "finished"));
2183 if (vamUpdate != null)
2185 this.removeProgressPanel(vamUpdate);
2189 vamUpdate = this.addProgressPanel(MessageManager
2190 .getString("label.updating_vamsas_session"));
2192 vamsasStart.setVisible(!b);
2193 vamsasStop.setVisible(!b);
2194 vamsasSave.setVisible(!b);
2197 public JInternalFrame[] getAllFrames()
2199 return desktop.getAllFrames();
2203 * Checks the given url to see if it gives a response indicating that the user
2204 * should be informed of a new questionnaire.
2208 public void checkForQuestionnaire(String url)
2210 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2211 // javax.swing.SwingUtilities.invokeLater(jvq);
2212 new Thread(jvq).start();
2216 * Proxy class for JDesktopPane which optionally displays the current memory
2217 * usage and highlights the desktop area with a red bar if free memory runs
2222 public class MyDesktopPane extends JDesktopPane implements Runnable
2225 private static final float ONE_MB = 1048576f;
2227 boolean showMemoryUsage = false;
2231 java.text.NumberFormat df;
2233 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2236 public MyDesktopPane(boolean showMemoryUsage)
2238 showMemoryUsage(showMemoryUsage);
2241 public void showMemoryUsage(boolean showMemoryUsage)
2243 this.showMemoryUsage = showMemoryUsage;
2244 if (showMemoryUsage)
2246 Thread worker = new Thread(this);
2251 public boolean isShowMemoryUsage()
2253 return showMemoryUsage;
2258 df = java.text.NumberFormat.getNumberInstance();
2259 df.setMaximumFractionDigits(2);
2260 runtime = Runtime.getRuntime();
2262 while (showMemoryUsage)
2266 maxMemory = runtime.maxMemory() / ONE_MB;
2267 allocatedMemory = runtime.totalMemory() / ONE_MB;
2268 freeMemory = runtime.freeMemory() / ONE_MB;
2269 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2271 percentUsage = (totalFreeMemory / maxMemory) * 100;
2273 // if (percentUsage < 20)
2275 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2277 // instance.set.setBorder(border1);
2280 // sleep after showing usage
2282 } catch (Exception ex)
2284 ex.printStackTrace();
2289 public void paintComponent(Graphics g)
2291 if (showMemoryUsage && g != null && df != null)
2293 if (percentUsage < 20)
2295 g.setColor(Color.red);
2297 FontMetrics fm = g.getFontMetrics();
2300 g.drawString(MessageManager.formatMessage(
2301 "label.memory_stats",
2303 { df.format(totalFreeMemory), df.format(maxMemory),
2304 df.format(percentUsage) }), 10,
2305 getHeight() - fm.getHeight());
2312 * fixes stacking order after a modal dialog to ensure windows that should be
2313 * on top actually are
2315 public void relayerWindows()
2320 protected JMenuItem groovyShell;
2322 public void doGroovyCheck()
2324 if (jalview.bin.Cache.groovyJarsPresent())
2326 groovyShell = new JMenuItem();
2327 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2328 groovyShell.addActionListener(new ActionListener()
2330 public void actionPerformed(ActionEvent e)
2332 groovyShell_actionPerformed(e);
2335 toolsMenu.add(groovyShell);
2336 groovyShell.setVisible(true);
2341 * Accessor method to quickly get all the AlignmentFrames loaded.
2343 * @return an array of AlignFrame, or null if none found
2345 public static AlignFrame[] getAlignFrames()
2347 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2353 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2355 for (int i = frames.length - 1; i > -1; i--)
2357 if (frames[i] instanceof AlignFrame)
2359 avp.add((AlignFrame) frames[i]);
2361 else if (frames[i] instanceof SplitFrame)
2364 * Also check for a split frame containing an AlignFrame
2366 GSplitFrame sf = (GSplitFrame) frames[i];
2367 if (sf.getTopFrame() instanceof AlignFrame)
2369 avp.add((AlignFrame) sf.getTopFrame());
2371 if (sf.getBottomFrame() instanceof AlignFrame)
2373 avp.add((AlignFrame) sf.getBottomFrame());
2377 if (avp.size() == 0)
2381 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2386 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2390 public GStructureViewer[] getJmols()
2392 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2398 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2400 for (int i = frames.length - 1; i > -1; i--)
2402 if (frames[i] instanceof AppJmol)
2404 GStructureViewer af = (GStructureViewer) frames[i];
2408 if (avp.size() == 0)
2412 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2417 * Add Groovy Support to Jalview
2419 public void groovyShell_actionPerformed(ActionEvent e)
2421 // use reflection to avoid creating compilation dependency.
2422 if (!jalview.bin.Cache.groovyJarsPresent())
2426 .getString("error.implementation_error_cannot_create_groovyshell"));
2430 Class<?> gcClass = Desktop.class.getClassLoader().loadClass(
2431 "groovy.ui.Console");
2432 Constructor<?> gccons = gcClass.getConstructor();
2433 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2435 { String.class, Object.class });
2436 java.lang.reflect.Method run = gcClass.getMethod("run");
2437 Object gc = gccons.newInstance();
2438 setvar.invoke(gc, new Object[]
2439 { "Jalview", this });
2441 } catch (Exception ex)
2443 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2444 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2446 MessageManager.getString("label.couldnt_create_groovy_shell"),
2447 MessageManager.getString("label.groovy_support_failed"),
2448 JOptionPane.ERROR_MESSAGE);
2453 * Progress bars managed by the IProgressIndicator method.
2455 private Hashtable<Long, JPanel> progressBars;
2457 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2462 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2464 public void setProgressBar(String message, long id)
2466 if (progressBars == null)
2468 progressBars = new Hashtable<Long, JPanel>();
2469 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2472 if (progressBars.get(new Long(id)) != null)
2474 JPanel progressPanel = progressBars.remove(new Long(id));
2475 if (progressBarHandlers.contains(new Long(id)))
2477 progressBarHandlers.remove(new Long(id));
2479 removeProgressPanel(progressPanel);
2483 progressBars.put(new Long(id), addProgressPanel(message));
2490 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2491 * jalview.gui.IProgressIndicatorHandler)
2493 public void registerHandler(final long id,
2494 final IProgressIndicatorHandler handler)
2496 if (progressBarHandlers == null
2497 || !progressBars.containsKey(new Long(id)))
2501 .getString("error.call_setprogressbar_before_registering_handler"));
2503 progressBarHandlers.put(new Long(id), handler);
2504 final JPanel progressPanel = progressBars.get(new Long(id));
2505 if (handler.canCancel())
2507 JButton cancel = new JButton(
2508 MessageManager.getString("action.cancel"));
2509 final IProgressIndicator us = this;
2510 cancel.addActionListener(new ActionListener()
2513 public void actionPerformed(ActionEvent e)
2515 handler.cancelActivity(id);
2516 us.setProgressBar(MessageManager.formatMessage(
2517 "label.cancelled_params", new Object[]
2518 { ((JLabel) progressPanel.getComponent(0)).getText() }),
2522 progressPanel.add(cancel, BorderLayout.EAST);
2528 * @return true if any progress bars are still active
2531 public boolean operationInProgress()
2533 if (progressBars != null && progressBars.size() > 0)
2541 * This will return the first AlignFrame holding the given viewport instance. It
2542 * will break if there are more than one AlignFrames viewing a particular av.
2545 * @return alignFrame for viewport
2547 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2549 if (desktop != null)
2551 AlignmentPanel[] aps = getAlignmentPanels(viewport
2552 .getSequenceSetId());
2553 for (int panel = 0; aps != null && panel < aps.length; panel++)
2555 if (aps[panel] != null && aps[panel].av == viewport)
2557 return aps[panel].alignFrame;
2564 public VamsasApplication getVamsasApplication()
2571 * flag set if jalview GUI is being operated programmatically
2573 private boolean inBatchMode = false;
2576 * check if jalview GUI is being operated programmatically
2578 * @return inBatchMode
2580 public boolean isInBatchMode()
2586 * set flag if jalview GUI is being operated programmatically
2588 * @param inBatchMode
2590 public void setInBatchMode(boolean inBatchMode)
2592 this.inBatchMode = inBatchMode;
2595 public void startServiceDiscovery()
2597 startServiceDiscovery(false);
2600 public void startServiceDiscovery(boolean blocking)
2602 boolean alive = true;
2603 Thread t0 = null, t1 = null, t2 = null;
2604 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2607 // todo: changesupport handlers need to be transferred
2608 if (discoverer == null)
2610 discoverer = new jalview.ws.jws1.Discoverer();
2611 // register PCS handler for desktop.
2612 discoverer.addPropertyChangeListener(changeSupport);
2614 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2615 // until we phase out completely
2616 (t0 = new Thread(discoverer)).start();
2619 // ENFIN services are EOLed as of Jalview 2.8.1 release
2624 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2626 // EnfinEnvision web service menu entries are rebuild every time the
2627 // menu is shown, so no changeSupport events are needed.
2628 jalview.ws.EnfinEnvision2OneWay.getInstance();
2629 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2632 } catch (Exception e)
2635 .info("Exception when trying to launch Envision2 workflow discovery.",
2637 Cache.log.info(e.getStackTrace());
2641 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2643 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2645 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2647 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2653 // TODO: do rest service discovery
2662 } catch (Exception e)
2665 alive = (t1 != null && t1.isAlive())
2666 || (t2 != null && t2.isAlive())
2667 || (t3 != null && t3.isAlive())
2668 || (t0 != null && t0.isAlive());
2674 * called to check if the service discovery process completed successfully.
2678 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2680 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2682 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2683 .getErrorMessages();
2686 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2688 if (serviceChangedDialog == null)
2690 // only run if we aren't already displaying one of these.
2691 addDialogThread(serviceChangedDialog = new Runnable()
2697 * JalviewDialog jd =new JalviewDialog() {
2699 * @Override protected void cancelPressed() { // TODO
2700 * Auto-generated method stub
2702 * }@Override protected void okPressed() { // TODO
2703 * Auto-generated method stub
2705 * }@Override protected void raiseClosed() { // TODO
2706 * Auto-generated method stub
2708 * } }; jd.initDialogFrame(new
2709 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2710 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2711 * + " or mis-configured HTTP proxy settings.<br/>" +
2712 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2714 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2715 * ), true, true, "Web Service Configuration Problem", 450,
2718 * jd.waitForInput();
2724 "<html><table width=\"450\"><tr><td>"
2726 + "</td></tr></table>"
2727 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2728 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2729 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2730 + " Tools->Preferences dialog box to change them.</p></html>"),
2731 "Web Service Configuration Problem",
2732 JOptionPane.DEFAULT_OPTION,
2733 JOptionPane.ERROR_MESSAGE);
2734 serviceChangedDialog = null;
2743 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2750 private Runnable serviceChangedDialog = null;
2753 * start a thread to open a URL in the configured browser. Pops up a warning
2754 * dialog to the user if there is an exception when calling out to the browser
2759 public static void showUrl(final String url)
2761 showUrl(url, Desktop.instance);
2765 * Like showUrl but allows progress handler to be specified
2769 * (null) or object implementing IProgressIndicator
2771 public static void showUrl(final String url,
2772 final IProgressIndicator progress)
2774 new Thread(new Runnable()
2780 if (progress != null)
2782 progress.setProgressBar(MessageManager.formatMessage(
2783 "status.opening_params", new Object[]
2784 { url }), this.hashCode());
2786 jalview.util.BrowserLauncher.openURL(url);
2787 } catch (Exception ex)
2789 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2791 .getString("label.web_browser_not_found_unix"),
2792 MessageManager.getString("label.web_browser_not_found"),
2793 JOptionPane.WARNING_MESSAGE);
2795 ex.printStackTrace();
2797 if (progress != null)
2799 progress.setProgressBar(null, this.hashCode());
2805 public static WsParamSetManager wsparamManager = null;
2807 public static ParamManager getUserParameterStore()
2809 if (wsparamManager == null)
2811 wsparamManager = new WsParamSetManager();
2813 return wsparamManager;
2817 * static hyperlink handler proxy method for use by Jalview's internal windows
2821 public static void hyperlinkUpdate(HyperlinkEvent e)
2823 if (e.getEventType() == EventType.ACTIVATED)
2828 url = e.getURL().toString();
2829 Desktop.showUrl(url);
2830 } catch (Exception x)
2834 if (Cache.log != null)
2836 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2840 System.err.println("Couldn't handle string " + url
2844 // ignore any exceptions due to dud links.
2851 * single thread that handles display of dialogs to user.
2853 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2856 * flag indicating if dialogExecutor should try to acquire a permit
2858 private volatile boolean dialogPause = true;
2863 private java.util.concurrent.Semaphore block = new Semaphore(0);
2866 * add another dialog thread to the queue
2870 public void addDialogThread(final Runnable prompter)
2872 dialogExecutor.submit(new Runnable()
2881 } catch (InterruptedException x)
2886 if (instance == null)
2892 SwingUtilities.invokeAndWait(prompter);
2893 } catch (Exception q)
2895 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2901 public void startDialogQueue()
2903 // set the flag so we don't pause waiting for another permit and semaphore
2904 // the current task to begin
2905 dialogPause = false;
2910 protected void snapShotWindow_actionPerformed(ActionEvent e)
2914 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2915 "View of Desktop", getWidth(), getHeight(), of = new File(
2916 "Jalview_snapshot" + System.currentTimeMillis()
2917 + ".eps"), "View of desktop");
2920 paintAll(im.getGraphics());
2922 } catch (Exception q)
2924 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
2928 Cache.log.info("Successfully written snapshot to file "
2929 + of.getAbsolutePath());
2933 * Explode the views in the given frame into separate AlignFrame windows.
2937 public void explodeViews(SplitFrame sf)
2939 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
2940 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
2941 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
2943 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
2945 int viewCount = topPanels.size();
2952 * Processing in reverse order works, forwards order leaves the first panels
2953 * not visible. I don't know why!
2955 for (int i = viewCount - 1; i >= 0; i--)
2958 * Make new top and bottom frames. These take over the respective
2959 * AlignmentPanel objects, including their AlignmentViewports, so the
2960 * cdna/protein relationships between the viewports is carried over to the
2963 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
2964 AlignFrame newTopFrame = new AlignFrame(topPanel);
2965 newTopFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
2966 AlignFrame.DEFAULT_HEIGHT));
2967 newTopFrame.setVisible(true);
2968 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
2969 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
2970 newBottomFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
2971 AlignFrame.DEFAULT_HEIGHT));
2972 newBottomFrame.setVisible(true);
2973 topPanel.av.setGatherViewsHere(false);
2974 bottomPanel.av.setGatherViewsHere(false);
2975 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
2977 // either panel may hold previous exploded frame geometry
2978 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
2979 .getExplodedGeometry();
2980 if (geometry != null)
2982 splitFrame.setBounds(geometry);
2984 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
2988 * Clear references to the panels (now relocated in the new SplitFrames)
2989 * before closing the old SplitFrame.
2992 bottomPanels.clear();
2997 * Gather expanded split frames, sharing the same pairs of sequence set ids,
2998 * back into the given SplitFrame as additional views. Note that the gathered
2999 * frames may themselves have multiple views.
3003 public void gatherViews(GSplitFrame source)
3005 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3006 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3007 myTopFrame.viewport.setExplodedGeometry(source.getBounds());
3008 myBottomFrame.viewport.setExplodedGeometry(source.getBounds());
3009 myTopFrame.viewport.setGatherViewsHere(true);
3010 myBottomFrame.viewport.setGatherViewsHere(true);
3011 String topViewId = myTopFrame.viewport.getSequenceSetId();
3012 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3014 JInternalFrame[] frames = desktop.getAllFrames();
3015 for (JInternalFrame frame : frames)
3017 if (frame instanceof SplitFrame && frame != source)
3019 SplitFrame sf = (SplitFrame) frame;
3020 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3021 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3022 boolean gatherThis = false;
3023 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3025 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3026 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3027 if (topViewId.equals(topPanel.av.getSequenceSetId())
3028 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3031 topPanel.av.setGatherViewsHere(false);
3032 bottomPanel.av.setGatherViewsHere(false);
3033 // both panels refer to the same split frame geometry
3034 Rectangle position = sf.getBounds();
3035 topPanel.av.setExplodedGeometry(position);
3036 bottomPanel.av.setExplodedGeometry(position);
3037 myTopFrame.addAlignmentPanel(topPanel, false);
3038 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3044 topFrame.getAlignPanels().clear();
3045 bottomFrame.getAlignPanels().clear();
3052 * The dust settles...give focus to the tab we did this from.
3054 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3058 // public static AlignFrame getCurrentAlignFrame()
3060 // return currentAlignFrame;
3063 // public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
3065 // Desktop.currentAlignFrame = currentAlignFrame;