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 public static jalview.ws.jws1.Discoverer discoverer;
174 public static Object[] jalviewClipboard;
176 public static boolean internalCopy = false;
178 static int fileLoadingCount = 0;
180 class MyDesktopManager implements DesktopManager
183 private DesktopManager delegate;
185 public MyDesktopManager(DesktopManager delegate)
187 this.delegate = delegate;
190 public void activateFrame(JInternalFrame f)
194 delegate.activateFrame(f);
195 } catch (NullPointerException npe)
197 Point p = getMousePosition();
198 instance.showPasteMenu(p.x, p.y);
202 public void beginDraggingFrame(JComponent f)
204 delegate.beginDraggingFrame(f);
207 public void beginResizingFrame(JComponent f, int direction)
209 delegate.beginResizingFrame(f, direction);
212 public void closeFrame(JInternalFrame f)
214 delegate.closeFrame(f);
217 public void deactivateFrame(JInternalFrame f)
219 delegate.deactivateFrame(f);
222 public void deiconifyFrame(JInternalFrame f)
224 delegate.deiconifyFrame(f);
227 public void dragFrame(JComponent f, int newX, int newY)
233 delegate.dragFrame(f, newX, newY);
236 public void endDraggingFrame(JComponent f)
238 delegate.endDraggingFrame(f);
241 public void endResizingFrame(JComponent f)
243 delegate.endResizingFrame(f);
246 public void iconifyFrame(JInternalFrame f)
248 delegate.iconifyFrame(f);
251 public void maximizeFrame(JInternalFrame f)
253 delegate.maximizeFrame(f);
256 public void minimizeFrame(JInternalFrame f)
258 delegate.minimizeFrame(f);
261 public void openFrame(JInternalFrame f)
263 delegate.openFrame(f);
266 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
269 Rectangle b = desktop.getBounds();
274 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
277 public void setBoundsForFrame(JComponent f, int newX, int newY,
278 int newWidth, int newHeight)
280 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
283 // All other methods, simply delegate
288 * Creates a new Desktop object.
293 * A note to implementors. It is ESSENTIAL that any activities that might
294 * block are spawned off as threads rather than waited for during this
298 doVamsasClientCheck();
300 doConfigureStructurePrefs();
301 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
302 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
303 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
305 boolean showjconsole = jalview.bin.Cache.getDefault(
306 "SHOW_JAVA_CONSOLE", false);
307 desktop = new MyDesktopPane(selmemusage);
308 showMemusage.setSelected(selmemusage);
309 desktop.setBackground(Color.white);
310 getContentPane().setLayout(new BorderLayout());
311 // alternate config - have scrollbars - see notes in JAL-153
312 // JScrollPane sp = new JScrollPane();
313 // sp.getViewport().setView(desktop);
314 // getContentPane().add(sp, BorderLayout.CENTER);
315 getContentPane().add(desktop, BorderLayout.CENTER);
316 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
318 // This line prevents Windows Look&Feel resizing all new windows to maximum
319 // if previous window was maximised
320 desktop.setDesktopManager(new MyDesktopManager(
321 new DefaultDesktopManager()));
323 Rectangle dims = getLastKnownDimensions("");
330 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
331 setBounds((screenSize.width - 900) / 2,
332 (screenSize.height - 650) / 2, 900, 650);
334 jconsole = new Console(this, showjconsole);
335 // add essential build information
336 jconsole.setHeader("Jalview Version: "
337 + jalview.bin.Cache.getProperty("VERSION") + "\n"
338 + "Jalview Installation: "
339 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
340 + "\n" + "Build Date: "
341 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
342 + "Java version: " + System.getProperty("java.version") + "\n"
343 + System.getProperty("os.arch") + " "
344 + System.getProperty("os.name") + " "
345 + System.getProperty("os.version"));
347 showConsole(showjconsole);
349 showNews.setVisible(false);
351 this.addWindowListener(new WindowAdapter()
353 public void windowClosing(WindowEvent evt)
360 this.addMouseListener(ma = new MouseAdapter()
362 public void mousePressed(MouseEvent evt)
364 if (SwingUtilities.isRightMouseButton(evt))
366 showPasteMenu(evt.getX(), evt.getY());
370 desktop.addMouseListener(ma);
372 this.addFocusListener(new FocusListener()
376 public void focusLost(FocusEvent e)
378 // TODO Auto-generated method stub
383 public void focusGained(FocusEvent e)
385 Cache.log.debug("Relaying windows after focus gain");
386 // make sure that we sort windows properly after we gain focus
387 instance.relayerWindows();
390 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
391 // Spawn a thread that shows the splashscreen
392 SwingUtilities.invokeLater(new Runnable()
401 // Thread off a new instance of the file chooser - this reduces the time it
402 // takes to open it later on.
403 new Thread(new Runnable()
407 Cache.log.debug("Filechooser init thread started.");
408 JalviewFileChooser chooser = new JalviewFileChooser(
409 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
410 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
411 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
412 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
413 Cache.log.debug("Filechooser init thread finished.");
416 // Add the service change listener
417 changeSupport.addJalviewPropertyChangeListener("services",
418 new PropertyChangeListener()
422 public void propertyChange(PropertyChangeEvent evt)
424 Cache.log.debug("Firing service changed event for "
425 + evt.getNewValue());
426 JalviewServicesChanged(evt);
432 public void doConfigureStructurePrefs()
434 // configure services
435 StructureSelectionManager ssm = StructureSelectionManager
436 .getStructureSelectionManager(this);
437 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
439 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
440 Preferences.ADD_TEMPFACT_ANN, true));
441 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
442 Preferences.STRUCT_FROM_PDB, true));
443 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
444 Preferences.USE_RNAVIEW, true));
448 ssm.setAddTempFacAnnot(false);
449 ssm.setProcessSecondaryStructure(false);
450 ssm.setSecStructServices(false);
454 public void checkForNews()
456 final Desktop me = this;
457 // Thread off the news reader, in case there are connection problems.
458 addDialogThread(new Runnable()
463 Cache.log.debug("Starting news thread.");
465 jvnews = new BlogReader(me);
466 showNews.setVisible(true);
467 Cache.log.debug("Completed news thread.");
472 protected void showNews_actionPerformed(ActionEvent e)
474 showNews(showNews.isSelected());
477 void showNews(boolean visible)
480 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
481 showNews.setSelected(visible);
482 if (visible && !jvnews.isVisible())
484 new Thread(new Runnable()
489 long instance = System.currentTimeMillis();
490 Desktop.instance.setProgressBar(
491 MessageManager.getString("status.refreshing_news"),
493 jvnews.refreshNews();
494 Desktop.instance.setProgressBar(null, instance);
503 * recover the last known dimensions for a jalview window
506 * - empty string is desktop, all other windows have unique prefix
507 * @return null or last known dimensions scaled to current geometry (if last
508 * window geom was known)
510 Rectangle getLastKnownDimensions(String windowName)
512 // TODO: lock aspect ratio for scaling desktop Bug #0058199
513 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
514 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
515 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
516 String width = jalview.bin.Cache.getProperty(windowName
518 String height = jalview.bin.Cache.getProperty(windowName
520 if ((x != null) && (y != null) && (width != null) && (height != null))
522 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
523 .parseInt(width), ih = Integer.parseInt(height);
524 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
526 // attempt #1 - try to cope with change in screen geometry - this
527 // version doesn't preserve original jv aspect ratio.
528 // take ratio of current screen size vs original screen size.
529 double sw = ((1f * screenSize.width) / (1f * Integer
530 .parseInt(jalview.bin.Cache
531 .getProperty("SCREENGEOMETRY_WIDTH"))));
532 double sh = ((1f * screenSize.height) / (1f * Integer
533 .parseInt(jalview.bin.Cache
534 .getProperty("SCREENGEOMETRY_HEIGHT"))));
535 // rescale the bounds depending upon the current screen geometry.
536 ix = (int) (ix * sw);
537 iw = (int) (iw * sw);
538 iy = (int) (iy * sh);
539 ih = (int) (ih * sh);
540 while (ix >= screenSize.width)
542 jalview.bin.Cache.log
543 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
544 ix -= screenSize.width;
546 while (iy >= screenSize.height)
548 jalview.bin.Cache.log
549 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
550 iy -= screenSize.height;
552 jalview.bin.Cache.log.debug("Got last known dimensions for "
553 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
556 // return dimensions for new instance
557 return new Rectangle(ix, iy, iw, ih);
562 private void doVamsasClientCheck()
564 if (jalview.bin.Cache.vamsasJarsPresent())
566 setupVamsasDisconnectedGui();
567 VamsasMenu.setVisible(true);
568 final Desktop us = this;
569 VamsasMenu.addMenuListener(new MenuListener()
571 // this listener remembers when the menu was first selected, and
572 // doesn't rebuild the session list until it has been cleared and
574 boolean refresh = true;
576 public void menuCanceled(MenuEvent e)
581 public void menuDeselected(MenuEvent e)
586 public void menuSelected(MenuEvent e)
590 us.buildVamsasStMenu();
595 vamsasStart.setVisible(true);
599 void showPasteMenu(int x, int y)
601 JPopupMenu popup = new JPopupMenu();
602 JMenuItem item = new JMenuItem(
603 MessageManager.getString("label.paste_new_window"));
604 item.addActionListener(new ActionListener()
606 public void actionPerformed(ActionEvent evt)
613 popup.show(this, x, y);
620 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
621 Transferable contents = c.getContents(this);
623 if (contents != null)
625 String file = (String) contents
626 .getTransferData(DataFlavor.stringFlavor);
628 String format = new IdentifyFile().Identify(file,
629 FormatAdapter.PASTE);
631 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
634 } catch (Exception ex)
637 .println("Unable to paste alignment from system clipboard:\n"
643 * Adds and opens the given frame to the desktop
654 public static synchronized void addInternalFrame(
655 final JInternalFrame frame, String title, int w, int h)
657 addInternalFrame(frame, title, true, w, h, true);
661 * Add an internal frame to the Jalview desktop
668 * When true, display frame immediately, otherwise, caller must call
669 * setVisible themselves.
675 public static synchronized void addInternalFrame(
676 final JInternalFrame frame, String title, boolean makeVisible,
679 addInternalFrame(frame, title, makeVisible, w, h, true);
683 * Add an internal frame to the Jalview desktop and make it visible
696 public static synchronized void addInternalFrame(
697 final JInternalFrame frame, String title, int w, int h,
700 addInternalFrame(frame, title, true, w, h, resizable);
704 * Add an internal frame to the Jalview desktop
711 * When true, display frame immediately, otherwise, caller must call
712 * setVisible themselves.
720 public static synchronized void addInternalFrame(
721 final JInternalFrame frame, String title, boolean makeVisible,
722 int w, int h, boolean resizable)
725 // TODO: allow callers to determine X and Y position of frame (eg. via
727 // TODO: consider fixing method to update entries in the window submenu with
728 // the current window title
730 frame.setTitle(title);
731 if (frame.getWidth() < 1 || frame.getHeight() < 1)
735 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
736 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
737 // IF JALVIEW IS RUNNING HEADLESS
738 // ///////////////////////////////////////////////
740 || (System.getProperty("java.awt.headless") != null && System
741 .getProperty("java.awt.headless").equals("true")))
748 frame.setVisible(makeVisible);
749 frame.setClosable(true);
750 frame.setResizable(resizable);
751 frame.setMaximizable(resizable);
752 frame.setIconifiable(resizable);
753 frame.setFrameIcon(null);
755 if (frame.getX() < 1 && frame.getY() < 1)
757 frame.setLocation(xOffset * openFrameCount, yOffset
758 * ((openFrameCount - 1) % 10) + yOffset);
761 final JMenuItem menuItem = new JMenuItem(title);
762 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
764 public void internalFrameActivated(
765 javax.swing.event.InternalFrameEvent evt)
767 JInternalFrame itf = desktop.getSelectedFrame();
775 public void internalFrameClosed(
776 javax.swing.event.InternalFrameEvent evt)
778 PaintRefresher.RemoveComponent(frame);
780 windowMenu.remove(menuItem);
781 JInternalFrame itf = desktop.getSelectedFrame();
790 menuItem.addActionListener(new ActionListener()
792 public void actionPerformed(ActionEvent e)
796 frame.setSelected(true);
797 frame.setIcon(false);
798 } catch (java.beans.PropertyVetoException ex)
804 menuItem.addMouseListener(new MouseListener()
808 public void mouseReleased(MouseEvent e)
813 public void mousePressed(MouseEvent e)
818 public void mouseExited(MouseEvent e)
822 frame.setSelected(false);
823 } catch (PropertyVetoException e1)
829 public void mouseEntered(MouseEvent e)
833 frame.setSelected(true);
834 } catch (PropertyVetoException e1)
840 public void mouseClicked(MouseEvent e)
846 windowMenu.add(menuItem);
852 frame.setSelected(true);
853 frame.requestFocus();
854 } catch (java.beans.PropertyVetoException ve)
856 } catch (java.lang.ClassCastException cex)
859 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
864 public void lostOwnership(Clipboard clipboard, Transferable contents)
868 Desktop.jalviewClipboard = null;
871 internalCopy = false;
874 public void dragEnter(DropTargetDragEvent evt)
878 public void dragExit(DropTargetEvent evt)
882 public void dragOver(DropTargetDragEvent evt)
886 public void dropActionChanged(DropTargetDragEvent evt)
896 public void drop(DropTargetDropEvent evt)
898 boolean success = true;
899 Transferable t = evt.getTransferable();
900 java.util.List files = null;
901 java.util.List protocols = null;
905 DataFlavor uriListFlavor = new DataFlavor(
906 "text/uri-list;class=java.lang.String");
907 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
909 // Works on Windows and MacOSX
910 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
911 files = (java.util.List) t
912 .getTransferData(DataFlavor.javaFileListFlavor);
914 else if (t.isDataFlavorSupported(uriListFlavor))
916 // This is used by Unix drag system
917 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
918 String data = (String) t.getTransferData(uriListFlavor);
919 files = new java.util.ArrayList(1);
920 protocols = new java.util.ArrayList(1);
921 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
922 data, "\r\n"); st.hasMoreTokens();)
924 String s = st.nextToken();
925 if (s.startsWith("#"))
927 // the line is a comment (as per the RFC 2483)
930 java.net.URI uri = new java.net.URI(s);
931 if (uri.getScheme().toLowerCase().startsWith("http"))
933 protocols.add(FormatAdapter.URL);
934 files.add(uri.toString());
938 // otherwise preserve old behaviour: catch all for file objects
939 java.io.File file = new java.io.File(uri);
940 protocols.add(FormatAdapter.FILE);
941 files.add(file.toString());
945 } catch (Exception e)
954 for (int i = 0; i < files.size(); i++)
956 String file = files.get(i).toString();
957 String protocol = (protocols == null) ? FormatAdapter.FILE
958 : (String) protocols.get(i);
959 String format = null;
961 if (file.endsWith(".jar"))
968 format = new IdentifyFile().Identify(file, protocol);
971 new FileLoader().LoadFile(file, protocol, format);
974 } catch (Exception ex)
979 evt.dropComplete(success); // need this to ensure input focus is properly
980 // transfered to any new windows created
989 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
991 JalviewFileChooser chooser = new JalviewFileChooser(
992 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
993 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
994 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
995 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
997 chooser.setFileView(new JalviewFileView());
998 chooser.setDialogTitle(MessageManager
999 .getString("label.open_local_file"));
1000 chooser.setToolTipText(MessageManager.getString("action.open"));
1002 int value = chooser.showOpenDialog(this);
1004 if (value == JalviewFileChooser.APPROVE_OPTION)
1006 String choice = chooser.getSelectedFile().getPath();
1007 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1008 .getSelectedFile().getParent());
1010 String format = null;
1011 if (chooser.getSelectedFormat() != null
1012 && chooser.getSelectedFormat().equals("Jalview"))
1018 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1021 if (viewport != null)
1023 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1028 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1039 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1041 // This construct allows us to have a wider textfield
1043 JLabel label = new JLabel(
1044 MessageManager.getString("label.input_file_url"));
1045 final JComboBox history = new JComboBox();
1047 JPanel panel = new JPanel(new GridLayout(2, 1));
1050 history.setPreferredSize(new Dimension(400, 20));
1051 history.setEditable(true);
1052 history.addItem("http://www.");
1054 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1058 if (historyItems != null)
1060 st = new StringTokenizer(historyItems, "\t");
1062 while (st.hasMoreTokens())
1064 history.addItem(st.nextElement());
1068 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1069 MessageManager.getString("label.input_alignment_from_url"),
1070 JOptionPane.OK_CANCEL_OPTION);
1072 if (reply != JOptionPane.OK_OPTION)
1077 String url = history.getSelectedItem().toString();
1079 if (url.toLowerCase().endsWith(".jar"))
1081 if (viewport != null)
1083 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1088 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1093 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1095 if (format.equals("URL NOT FOUND"))
1097 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1098 MessageManager.formatMessage("label.couldnt_locate",
1100 { url }), MessageManager
1101 .getString("label.url_not_found"),
1102 JOptionPane.WARNING_MESSAGE);
1107 if (viewport != null)
1109 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1113 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1124 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1126 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1127 cap.setForInput(viewport);
1128 Desktop.addInternalFrame(cap,
1129 MessageManager.getString("label.cut_paste_alignmen_file"),
1138 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1140 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1141 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1143 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1144 getBounds().y, getWidth(), getHeight()));
1146 if (jconsole != null)
1148 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1149 jconsole.stopConsole();
1153 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1156 if (dialogExecutor != null)
1158 dialogExecutor.shutdownNow();
1164 private void storeLastKnownDimensions(String string, Rectangle jc)
1166 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1167 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1168 + " height:" + jc.height);
1170 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1171 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1172 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1173 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1182 public void aboutMenuItem_actionPerformed(ActionEvent e)
1184 // StringBuffer message = getAboutMessage(false);
1185 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1187 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1188 new Thread(new Runnable()
1192 new SplashScreen(true);
1197 public StringBuffer getAboutMessage(boolean shortv)
1199 StringBuffer message = new StringBuffer();
1200 message.append("<html>");
1203 message.append("<h1><strong>Version: "
1204 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1205 message.append("<strong>Last Updated: <em>"
1206 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1207 + "</em></strong>");
1213 message.append("<strong>Version "
1214 + jalview.bin.Cache.getProperty("VERSION")
1215 + "; last updated: "
1216 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1219 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1222 message.append("<br>...Checking latest version...</br>");
1224 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1225 .equals(jalview.bin.Cache.getProperty("VERSION")))
1227 boolean red = false;
1228 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1229 .indexOf("automated build") == -1)
1232 // Displayed when code version and jnlp version do not match and code
1233 // version is not a development build
1234 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1237 message.append("<br>!! Version "
1238 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1240 + " is available for download from "
1241 + jalview.bin.Cache.getDefault("www.jalview.org",
1242 "http://www.jalview.org") + " !!");
1245 message.append("</div>");
1248 message.append("<br>Authors: "
1250 .getDefault("AUTHORFNAMES",
1251 "The Jalview Authors (See AUTHORS file for current list)")
1252 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1253 + "<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"
1254 + "<br><br>If you use Jalview, please cite:"
1255 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1256 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1257 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1268 public void documentationMenuItem_actionPerformed(ActionEvent e)
1272 Help.showHelpWindow();
1273 } catch (Exception ex)
1278 public void closeAll_actionPerformed(ActionEvent e)
1280 JInternalFrame[] frames = desktop.getAllFrames();
1281 for (int i = 0; i < frames.length; i++)
1285 frames[i].setClosed(true);
1286 } catch (java.beans.PropertyVetoException ex)
1290 System.out.println("ALL CLOSED");
1291 if (v_client != null)
1293 // TODO clear binding to vamsas document objects on close_all
1298 public void raiseRelated_actionPerformed(ActionEvent e)
1300 reorderAssociatedWindows(false, false);
1303 public void minimizeAssociated_actionPerformed(ActionEvent e)
1305 reorderAssociatedWindows(true, false);
1308 void closeAssociatedWindows()
1310 reorderAssociatedWindows(false, true);
1316 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1319 protected void garbageCollect_actionPerformed(ActionEvent e)
1321 // We simply collect the garbage
1322 jalview.bin.Cache.log.debug("Collecting garbage...");
1324 jalview.bin.Cache.log.debug("Finished garbage collection.");
1331 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1334 protected void showMemusage_actionPerformed(ActionEvent e)
1336 desktop.showMemoryUsage(showMemusage.isSelected());
1343 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1346 protected void showConsole_actionPerformed(ActionEvent e)
1348 showConsole(showConsole.isSelected());
1351 Console jconsole = null;
1354 * control whether the java console is visible or not
1358 void showConsole(boolean selected)
1360 showConsole.setSelected(selected);
1361 // TODO: decide if we should update properties file
1362 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1364 jconsole.setVisible(selected);
1367 void reorderAssociatedWindows(boolean minimize, boolean close)
1369 JInternalFrame[] frames = desktop.getAllFrames();
1370 if (frames == null || frames.length < 1)
1375 AlignmentViewport source = null, target = null;
1376 if (frames[0] instanceof AlignFrame)
1378 source = ((AlignFrame) frames[0]).getCurrentView();
1380 else if (frames[0] instanceof TreePanel)
1382 source = ((TreePanel) frames[0]).getViewPort();
1384 else if (frames[0] instanceof PCAPanel)
1386 source = ((PCAPanel) frames[0]).av;
1388 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1390 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1395 for (int i = 0; i < frames.length; i++)
1398 if (frames[i] == null)
1402 if (frames[i] instanceof AlignFrame)
1404 target = ((AlignFrame) frames[i]).getCurrentView();
1406 else if (frames[i] instanceof TreePanel)
1408 target = ((TreePanel) frames[i]).getViewPort();
1410 else if (frames[i] instanceof PCAPanel)
1412 target = ((PCAPanel) frames[i]).av;
1414 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1416 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1419 if (source == target)
1425 frames[i].setClosed(true);
1429 frames[i].setIcon(minimize);
1432 frames[i].toFront();
1436 } catch (java.beans.PropertyVetoException ex)
1450 protected void preferences_actionPerformed(ActionEvent e)
1461 public void saveState_actionPerformed(ActionEvent e)
1463 JalviewFileChooser chooser = new JalviewFileChooser(
1464 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1465 { "jvp" }, new String[]
1466 { "Jalview Project" }, "Jalview Project");
1468 chooser.setFileView(new JalviewFileView());
1469 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1471 int value = chooser.showSaveDialog(this);
1473 if (value == JalviewFileChooser.APPROVE_OPTION)
1475 final Desktop me = this;
1476 final java.io.File choice = chooser.getSelectedFile();
1477 setProjectFile(choice);
1479 // TODO or move inside the new Thread?
1480 saveChimeraSessions(choice.getAbsolutePath());
1482 new Thread(new Runnable()
1487 setProgressBar(MessageManager.formatMessage(
1488 "label.saving_jalview_project", new Object[]
1489 { choice.getName() }), choice.hashCode());
1490 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1491 choice.getParent());
1492 // TODO catch and handle errors for savestate
1493 // TODO prevent user from messing with the Desktop whilst we're saving
1496 new Jalview2XML().saveState(choice);
1497 } catch (OutOfMemoryError oom)
1499 new OOMWarning("Whilst saving current state to "
1500 + choice.getName(), oom);
1501 } catch (Exception ex)
1504 "Problems whilst trying to save to " + choice.getName(),
1506 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1507 "label.error_whilst_saving_current_state_to",
1509 { choice.getName() }), MessageManager
1510 .getString("label.couldnt_save_project"),
1511 JOptionPane.WARNING_MESSAGE);
1513 setProgressBar(null, choice.hashCode());
1520 * Request any open, linked Chimera sessions to save their state.
1522 * @param jalviewProjectFilename
1523 * the filename of the Jalview project; Chimera session files should
1524 * be given distinct, but obviously related, names.
1526 public void saveChimeraSessions(String jalviewProjectFilename)
1529 for (JInternalFrame frame : getAllFrames())
1531 if (frame instanceof ChimeraViewFrame)
1534 * Construct a filename for the Chimera session by append _chimera<n>.py
1535 * to the Jalview project file name.
1537 String chimeraPath = jalviewProjectFilename + "_chimera_" + i
1539 ((ChimeraViewFrame) frame).saveSession(chimeraPath);
1545 private void setProjectFile(File choice)
1547 this.projectFile = choice;
1550 public File getProjectFile()
1552 return this.projectFile;
1561 public void loadState_actionPerformed(ActionEvent e)
1563 JalviewFileChooser chooser = new JalviewFileChooser(
1564 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1565 { "jvp", "jar" }, new String[]
1566 { "Jalview Project", "Jalview Project (old)" },
1568 chooser.setFileView(new JalviewFileView());
1569 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1571 int value = chooser.showOpenDialog(this);
1573 if (value == JalviewFileChooser.APPROVE_OPTION)
1575 final File selectedFile = chooser.getSelectedFile();
1576 setProjectFile(selectedFile);
1577 final String choice = selectedFile.getAbsolutePath();
1578 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1579 selectedFile.getParent());
1580 new Thread(new Runnable()
1584 setProgressBar(MessageManager.formatMessage(
1585 "label.loading_jalview_project", new Object[]
1586 { choice }), choice.hashCode());
1589 new Jalview2XML().loadJalviewAlign(choice);
1590 } catch (OutOfMemoryError oom)
1592 new OOMWarning("Whilst loading project from " + choice, oom);
1593 } catch (Exception ex)
1595 Cache.log.error("Problems whilst loading project from "
1597 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1599 "label.error_whilst_loading_project_from",
1601 { choice }), MessageManager
1602 .getString("label.couldnt_load_project"),
1603 JOptionPane.WARNING_MESSAGE);
1605 setProgressBar(null, choice.hashCode());
1611 public void inputSequence_actionPerformed(ActionEvent e)
1613 new SequenceFetcher(this);
1616 JPanel progressPanel;
1618 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1620 public void startLoading(final String fileName)
1622 if (fileLoadingCount == 0)
1624 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1625 "label.loading_file", new Object[]
1631 private JPanel addProgressPanel(String string)
1633 if (progressPanel == null)
1635 progressPanel = new JPanel(new GridLayout(1, 1));
1636 totalProgressCount = 0;
1637 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1639 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1640 JProgressBar progressBar = new JProgressBar();
1641 progressBar.setIndeterminate(true);
1643 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1645 thisprogress.add(progressBar, BorderLayout.CENTER);
1646 progressPanel.add(thisprogress);
1647 ((GridLayout) progressPanel.getLayout())
1648 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1649 ++totalProgressCount;
1650 instance.validate();
1651 return thisprogress;
1654 int totalProgressCount = 0;
1656 private void removeProgressPanel(JPanel progbar)
1658 if (progressPanel != null)
1660 synchronized (progressPanel)
1662 progressPanel.remove(progbar);
1663 GridLayout gl = (GridLayout) progressPanel.getLayout();
1664 gl.setRows(gl.getRows() - 1);
1665 if (--totalProgressCount < 1)
1667 this.getContentPane().remove(progressPanel);
1668 progressPanel = null;
1675 public void stopLoading()
1678 if (fileLoadingCount < 1)
1680 while (fileLoadingPanels.size() > 0)
1682 removeProgressPanel(fileLoadingPanels.remove(0));
1684 fileLoadingPanels.clear();
1685 fileLoadingCount = 0;
1690 public static int getViewCount(String alignmentId)
1692 AlignmentViewport[] aps = getViewports(alignmentId);
1693 return (aps == null) ? 0 : aps.length;
1698 * @param alignmentId
1699 * - if null, all sets are returned
1700 * @return all AlignmentPanels concerning the alignmentId sequence set
1702 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1704 if (Desktop.desktop == null)
1706 // no frames created and in headless mode
1707 // TODO: verify that frames are recoverable when in headless mode
1710 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1711 AlignFrame[] frames = getAlignFrames();
1716 for (AlignFrame af : frames)
1718 for (AlignmentPanel ap : af.alignPanels)
1720 if (alignmentId==null || alignmentId.equals(ap.av.getSequenceSetId()))
1726 if (aps.size() == 0)
1730 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1735 * get all the viewports on an alignment.
1737 * @param sequenceSetId
1738 * unique alignment id (may be null - all viewports returned in that
1740 * @return all viewports on the alignment bound to sequenceSetId
1742 public static AlignmentViewport[] getViewports(String sequenceSetId)
1744 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1745 if (desktop != null)
1747 AlignFrame[] frames = Desktop.getAlignFrames();
1749 for (AlignFrame afr : frames)
1751 if (sequenceSetId==null || afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1753 if (afr.alignPanels != null)
1755 for (AlignmentPanel ap : afr.alignPanels)
1757 if (sequenceSetId == null
1758 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1766 viewp.add(afr.getViewport());
1770 if (viewp.size() > 0)
1772 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1779 * Explode the views in the given frame into separate AlignFrame
1783 public void explodeViews(AlignFrame af)
1785 int size = af.alignPanels.size();
1791 for (int i = 0; i < size; i++)
1793 AlignmentPanel ap = af.alignPanels.get(i);
1794 AlignFrame newaf = new AlignFrame(ap);
1797 * Restore the view's last exploded frame geometry if known. Multiple
1798 * views from one exploded frame share and restore the same (frame)
1799 * position and size.
1801 Rectangle geometry = ap.av.getExplodedGeometry();
1802 if (geometry != null)
1804 newaf.setBounds(geometry);
1807 ap.av.setGatherViewsHere(false);
1809 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1810 AlignFrame.DEFAULT_HEIGHT);
1813 af.alignPanels.clear();
1814 af.closeMenuItem_actionPerformed(true);
1819 * Gather expanded views (separate AlignFrame's) with the same sequence set
1820 * identifier back in to this frame as additional views, and close the
1821 * expanded views. Note the expanded frames may themselves have multiple
1822 * views. We take the lot.
1826 public void gatherViews(AlignFrame source)
1828 source.viewport.setGatherViewsHere(true);
1829 source.viewport.setExplodedGeometry(source.getBounds());
1830 JInternalFrame[] frames = desktop.getAllFrames();
1831 String viewId = source.viewport.getSequenceSetId();
1833 for (int t = 0; t < frames.length; t++)
1835 if (frames[t] instanceof AlignFrame && frames[t] != source)
1837 AlignFrame af = (AlignFrame) frames[t];
1838 boolean gatherThis = false;
1839 for (int a = 0; a < af.alignPanels.size(); a++)
1841 AlignmentPanel ap = af.alignPanels.get(a);
1842 if (viewId.equals(ap.av.getSequenceSetId()))
1845 ap.av.setGatherViewsHere(false);
1846 ap.av.setExplodedGeometry(af.getBounds());
1847 source.addAlignmentPanel(ap, false);
1853 af.alignPanels.clear();
1854 af.closeMenuItem_actionPerformed(true);
1861 jalview.gui.VamsasApplication v_client = null;
1863 public void vamsasImport_actionPerformed(ActionEvent e)
1865 if (v_client == null)
1867 // Load and try to start a session.
1868 JalviewFileChooser chooser = new JalviewFileChooser(
1869 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1871 chooser.setFileView(new JalviewFileView());
1872 chooser.setDialogTitle(MessageManager
1873 .getString("label.open_saved_vamsas_session"));
1874 chooser.setToolTipText(MessageManager
1875 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1877 int value = chooser.showOpenDialog(this);
1879 if (value == JalviewFileChooser.APPROVE_OPTION)
1881 String fle = chooser.getSelectedFile().toString();
1882 if (!vamsasImport(chooser.getSelectedFile()))
1885 .showInternalMessageDialog(
1887 MessageManager.formatMessage(
1888 "label.couldnt_import_as_vamsas_session",
1892 .getString("label.vamsas_document_import_failed"),
1893 JOptionPane.ERROR_MESSAGE);
1899 jalview.bin.Cache.log
1900 .error("Implementation error - load session from a running session is not supported.");
1905 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1908 * @return true if import was a success and a session was started.
1910 public boolean vamsasImport(URL url)
1912 // TODO: create progress bar
1913 if (v_client != null)
1916 jalview.bin.Cache.log
1917 .error("Implementation error - load session from a running session is not supported.");
1923 // copy the URL content to a temporary local file
1924 // TODO: be a bit cleverer here with nio (?!)
1925 File file = File.createTempFile("vdocfromurl", ".vdj");
1926 FileOutputStream fos = new FileOutputStream(file);
1927 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1928 byte[] buffer = new byte[2048];
1930 while ((ln = bis.read(buffer)) > -1)
1932 fos.write(buffer, 0, ln);
1936 v_client = new jalview.gui.VamsasApplication(this, file,
1937 url.toExternalForm());
1938 } catch (Exception ex)
1940 jalview.bin.Cache.log.error(
1941 "Failed to create new vamsas session from contents of URL "
1945 setupVamsasConnectedGui();
1946 v_client.initial_update(); // TODO: thread ?
1947 return v_client.inSession();
1951 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1954 * @return true if import was a success and a session was started.
1956 public boolean vamsasImport(File file)
1958 if (v_client != null)
1961 jalview.bin.Cache.log
1962 .error("Implementation error - load session from a running session is not supported.");
1966 setProgressBar(MessageManager.formatMessage(
1967 "status.importing_vamsas_session_from", new Object[]
1968 { file.getName() }), file.hashCode());
1971 v_client = new jalview.gui.VamsasApplication(this, file, null);
1972 } catch (Exception ex)
1974 setProgressBar(MessageManager.formatMessage(
1975 "status.importing_vamsas_session_from", new Object[]
1976 { file.getName() }), file.hashCode());
1977 jalview.bin.Cache.log.error(
1978 "New vamsas session from existing session file failed:", ex);
1981 setupVamsasConnectedGui();
1982 v_client.initial_update(); // TODO: thread ?
1983 setProgressBar(MessageManager.formatMessage(
1984 "status.importing_vamsas_session_from", new Object[]
1985 { file.getName() }), file.hashCode());
1986 return v_client.inSession();
1989 public boolean joinVamsasSession(String mysesid)
1991 if (v_client != null)
1995 .getString("error.try_join_vamsas_session_another"));
1997 if (mysesid == null)
2000 MessageManager.getString("error.invalid_vamsas_session_id"));
2002 v_client = new VamsasApplication(this, mysesid);
2003 setupVamsasConnectedGui();
2004 v_client.initial_update();
2005 return (v_client.inSession());
2008 public void vamsasStart_actionPerformed(ActionEvent e)
2010 if (v_client == null)
2013 // we just start a default session for moment.
2015 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2016 * getProperty("LAST_DIRECTORY"));
2018 * chooser.setFileView(new JalviewFileView());
2019 * chooser.setDialogTitle("Load Vamsas file");
2020 * chooser.setToolTipText("Import");
2022 * int value = chooser.showOpenDialog(this);
2024 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2025 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2027 v_client = new VamsasApplication(this);
2028 setupVamsasConnectedGui();
2029 v_client.initial_update(); // TODO: thread ?
2033 // store current data in session.
2034 v_client.push_update(); // TODO: thread
2038 protected void setupVamsasConnectedGui()
2040 vamsasStart.setText(MessageManager.getString("label.session_update"));
2041 vamsasSave.setVisible(true);
2042 vamsasStop.setVisible(true);
2043 vamsasImport.setVisible(false); // Document import to existing session is
2044 // not possible for vamsas-client-1.0.
2047 protected void setupVamsasDisconnectedGui()
2049 vamsasSave.setVisible(false);
2050 vamsasStop.setVisible(false);
2051 vamsasImport.setVisible(true);
2052 vamsasStart.setText(MessageManager
2053 .getString("label.new_vamsas_session"));
2056 public void vamsasStop_actionPerformed(ActionEvent e)
2058 if (v_client != null)
2060 v_client.end_session();
2062 setupVamsasDisconnectedGui();
2066 protected void buildVamsasStMenu()
2068 if (v_client == null)
2070 String[] sess = null;
2073 sess = VamsasApplication.getSessionList();
2074 } catch (Exception e)
2076 jalview.bin.Cache.log.warn(
2077 "Problem getting current sessions list.", e);
2082 jalview.bin.Cache.log.debug("Got current sessions list: "
2083 + sess.length + " entries.");
2084 VamsasStMenu.removeAll();
2085 for (int i = 0; i < sess.length; i++)
2087 JMenuItem sessit = new JMenuItem();
2088 sessit.setText(sess[i]);
2089 sessit.setToolTipText(MessageManager.formatMessage(
2090 "label.connect_to_session", new Object[]
2092 final Desktop dsktp = this;
2093 final String mysesid = sess[i];
2094 sessit.addActionListener(new ActionListener()
2097 public void actionPerformed(ActionEvent e)
2099 if (dsktp.v_client == null)
2101 Thread rthr = new Thread(new Runnable()
2106 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2107 dsktp.setupVamsasConnectedGui();
2108 dsktp.v_client.initial_update();
2116 VamsasStMenu.add(sessit);
2118 // don't show an empty menu.
2119 VamsasStMenu.setVisible(sess.length > 0);
2124 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2125 VamsasStMenu.removeAll();
2126 VamsasStMenu.setVisible(false);
2131 // Not interested in the content. Just hide ourselves.
2132 VamsasStMenu.setVisible(false);
2136 public void vamsasSave_actionPerformed(ActionEvent e)
2138 if (v_client != null)
2140 JalviewFileChooser chooser = new JalviewFileChooser(
2141 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2142 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2144 { "Vamsas Document" }, "Vamsas Document");
2146 chooser.setFileView(new JalviewFileView());
2147 chooser.setDialogTitle(MessageManager
2148 .getString("label.save_vamsas_document_archive"));
2150 int value = chooser.showSaveDialog(this);
2152 if (value == JalviewFileChooser.APPROVE_OPTION)
2154 java.io.File choice = chooser.getSelectedFile();
2155 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2156 "label.saving_vamsas_doc", new Object[]
2157 { choice.getName() }));
2158 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2159 String warnmsg = null;
2160 String warnttl = null;
2163 v_client.vclient.storeDocument(choice);
2166 warnttl = "Serious Problem saving Vamsas Document";
2167 warnmsg = ex.toString();
2168 jalview.bin.Cache.log.error("Error Whilst saving document to "
2171 } catch (Exception ex)
2173 warnttl = "Problem saving Vamsas Document.";
2174 warnmsg = ex.toString();
2175 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2179 removeProgressPanel(progpanel);
2180 if (warnmsg != null)
2182 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2184 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2190 JPanel vamUpdate = null;
2193 * hide vamsas user gui bits when a vamsas document event is being handled.
2196 * true to hide gui, false to reveal gui
2198 public void setVamsasUpdate(boolean b)
2200 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2201 + (b ? "in progress" : "finished"));
2203 if (vamUpdate != null)
2205 this.removeProgressPanel(vamUpdate);
2209 vamUpdate = this.addProgressPanel(MessageManager
2210 .getString("label.updating_vamsas_session"));
2212 vamsasStart.setVisible(!b);
2213 vamsasStop.setVisible(!b);
2214 vamsasSave.setVisible(!b);
2217 public JInternalFrame[] getAllFrames()
2219 return desktop.getAllFrames();
2223 * Checks the given url to see if it gives a response indicating that the user
2224 * should be informed of a new questionnaire.
2228 public void checkForQuestionnaire(String url)
2230 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2231 // javax.swing.SwingUtilities.invokeLater(jvq);
2232 new Thread(jvq).start();
2236 * Proxy class for JDesktopPane which optionally displays the current memory
2237 * usage and highlights the desktop area with a red bar if free memory runs
2242 public class MyDesktopPane extends JDesktopPane implements Runnable
2245 private static final float ONE_MB = 1048576f;
2247 boolean showMemoryUsage = false;
2251 java.text.NumberFormat df;
2253 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2256 public MyDesktopPane(boolean showMemoryUsage)
2258 showMemoryUsage(showMemoryUsage);
2261 public void showMemoryUsage(boolean showMemoryUsage)
2263 this.showMemoryUsage = showMemoryUsage;
2264 if (showMemoryUsage)
2266 Thread worker = new Thread(this);
2271 public boolean isShowMemoryUsage()
2273 return showMemoryUsage;
2278 df = java.text.NumberFormat.getNumberInstance();
2279 df.setMaximumFractionDigits(2);
2280 runtime = Runtime.getRuntime();
2282 while (showMemoryUsage)
2286 maxMemory = runtime.maxMemory() / ONE_MB;
2287 allocatedMemory = runtime.totalMemory() / ONE_MB;
2288 freeMemory = runtime.freeMemory() / ONE_MB;
2289 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2291 percentUsage = (totalFreeMemory / maxMemory) * 100;
2293 // if (percentUsage < 20)
2295 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2297 // instance.set.setBorder(border1);
2300 // sleep after showing usage
2302 } catch (Exception ex)
2304 ex.printStackTrace();
2309 public void paintComponent(Graphics g)
2311 if (showMemoryUsage && g != null && df != null)
2313 if (percentUsage < 20)
2315 g.setColor(Color.red);
2317 FontMetrics fm = g.getFontMetrics();
2320 g.drawString(MessageManager.formatMessage(
2321 "label.memory_stats",
2323 { df.format(totalFreeMemory), df.format(maxMemory),
2324 df.format(percentUsage) }), 10,
2325 getHeight() - fm.getHeight());
2332 * fixes stacking order after a modal dialog to ensure windows that should be
2333 * on top actually are
2335 public void relayerWindows()
2340 protected JMenuItem groovyShell;
2342 public void doGroovyCheck()
2344 if (jalview.bin.Cache.groovyJarsPresent())
2346 groovyShell = new JMenuItem();
2347 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2348 groovyShell.addActionListener(new ActionListener()
2350 public void actionPerformed(ActionEvent e)
2352 groovyShell_actionPerformed(e);
2355 toolsMenu.add(groovyShell);
2356 groovyShell.setVisible(true);
2361 * Accessor method to quickly get all the AlignmentFrames loaded.
2363 * @return an array of AlignFrame, or null if none found
2365 public static AlignFrame[] getAlignFrames()
2367 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2373 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2375 for (int i = frames.length - 1; i > -1; i--)
2377 if (frames[i] instanceof AlignFrame)
2379 avp.add((AlignFrame) frames[i]);
2381 else if (frames[i] instanceof SplitFrame)
2384 * Also check for a split frame containing an AlignFrame
2386 GSplitFrame sf = (GSplitFrame) frames[i];
2387 if (sf.getTopFrame() instanceof AlignFrame)
2389 avp.add((AlignFrame) sf.getTopFrame());
2391 if (sf.getBottomFrame() instanceof AlignFrame)
2393 avp.add((AlignFrame) sf.getBottomFrame());
2397 if (avp.size() == 0)
2401 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2406 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2410 public GStructureViewer[] getJmols()
2412 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2418 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2420 for (int i = frames.length - 1; i > -1; i--)
2422 if (frames[i] instanceof AppJmol)
2424 GStructureViewer af = (GStructureViewer) frames[i];
2428 if (avp.size() == 0)
2432 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2437 * Add Groovy Support to Jalview
2439 public void groovyShell_actionPerformed(ActionEvent e)
2441 // use reflection to avoid creating compilation dependency.
2442 if (!jalview.bin.Cache.groovyJarsPresent())
2446 .getString("error.implementation_error_cannot_create_groovyshell"));
2450 Class<?> gcClass = Desktop.class.getClassLoader().loadClass(
2451 "groovy.ui.Console");
2452 Constructor<?> gccons = gcClass.getConstructor();
2453 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2455 { String.class, Object.class });
2456 java.lang.reflect.Method run = gcClass.getMethod("run");
2457 Object gc = gccons.newInstance();
2458 setvar.invoke(gc, new Object[]
2459 { "Jalview", this });
2461 } catch (Exception ex)
2463 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2464 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2466 MessageManager.getString("label.couldnt_create_groovy_shell"),
2467 MessageManager.getString("label.groovy_support_failed"),
2468 JOptionPane.ERROR_MESSAGE);
2473 * Progress bars managed by the IProgressIndicator method.
2475 private Hashtable<Long, JPanel> progressBars;
2477 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2482 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2484 public void setProgressBar(String message, long id)
2486 if (progressBars == null)
2488 progressBars = new Hashtable<Long, JPanel>();
2489 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2492 if (progressBars.get(new Long(id)) != null)
2494 JPanel progressPanel = progressBars.remove(new Long(id));
2495 if (progressBarHandlers.contains(new Long(id)))
2497 progressBarHandlers.remove(new Long(id));
2499 removeProgressPanel(progressPanel);
2503 progressBars.put(new Long(id), addProgressPanel(message));
2510 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2511 * jalview.gui.IProgressIndicatorHandler)
2513 public void registerHandler(final long id,
2514 final IProgressIndicatorHandler handler)
2516 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2520 .getString("error.call_setprogressbar_before_registering_handler"));
2522 progressBarHandlers.put(new Long(id), handler);
2523 final JPanel progressPanel = progressBars.get(new Long(id));
2524 if (handler.canCancel())
2526 JButton cancel = new JButton(
2527 MessageManager.getString("action.cancel"));
2528 final IProgressIndicator us = this;
2529 cancel.addActionListener(new ActionListener()
2532 public void actionPerformed(ActionEvent e)
2534 handler.cancelActivity(id);
2535 us.setProgressBar(MessageManager.formatMessage(
2536 "label.cancelled_params", new Object[]
2537 { ((JLabel) progressPanel.getComponent(0)).getText() }),
2541 progressPanel.add(cancel, BorderLayout.EAST);
2547 * @return true if any progress bars are still active
2550 public boolean operationInProgress()
2552 if (progressBars != null && progressBars.size() > 0)
2560 * This will return the first AlignFrame holding the given viewport instance. It
2561 * will break if there are more than one AlignFrames viewing a particular av.
2564 * @return alignFrame for viewport
2566 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2568 if (desktop != null)
2570 AlignmentPanel[] aps = getAlignmentPanels(viewport
2571 .getSequenceSetId());
2572 for (int panel = 0; aps != null && panel < aps.length; panel++)
2574 if (aps[panel] != null && aps[panel].av == viewport)
2576 return aps[panel].alignFrame;
2583 public VamsasApplication getVamsasApplication()
2590 * flag set if jalview GUI is being operated programmatically
2592 private boolean inBatchMode = false;
2595 * check if jalview GUI is being operated programmatically
2597 * @return inBatchMode
2599 public boolean isInBatchMode()
2605 * set flag if jalview GUI is being operated programmatically
2607 * @param inBatchMode
2609 public void setInBatchMode(boolean inBatchMode)
2611 this.inBatchMode = inBatchMode;
2614 public void startServiceDiscovery()
2616 startServiceDiscovery(false);
2619 public void startServiceDiscovery(boolean blocking)
2621 boolean alive = true;
2622 Thread t0 = null, t1 = null, t2 = null;
2623 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2626 // todo: changesupport handlers need to be transferred
2627 if (discoverer == null)
2629 discoverer = new jalview.ws.jws1.Discoverer();
2630 // register PCS handler for desktop.
2631 discoverer.addPropertyChangeListener(changeSupport);
2633 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2634 // until we phase out completely
2635 (t0 = new Thread(discoverer)).start();
2638 // ENFIN services are EOLed as of Jalview 2.8.1 release
2643 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2645 // EnfinEnvision web service menu entries are rebuild every time the
2646 // menu is shown, so no changeSupport events are needed.
2647 jalview.ws.EnfinEnvision2OneWay.getInstance();
2648 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2651 } catch (Exception e)
2654 .info("Exception when trying to launch Envision2 workflow discovery.",
2656 Cache.log.info(e.getStackTrace());
2660 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2662 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2664 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2666 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2672 // TODO: do rest service discovery
2681 } catch (Exception e)
2684 alive = (t1 != null && t1.isAlive())
2685 || (t2 != null && t2.isAlive())
2686 || (t3 != null && t3.isAlive())
2687 || (t0 != null && t0.isAlive());
2693 * called to check if the service discovery process completed successfully.
2697 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2699 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2701 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2702 .getErrorMessages();
2705 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2707 if (serviceChangedDialog == null)
2709 // only run if we aren't already displaying one of these.
2710 addDialogThread(serviceChangedDialog = new Runnable()
2716 * JalviewDialog jd =new JalviewDialog() {
2718 * @Override protected void cancelPressed() { // TODO
2719 * Auto-generated method stub
2721 * }@Override protected void okPressed() { // TODO
2722 * Auto-generated method stub
2724 * }@Override protected void raiseClosed() { // TODO
2725 * Auto-generated method stub
2727 * } }; jd.initDialogFrame(new
2728 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2729 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2730 * + " or mis-configured HTTP proxy settings.<br/>" +
2731 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2733 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2734 * ), true, true, "Web Service Configuration Problem", 450,
2737 * jd.waitForInput();
2743 "<html><table width=\"450\"><tr><td>"
2745 + "</td></tr></table>"
2746 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2747 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2748 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2749 + " Tools->Preferences dialog box to change them.</p></html>"),
2750 "Web Service Configuration Problem",
2751 JOptionPane.DEFAULT_OPTION,
2752 JOptionPane.ERROR_MESSAGE);
2753 serviceChangedDialog = null;
2762 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2769 private Runnable serviceChangedDialog = null;
2772 * start a thread to open a URL in the configured browser. Pops up a warning
2773 * dialog to the user if there is an exception when calling out to the browser
2778 public static void showUrl(final String url)
2780 showUrl(url, Desktop.instance);
2784 * Like showUrl but allows progress handler to be specified
2788 * (null) or object implementing IProgressIndicator
2790 public static void showUrl(final String url,
2791 final IProgressIndicator progress)
2793 new Thread(new Runnable()
2799 if (progress != null)
2801 progress.setProgressBar(MessageManager.formatMessage(
2802 "status.opening_params", new Object[]
2803 { url }), this.hashCode());
2805 jalview.util.BrowserLauncher.openURL(url);
2806 } catch (Exception ex)
2808 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2810 .getString("label.web_browser_not_found_unix"),
2811 MessageManager.getString("label.web_browser_not_found"),
2812 JOptionPane.WARNING_MESSAGE);
2814 ex.printStackTrace();
2816 if (progress != null)
2818 progress.setProgressBar(null, this.hashCode());
2824 public static WsParamSetManager wsparamManager = null;
2826 public static ParamManager getUserParameterStore()
2828 if (wsparamManager == null)
2830 wsparamManager = new WsParamSetManager();
2832 return wsparamManager;
2836 * static hyperlink handler proxy method for use by Jalview's internal windows
2840 public static void hyperlinkUpdate(HyperlinkEvent e)
2842 if (e.getEventType() == EventType.ACTIVATED)
2847 url = e.getURL().toString();
2848 Desktop.showUrl(url);
2849 } catch (Exception x)
2853 if (Cache.log != null)
2855 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2859 System.err.println("Couldn't handle string " + url
2863 // ignore any exceptions due to dud links.
2870 * single thread that handles display of dialogs to user.
2872 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2875 * flag indicating if dialogExecutor should try to acquire a permit
2877 private volatile boolean dialogPause = true;
2882 private java.util.concurrent.Semaphore block = new Semaphore(0);
2885 * add another dialog thread to the queue
2889 public void addDialogThread(final Runnable prompter)
2891 dialogExecutor.submit(new Runnable()
2900 } catch (InterruptedException x)
2905 if (instance == null)
2911 SwingUtilities.invokeAndWait(prompter);
2912 } catch (Exception q)
2914 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2920 public void startDialogQueue()
2922 // set the flag so we don't pause waiting for another permit and semaphore
2923 // the current task to begin
2924 dialogPause = false;
2929 protected void snapShotWindow_actionPerformed(ActionEvent e)
2933 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2934 "View of Desktop", getWidth(), getHeight(), of = new File(
2935 "Jalview_snapshot" + System.currentTimeMillis()
2936 + ".eps"), "View of desktop");
2939 paintAll(im.getGraphics());
2941 } catch (Exception q)
2943 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
2947 Cache.log.info("Successfully written snapshot to file "
2948 + of.getAbsolutePath());
2952 * Explode the views in the given frame into separate AlignFrame windows.
2956 public void explodeViews(SplitFrame sf)
2958 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
2959 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
2960 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
2962 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
2964 int viewCount = topPanels.size();
2971 * Processing in reverse order works, forwards order leaves the first panels
2972 * not visible. I don't know why!
2974 for (int i = viewCount - 1; i >= 0; i--)
2977 * Make new top and bottom frames. These take over the respective
2978 * AlignmentPanel objects, including their AlignmentViewports, so the
2979 * cdna/protein relationships between the viewports is carried over to the
2982 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
2983 AlignFrame newTopFrame = new AlignFrame(topPanel);
2984 newTopFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
2985 AlignFrame.DEFAULT_HEIGHT));
2986 newTopFrame.setVisible(true);
2987 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
2988 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
2989 newBottomFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
2990 AlignFrame.DEFAULT_HEIGHT));
2991 newBottomFrame.setVisible(true);
2992 topPanel.av.setGatherViewsHere(false);
2993 bottomPanel.av.setGatherViewsHere(false);
2994 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
2996 // either panel may hold previous exploded frame geometry
2997 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
2998 .getExplodedGeometry();
2999 if (geometry != null)
3001 splitFrame.setBounds(geometry);
3003 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3007 * Clear references to the panels (now relocated in the new SplitFrames)
3008 * before closing the old SplitFrame.
3011 bottomPanels.clear();
3016 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3017 * back into the given SplitFrame as additional views. Note that the gathered
3018 * frames may themselves have multiple views.
3022 public void gatherViews(GSplitFrame source)
3024 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3025 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3026 myTopFrame.viewport.setExplodedGeometry(source.getBounds());
3027 myBottomFrame.viewport.setExplodedGeometry(source.getBounds());
3028 myTopFrame.viewport.setGatherViewsHere(true);
3029 myBottomFrame.viewport.setGatherViewsHere(true);
3030 String topViewId = myTopFrame.viewport.getSequenceSetId();
3031 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3033 JInternalFrame[] frames = desktop.getAllFrames();
3034 for (JInternalFrame frame : frames)
3036 if (frame instanceof SplitFrame && frame != source)
3038 SplitFrame sf = (SplitFrame) frame;
3039 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3040 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3041 boolean gatherThis = false;
3042 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3044 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3045 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3046 if (topViewId.equals(topPanel.av.getSequenceSetId())
3047 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3050 topPanel.av.setGatherViewsHere(false);
3051 bottomPanel.av.setGatherViewsHere(false);
3052 // both panels refer to the same split frame geometry
3053 Rectangle position = sf.getBounds();
3054 topPanel.av.setExplodedGeometry(position);
3055 bottomPanel.av.setExplodedGeometry(position);
3056 myTopFrame.addAlignmentPanel(topPanel, false);
3057 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3063 topFrame.getAlignPanels().clear();
3064 bottomFrame.getAlignPanels().clear();
3071 * The dust settles...give focus to the tab we did this from.
3073 myTopFrame.setDisplayedView(myTopFrame.alignPanel);