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 jalview.api.AlignViewportI;
24 import jalview.api.AlignmentViewPanel;
25 import jalview.bin.Cache;
26 import jalview.io.FileLoader;
27 import jalview.io.FormatAdapter;
28 import jalview.io.IdentifyFile;
29 import jalview.io.JalviewFileChooser;
30 import jalview.io.JalviewFileView;
31 import jalview.jbgui.GSplitFrame;
32 import jalview.jbgui.GStructureViewer;
33 import jalview.structure.StructureSelectionManager;
34 import jalview.util.ImageMaker;
35 import jalview.util.MessageManager;
36 import jalview.util.Platform;
37 import jalview.viewmodel.AlignmentViewport;
38 import jalview.ws.params.ParamManager;
40 import java.awt.BorderLayout;
41 import java.awt.Color;
42 import java.awt.Dimension;
43 import java.awt.FontMetrics;
44 import java.awt.Graphics;
45 import java.awt.GridLayout;
46 import java.awt.Point;
47 import java.awt.Rectangle;
48 import java.awt.Toolkit;
49 import java.awt.datatransfer.Clipboard;
50 import java.awt.datatransfer.ClipboardOwner;
51 import java.awt.datatransfer.DataFlavor;
52 import java.awt.datatransfer.Transferable;
53 import java.awt.dnd.DnDConstants;
54 import java.awt.dnd.DropTargetDragEvent;
55 import java.awt.dnd.DropTargetDropEvent;
56 import java.awt.dnd.DropTargetEvent;
57 import java.awt.dnd.DropTargetListener;
58 import java.awt.event.ActionEvent;
59 import java.awt.event.ActionListener;
60 import java.awt.event.FocusEvent;
61 import java.awt.event.FocusListener;
62 import java.awt.event.MouseAdapter;
63 import java.awt.event.MouseEvent;
64 import java.awt.event.MouseListener;
65 import java.awt.event.WindowAdapter;
66 import java.awt.event.WindowEvent;
67 import java.beans.PropertyChangeEvent;
68 import java.beans.PropertyChangeListener;
69 import java.beans.PropertyVetoException;
70 import java.io.BufferedInputStream;
72 import java.io.FileOutputStream;
73 import java.lang.reflect.Constructor;
75 import java.util.ArrayList;
76 import java.util.Hashtable;
77 import java.util.List;
78 import java.util.StringTokenizer;
79 import java.util.Vector;
80 import java.util.concurrent.ExecutorService;
81 import java.util.concurrent.Executors;
82 import java.util.concurrent.Semaphore;
84 import javax.swing.DefaultDesktopManager;
85 import javax.swing.DesktopManager;
86 import javax.swing.JButton;
87 import javax.swing.JComboBox;
88 import javax.swing.JComponent;
89 import javax.swing.JDesktopPane;
90 import javax.swing.JFrame;
91 import javax.swing.JInternalFrame;
92 import javax.swing.JLabel;
93 import javax.swing.JMenuItem;
94 import javax.swing.JOptionPane;
95 import javax.swing.JPanel;
96 import javax.swing.JPopupMenu;
97 import javax.swing.JProgressBar;
98 import javax.swing.SwingUtilities;
99 import javax.swing.event.HyperlinkEvent;
100 import javax.swing.event.HyperlinkEvent.EventType;
101 import javax.swing.event.MenuEvent;
102 import javax.swing.event.MenuListener;
109 * @version $Revision: 1.155 $
111 public class Desktop extends jalview.jbgui.GDesktop implements
112 DropTargetListener, ClipboardOwner, IProgressIndicator,
113 jalview.api.StructureSelectionManagerProvider
116 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
119 * news reader - null if it was never started.
121 private BlogReader jvnews = null;
123 private File projectFile;
127 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
129 public void addJalviewPropertyChangeListener(
130 PropertyChangeListener listener)
132 changeSupport.addJalviewPropertyChangeListener(listener);
136 * @param propertyName
138 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
139 * java.beans.PropertyChangeListener)
141 public void addJalviewPropertyChangeListener(String propertyName,
142 PropertyChangeListener listener)
144 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
148 * @param propertyName
150 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
151 * java.beans.PropertyChangeListener)
153 public void removeJalviewPropertyChangeListener(String propertyName,
154 PropertyChangeListener listener)
156 changeSupport.removeJalviewPropertyChangeListener(propertyName,
160 /** Singleton Desktop instance */
161 public static Desktop instance;
163 public static MyDesktopPane desktop;
165 static int openFrameCount = 0;
167 static final int xOffset = 30;
169 static final int yOffset = 30;
171 private static AlignFrame currentAlignFrame;
173 public static jalview.ws.jws1.Discoverer discoverer;
175 public static Object[] jalviewClipboard;
177 public static boolean internalCopy = false;
179 static int fileLoadingCount = 0;
181 class MyDesktopManager implements DesktopManager
184 private DesktopManager delegate;
186 public MyDesktopManager(DesktopManager delegate)
188 this.delegate = delegate;
191 public void activateFrame(JInternalFrame f)
195 delegate.activateFrame(f);
196 } catch (NullPointerException npe)
198 Point p = getMousePosition();
199 instance.showPasteMenu(p.x, p.y);
203 public void beginDraggingFrame(JComponent f)
205 delegate.beginDraggingFrame(f);
208 public void beginResizingFrame(JComponent f, int direction)
210 delegate.beginResizingFrame(f, direction);
213 public void closeFrame(JInternalFrame f)
215 delegate.closeFrame(f);
218 public void deactivateFrame(JInternalFrame f)
220 delegate.deactivateFrame(f);
223 public void deiconifyFrame(JInternalFrame f)
225 delegate.deiconifyFrame(f);
228 public void dragFrame(JComponent f, int newX, int newY)
234 delegate.dragFrame(f, newX, newY);
237 public void endDraggingFrame(JComponent f)
239 delegate.endDraggingFrame(f);
242 public void endResizingFrame(JComponent f)
244 delegate.endResizingFrame(f);
247 public void iconifyFrame(JInternalFrame f)
249 delegate.iconifyFrame(f);
252 public void maximizeFrame(JInternalFrame f)
254 delegate.maximizeFrame(f);
257 public void minimizeFrame(JInternalFrame f)
259 delegate.minimizeFrame(f);
262 public void openFrame(JInternalFrame f)
264 delegate.openFrame(f);
268 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
275 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
278 public void setBoundsForFrame(JComponent f, int newX, int newY,
279 int newWidth, int newHeight)
281 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
284 // All other methods, simply delegate
289 * Creates a new Desktop object.
294 * A note to implementors. It is ESSENTIAL that any activities that might
295 * block are spawned off as threads rather than waited for during this
299 doVamsasClientCheck();
301 doConfigureStructurePrefs();
302 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
303 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
304 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
306 boolean showjconsole = jalview.bin.Cache.getDefault(
307 "SHOW_JAVA_CONSOLE", false);
308 desktop = new MyDesktopPane(selmemusage);
309 if (Platform.isAMac())
311 desktop.setDoubleBuffered(false);
313 showMemusage.setSelected(selmemusage);
314 desktop.setBackground(Color.white);
315 getContentPane().setLayout(new BorderLayout());
316 // alternate config - have scrollbars - see notes in JAL-153
317 // JScrollPane sp = new JScrollPane();
318 // sp.getViewport().setView(desktop);
319 // getContentPane().add(sp, BorderLayout.CENTER);
320 getContentPane().add(desktop, BorderLayout.CENTER);
321 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
323 // This line prevents Windows Look&Feel resizing all new windows to maximum
324 // if previous window was maximised
325 desktop.setDesktopManager(new MyDesktopManager(
326 new DefaultDesktopManager()));
328 Rectangle dims = getLastKnownDimensions("");
335 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
336 setBounds((screenSize.width - 900) / 2,
337 (screenSize.height - 650) / 2, 900, 650);
339 jconsole = new Console(this, showjconsole);
340 // add essential build information
341 jconsole.setHeader("Jalview Version: "
342 + jalview.bin.Cache.getProperty("VERSION") + "\n"
343 + "Jalview Installation: "
344 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
345 + "\n" + "Build Date: "
346 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
347 + "Java version: " + System.getProperty("java.version") + "\n"
348 + System.getProperty("os.arch") + " "
349 + System.getProperty("os.name") + " "
350 + System.getProperty("os.version"));
352 showConsole(showjconsole);
354 showNews.setVisible(false);
356 this.addWindowListener(new WindowAdapter()
358 public void windowClosing(WindowEvent evt)
365 this.addMouseListener(ma = new MouseAdapter()
367 public void mousePressed(MouseEvent evt)
369 if (SwingUtilities.isRightMouseButton(evt))
371 showPasteMenu(evt.getX(), evt.getY());
375 desktop.addMouseListener(ma);
377 this.addFocusListener(new FocusListener()
381 public void focusLost(FocusEvent e)
383 // TODO Auto-generated method stub
388 public void focusGained(FocusEvent e)
390 Cache.log.debug("Relaying windows after focus gain");
391 // make sure that we sort windows properly after we gain focus
392 instance.relayerWindows();
395 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
396 // Spawn a thread that shows the splashscreen
397 SwingUtilities.invokeLater(new Runnable()
406 // Thread off a new instance of the file chooser - this reduces the time it
407 // takes to open it later on.
408 new Thread(new Runnable()
412 Cache.log.debug("Filechooser init thread started.");
413 new JalviewFileChooser(
414 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
415 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
416 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
417 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
418 Cache.log.debug("Filechooser init thread finished.");
421 // Add the service change listener
422 changeSupport.addJalviewPropertyChangeListener("services",
423 new PropertyChangeListener()
427 public void propertyChange(PropertyChangeEvent evt)
429 Cache.log.debug("Firing service changed event for "
430 + evt.getNewValue());
431 JalviewServicesChanged(evt);
437 public void doConfigureStructurePrefs()
439 // configure services
440 StructureSelectionManager ssm = StructureSelectionManager
441 .getStructureSelectionManager(this);
442 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
444 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
445 Preferences.ADD_TEMPFACT_ANN, true));
446 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
447 Preferences.STRUCT_FROM_PDB, true));
448 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
449 Preferences.USE_RNAVIEW, true));
453 ssm.setAddTempFacAnnot(false);
454 ssm.setProcessSecondaryStructure(false);
455 ssm.setSecStructServices(false);
459 public void checkForNews()
461 final Desktop me = this;
462 // Thread off the news reader, in case there are connection problems.
463 addDialogThread(new Runnable()
468 Cache.log.debug("Starting news thread.");
470 jvnews = new BlogReader(me);
471 showNews.setVisible(true);
472 Cache.log.debug("Completed news thread.");
478 protected void showNews_actionPerformed(ActionEvent e)
480 showNews(showNews.isSelected());
483 void showNews(boolean visible)
486 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
487 showNews.setSelected(visible);
488 if (visible && !jvnews.isVisible())
490 new Thread(new Runnable()
495 long now = System.currentTimeMillis();
496 Desktop.instance.setProgressBar(
497 MessageManager.getString("status.refreshing_news"), now);
498 jvnews.refreshNews();
499 Desktop.instance.setProgressBar(null, now);
508 * recover the last known dimensions for a jalview window
511 * - empty string is desktop, all other windows have unique prefix
512 * @return null or last known dimensions scaled to current geometry (if last
513 * window geom was known)
515 Rectangle getLastKnownDimensions(String windowName)
517 // TODO: lock aspect ratio for scaling desktop Bug #0058199
518 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
519 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
520 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
521 String width = jalview.bin.Cache.getProperty(windowName
523 String height = jalview.bin.Cache.getProperty(windowName
525 if ((x != null) && (y != null) && (width != null) && (height != null))
527 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
528 .parseInt(width), ih = Integer.parseInt(height);
529 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
531 // attempt #1 - try to cope with change in screen geometry - this
532 // version doesn't preserve original jv aspect ratio.
533 // take ratio of current screen size vs original screen size.
534 double sw = ((1f * screenSize.width) / (1f * Integer
535 .parseInt(jalview.bin.Cache
536 .getProperty("SCREENGEOMETRY_WIDTH"))));
537 double sh = ((1f * screenSize.height) / (1f * Integer
538 .parseInt(jalview.bin.Cache
539 .getProperty("SCREENGEOMETRY_HEIGHT"))));
540 // rescale the bounds depending upon the current screen geometry.
541 ix = (int) (ix * sw);
542 iw = (int) (iw * sw);
543 iy = (int) (iy * sh);
544 ih = (int) (ih * sh);
545 while (ix >= screenSize.width)
547 jalview.bin.Cache.log
548 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
549 ix -= screenSize.width;
551 while (iy >= screenSize.height)
553 jalview.bin.Cache.log
554 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
555 iy -= screenSize.height;
557 jalview.bin.Cache.log.debug("Got last known dimensions for "
558 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
561 // return dimensions for new instance
562 return new Rectangle(ix, iy, iw, ih);
567 private void doVamsasClientCheck()
569 if (jalview.bin.Cache.vamsasJarsPresent())
571 setupVamsasDisconnectedGui();
572 VamsasMenu.setVisible(true);
573 final Desktop us = this;
574 VamsasMenu.addMenuListener(new MenuListener()
576 // this listener remembers when the menu was first selected, and
577 // doesn't rebuild the session list until it has been cleared and
579 boolean refresh = true;
581 public void menuCanceled(MenuEvent e)
586 public void menuDeselected(MenuEvent e)
591 public void menuSelected(MenuEvent e)
595 us.buildVamsasStMenu();
600 vamsasStart.setVisible(true);
604 void showPasteMenu(int x, int y)
606 JPopupMenu popup = new JPopupMenu();
607 JMenuItem item = new JMenuItem(
608 MessageManager.getString("label.paste_new_window"));
609 item.addActionListener(new ActionListener()
611 public void actionPerformed(ActionEvent evt)
618 popup.show(this, x, y);
625 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
626 Transferable contents = c.getContents(this);
628 if (contents != null)
630 String file = (String) contents
631 .getTransferData(DataFlavor.stringFlavor);
633 String format = new IdentifyFile().Identify(file,
634 FormatAdapter.PASTE);
636 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
639 } catch (Exception ex)
642 .println("Unable to paste alignment from system clipboard:\n"
648 * Adds and opens the given frame to the desktop
659 public static synchronized void addInternalFrame(
660 final JInternalFrame frame, String title, int w, int h)
662 addInternalFrame(frame, title, true, w, h, true);
666 * Add an internal frame to the Jalview desktop
673 * When true, display frame immediately, otherwise, caller must call
674 * setVisible themselves.
680 public static synchronized void addInternalFrame(
681 final JInternalFrame frame, String title, boolean makeVisible,
684 addInternalFrame(frame, title, makeVisible, w, h, true);
688 * Add an internal frame to the Jalview desktop and make it visible
701 public static synchronized void addInternalFrame(
702 final JInternalFrame frame, String title, int w, int h,
705 addInternalFrame(frame, title, true, w, h, resizable);
709 * Add an internal frame to the Jalview desktop
716 * When true, display frame immediately, otherwise, caller must call
717 * setVisible themselves.
725 public static synchronized void addInternalFrame(
726 final JInternalFrame frame, String title, boolean makeVisible,
727 int w, int h, boolean resizable)
730 // TODO: allow callers to determine X and Y position of frame (eg. via
732 // TODO: consider fixing method to update entries in the window submenu with
733 // the current window title
735 frame.setTitle(title);
736 if (frame.getWidth() < 1 || frame.getHeight() < 1)
740 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
741 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
742 // IF JALVIEW IS RUNNING HEADLESS
743 // ///////////////////////////////////////////////
745 || (System.getProperty("java.awt.headless") != null && System
746 .getProperty("java.awt.headless").equals("true")))
753 frame.setVisible(makeVisible);
754 frame.setClosable(true);
755 frame.setResizable(resizable);
756 frame.setMaximizable(resizable);
757 frame.setIconifiable(resizable);
758 if (Platform.isAMac())
760 frame.setIconifiable(false);
761 frame.setFrameIcon(null);
762 // frame.setDesktopIcon(null);
763 frame.setDoubleBuffered(false);
765 if (frame.getX() < 1 && frame.getY() < 1)
767 frame.setLocation(xOffset * openFrameCount, yOffset
768 * ((openFrameCount - 1) % 10) + yOffset);
771 final JMenuItem menuItem = new JMenuItem(title);
772 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
774 public void internalFrameActivated(
775 javax.swing.event.InternalFrameEvent evt)
777 JInternalFrame itf = desktop.getSelectedFrame();
785 public void internalFrameClosed(
786 javax.swing.event.InternalFrameEvent evt)
788 PaintRefresher.RemoveComponent(frame);
790 windowMenu.remove(menuItem);
791 JInternalFrame itf = desktop.getSelectedFrame();
800 menuItem.addActionListener(new ActionListener()
802 public void actionPerformed(ActionEvent e)
806 frame.setSelected(true);
807 frame.setIcon(false);
808 } catch (java.beans.PropertyVetoException ex)
814 menuItem.addMouseListener(new MouseListener()
818 public void mouseReleased(MouseEvent e)
823 public void mousePressed(MouseEvent e)
828 public void mouseExited(MouseEvent e)
832 frame.setSelected(false);
833 } catch (PropertyVetoException e1)
839 public void mouseEntered(MouseEvent e)
843 frame.setSelected(true);
844 } catch (PropertyVetoException e1)
850 public void mouseClicked(MouseEvent e)
856 windowMenu.add(menuItem);
862 frame.setSelected(true);
863 frame.requestFocus();
864 } catch (java.beans.PropertyVetoException ve)
866 } catch (java.lang.ClassCastException cex)
869 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
874 public void lostOwnership(Clipboard clipboard, Transferable contents)
878 Desktop.jalviewClipboard = null;
881 internalCopy = false;
884 public void dragEnter(DropTargetDragEvent evt)
888 public void dragExit(DropTargetEvent evt)
892 public void dragOver(DropTargetDragEvent evt)
897 public void dropActionChanged(DropTargetDragEvent evt)
907 public void drop(DropTargetDropEvent evt)
909 boolean success = true;
910 Transferable t = evt.getTransferable();
911 java.util.List files = null;
912 java.util.List protocols = null;
916 DataFlavor uriListFlavor = new DataFlavor(
917 "text/uri-list;class=java.lang.String");
918 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
920 // Works on Windows and MacOSX
921 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
922 files = (java.util.List) t
923 .getTransferData(DataFlavor.javaFileListFlavor);
925 else if (t.isDataFlavorSupported(uriListFlavor))
927 // This is used by Unix drag system
928 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
929 String data = (String) t.getTransferData(uriListFlavor);
930 files = new java.util.ArrayList(1);
931 protocols = new java.util.ArrayList(1);
932 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
933 data, "\r\n"); st.hasMoreTokens();)
935 String s = st.nextToken();
936 if (s.startsWith("#"))
938 // the line is a comment (as per the RFC 2483)
941 java.net.URI uri = new java.net.URI(s);
942 if (uri.getScheme().toLowerCase().startsWith("http"))
944 protocols.add(FormatAdapter.URL);
945 files.add(uri.toString());
949 // otherwise preserve old behaviour: catch all for file objects
950 java.io.File file = new java.io.File(uri);
951 protocols.add(FormatAdapter.FILE);
952 files.add(file.toString());
956 } catch (Exception e)
965 for (int i = 0; i < files.size(); i++)
967 String file = files.get(i).toString();
968 String protocol = (protocols == null) ? FormatAdapter.FILE
969 : (String) protocols.get(i);
970 String format = null;
972 if (file.endsWith(".jar"))
979 format = new IdentifyFile().Identify(file, protocol);
982 new FileLoader().LoadFile(file, protocol, format);
985 } catch (Exception ex)
990 evt.dropComplete(success); // need this to ensure input focus is properly
991 // transfered to any new windows created
1001 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1003 JalviewFileChooser chooser = new JalviewFileChooser(
1004 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1005 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1006 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1007 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1009 chooser.setFileView(new JalviewFileView());
1010 chooser.setDialogTitle(MessageManager
1011 .getString("label.open_local_file"));
1012 chooser.setToolTipText(MessageManager.getString("action.open"));
1014 int value = chooser.showOpenDialog(this);
1016 if (value == JalviewFileChooser.APPROVE_OPTION)
1018 String choice = chooser.getSelectedFile().getPath();
1019 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1020 .getSelectedFile().getParent());
1022 String format = null;
1023 if (chooser.getSelectedFormat() != null
1024 && chooser.getSelectedFormat().equals("Jalview"))
1030 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1033 if (viewport != null)
1035 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1037 // viewport.setShowSequenceFeatures(JSONFile.isSeqFeaturesEnabled());
1038 // AlignFrame af = viewport.getAlignPanel().alignFrame;
1041 // af.changeColour(JSONFile.getColourScheme());
1042 // af.setMenusForViewport();
1047 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1059 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1061 // This construct allows us to have a wider textfield
1063 JLabel label = new JLabel(
1064 MessageManager.getString("label.input_file_url"));
1065 final JComboBox history = new JComboBox();
1067 JPanel panel = new JPanel(new GridLayout(2, 1));
1070 history.setPreferredSize(new Dimension(400, 20));
1071 history.setEditable(true);
1072 history.addItem("http://www.");
1074 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1078 if (historyItems != null)
1080 st = new StringTokenizer(historyItems, "\t");
1082 while (st.hasMoreTokens())
1084 history.addItem(st.nextElement());
1088 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1089 MessageManager.getString("label.input_alignment_from_url"),
1090 JOptionPane.OK_CANCEL_OPTION);
1092 if (reply != JOptionPane.OK_OPTION)
1097 String url = history.getSelectedItem().toString();
1099 if (url.toLowerCase().endsWith(".jar"))
1101 if (viewport != null)
1103 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1108 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1113 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1115 if (format.equals("URL NOT FOUND"))
1117 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1118 MessageManager.formatMessage("label.couldnt_locate",
1119 new Object[] { url }), MessageManager
1120 .getString("label.url_not_found"),
1121 JOptionPane.WARNING_MESSAGE);
1126 if (viewport != null)
1128 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1132 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1138 * Opens the CutAndPaste window for the user to paste an alignment in to
1141 * - if not null, the pasted alignment is added to the current
1142 * alignment; if null, to a new alignment window
1145 public void inputTextboxMenuItem_actionPerformed(
1146 AlignmentViewPanel viewPanel)
1148 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1149 cap.setForInput(viewPanel);
1150 Desktop.addInternalFrame(cap,
1151 MessageManager.getString("label.cut_paste_alignmen_file"),
1161 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1163 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1164 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1166 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1167 getBounds().y, getWidth(), getHeight()));
1169 if (jconsole != null)
1171 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1172 jconsole.stopConsole();
1176 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1179 if (dialogExecutor != null)
1181 dialogExecutor.shutdownNow();
1183 closeAll_actionPerformed(null);
1187 private void storeLastKnownDimensions(String string, Rectangle jc)
1189 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1190 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1191 + " height:" + jc.height);
1193 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1194 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1195 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1196 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1206 public void aboutMenuItem_actionPerformed(ActionEvent e)
1208 // StringBuffer message = getAboutMessage(false);
1209 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1211 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1212 new Thread(new Runnable()
1216 new SplashScreen(true);
1221 public StringBuffer getAboutMessage(boolean shortv)
1223 StringBuffer message = new StringBuffer();
1224 message.append("<html>");
1227 message.append("<h1><strong>Version: "
1228 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1229 message.append("<strong>Last Updated: <em>"
1230 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1231 + "</em></strong>");
1237 message.append("<strong>Version "
1238 + jalview.bin.Cache.getProperty("VERSION")
1239 + "; last updated: "
1240 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1243 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1246 message.append("<br>...Checking latest version...</br>");
1248 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1249 .equals(jalview.bin.Cache.getProperty("VERSION")))
1251 boolean red = false;
1252 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1253 .indexOf("automated build") == -1)
1256 // Displayed when code version and jnlp version do not match and code
1257 // version is not a development build
1258 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1261 message.append("<br>!! Version "
1262 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1264 + " is available for download from "
1265 + jalview.bin.Cache.getDefault("www.jalview.org",
1266 "http://www.jalview.org") + " !!");
1269 message.append("</div>");
1272 message.append("<br>Authors: "
1274 .getDefault("AUTHORFNAMES",
1275 "The Jalview Authors (See AUTHORS file for current list)")
1276 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1277 + "<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"
1278 + "<br><br>If you use Jalview, please cite:"
1279 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1280 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1281 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1293 public void documentationMenuItem_actionPerformed(ActionEvent e)
1297 Help.showHelpWindow();
1298 } catch (Exception ex)
1304 public void closeAll_actionPerformed(ActionEvent e)
1306 JInternalFrame[] frames = desktop.getAllFrames();
1307 for (int i = 0; i < frames.length; i++)
1311 frames[i].setClosed(true);
1312 } catch (java.beans.PropertyVetoException ex)
1316 System.out.println("ALL CLOSED");
1317 if (v_client != null)
1319 // TODO clear binding to vamsas document objects on close_all
1323 * reset state of singleton objects as appropriate (clear down session state
1324 * when all windows are closed)
1326 StructureSelectionManager ssm = StructureSelectionManager
1327 .getStructureSelectionManager(this);
1335 public void raiseRelated_actionPerformed(ActionEvent e)
1337 reorderAssociatedWindows(false, false);
1341 public void minimizeAssociated_actionPerformed(ActionEvent e)
1343 reorderAssociatedWindows(true, false);
1346 void closeAssociatedWindows()
1348 reorderAssociatedWindows(false, true);
1354 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1358 protected void garbageCollect_actionPerformed(ActionEvent e)
1360 // We simply collect the garbage
1361 jalview.bin.Cache.log.debug("Collecting garbage...");
1363 jalview.bin.Cache.log.debug("Finished garbage collection.");
1370 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1374 protected void showMemusage_actionPerformed(ActionEvent e)
1376 desktop.showMemoryUsage(showMemusage.isSelected());
1383 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1387 protected void showConsole_actionPerformed(ActionEvent e)
1389 showConsole(showConsole.isSelected());
1392 Console jconsole = null;
1395 * control whether the java console is visible or not
1399 void showConsole(boolean selected)
1401 showConsole.setSelected(selected);
1402 // TODO: decide if we should update properties file
1403 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1405 jconsole.setVisible(selected);
1408 void reorderAssociatedWindows(boolean minimize, boolean close)
1410 JInternalFrame[] frames = desktop.getAllFrames();
1411 if (frames == null || frames.length < 1)
1416 AlignmentViewport source = null, target = null;
1417 if (frames[0] instanceof AlignFrame)
1419 source = ((AlignFrame) frames[0]).getCurrentView();
1421 else if (frames[0] instanceof TreePanel)
1423 source = ((TreePanel) frames[0]).getViewPort();
1425 else if (frames[0] instanceof PCAPanel)
1427 source = ((PCAPanel) frames[0]).av;
1429 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1431 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1436 for (int i = 0; i < frames.length; i++)
1439 if (frames[i] == null)
1443 if (frames[i] instanceof AlignFrame)
1445 target = ((AlignFrame) frames[i]).getCurrentView();
1447 else if (frames[i] instanceof TreePanel)
1449 target = ((TreePanel) frames[i]).getViewPort();
1451 else if (frames[i] instanceof PCAPanel)
1453 target = ((PCAPanel) frames[i]).av;
1455 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1457 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1460 if (source == target)
1466 frames[i].setClosed(true);
1470 frames[i].setIcon(minimize);
1473 frames[i].toFront();
1477 } catch (java.beans.PropertyVetoException ex)
1492 protected void preferences_actionPerformed(ActionEvent e)
1504 public void saveState_actionPerformed(ActionEvent e)
1506 JalviewFileChooser chooser = new JalviewFileChooser(
1507 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1508 new String[] { "jvp" }, new String[] { "Jalview Project" },
1511 chooser.setFileView(new JalviewFileView());
1512 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1514 int value = chooser.showSaveDialog(this);
1516 if (value == JalviewFileChooser.APPROVE_OPTION)
1518 final Desktop me = this;
1519 final java.io.File choice = chooser.getSelectedFile();
1520 setProjectFile(choice);
1522 new Thread(new Runnable()
1526 // TODO: refactor to Jalview desktop session controller action.
1527 setProgressBar(MessageManager.formatMessage(
1528 "label.saving_jalview_project",
1529 new Object[] { choice.getName() }), choice.hashCode());
1530 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1531 choice.getParent());
1532 // TODO catch and handle errors for savestate
1533 // TODO prevent user from messing with the Desktop whilst we're saving
1536 new Jalview2XML().saveState(choice);
1537 } catch (OutOfMemoryError oom)
1539 new OOMWarning("Whilst saving current state to "
1540 + choice.getName(), oom);
1541 } catch (Exception ex)
1544 "Problems whilst trying to save to " + choice.getName(),
1546 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1547 "label.error_whilst_saving_current_state_to",
1548 new Object[] { choice.getName() }), MessageManager
1549 .getString("label.couldnt_save_project"),
1550 JOptionPane.WARNING_MESSAGE);
1552 setProgressBar(null, choice.hashCode());
1558 private void setProjectFile(File choice)
1560 this.projectFile = choice;
1563 public File getProjectFile()
1565 return this.projectFile;
1575 public void loadState_actionPerformed(ActionEvent e)
1577 JalviewFileChooser chooser = new JalviewFileChooser(
1578 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1579 "jvp", "jar" }, new String[] { "Jalview Project",
1580 "Jalview Project (old)" }, "Jalview Project");
1581 chooser.setFileView(new JalviewFileView());
1582 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1584 int value = chooser.showOpenDialog(this);
1586 if (value == JalviewFileChooser.APPROVE_OPTION)
1588 final File selectedFile = chooser.getSelectedFile();
1589 setProjectFile(selectedFile);
1590 final String choice = selectedFile.getAbsolutePath();
1591 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1592 selectedFile.getParent());
1593 new Thread(new Runnable()
1598 MessageManager.formatMessage(
1599 "label.loading_jalview_project",
1600 new Object[] { choice }), choice.hashCode());
1603 new Jalview2XML().loadJalviewAlign(choice);
1604 } catch (OutOfMemoryError oom)
1606 new OOMWarning("Whilst loading project from " + choice, oom);
1607 } catch (Exception ex)
1609 Cache.log.error("Problems whilst loading project from "
1611 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1613 "label.error_whilst_loading_project_from",
1614 new Object[] { choice }), MessageManager
1615 .getString("label.couldnt_load_project"),
1616 JOptionPane.WARNING_MESSAGE);
1618 setProgressBar(null, choice.hashCode());
1625 public void inputSequence_actionPerformed(ActionEvent e)
1627 new SequenceFetcher(this);
1630 JPanel progressPanel;
1632 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1634 public void startLoading(final String fileName)
1636 if (fileLoadingCount == 0)
1638 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1639 "label.loading_file", new Object[] { fileName })));
1644 private JPanel addProgressPanel(String string)
1646 if (progressPanel == null)
1648 progressPanel = new JPanel(new GridLayout(1, 1));
1649 totalProgressCount = 0;
1650 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1652 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1653 JProgressBar progressBar = new JProgressBar();
1654 progressBar.setIndeterminate(true);
1656 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1658 thisprogress.add(progressBar, BorderLayout.CENTER);
1659 progressPanel.add(thisprogress);
1660 ((GridLayout) progressPanel.getLayout())
1661 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1662 ++totalProgressCount;
1663 instance.validate();
1664 return thisprogress;
1667 int totalProgressCount = 0;
1669 private void removeProgressPanel(JPanel progbar)
1671 if (progressPanel != null)
1673 synchronized (progressPanel)
1675 progressPanel.remove(progbar);
1676 GridLayout gl = (GridLayout) progressPanel.getLayout();
1677 gl.setRows(gl.getRows() - 1);
1678 if (--totalProgressCount < 1)
1680 this.getContentPane().remove(progressPanel);
1681 progressPanel = null;
1688 public void stopLoading()
1691 if (fileLoadingCount < 1)
1693 while (fileLoadingPanels.size() > 0)
1695 removeProgressPanel(fileLoadingPanels.remove(0));
1697 fileLoadingPanels.clear();
1698 fileLoadingCount = 0;
1703 public static int getViewCount(String alignmentId)
1705 AlignmentViewport[] aps = getViewports(alignmentId);
1706 return (aps == null) ? 0 : aps.length;
1711 * @param alignmentId
1712 * - if null, all sets are returned
1713 * @return all AlignmentPanels concerning the alignmentId sequence set
1715 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1717 if (Desktop.desktop == null)
1719 // no frames created and in headless mode
1720 // TODO: verify that frames are recoverable when in headless mode
1723 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1724 AlignFrame[] frames = getAlignFrames();
1729 for (AlignFrame af : frames)
1731 for (AlignmentPanel ap : af.alignPanels)
1733 if (alignmentId == null
1734 || alignmentId.equals(ap.av.getSequenceSetId()))
1740 if (aps.size() == 0)
1744 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1749 * get all the viewports on an alignment.
1751 * @param sequenceSetId
1752 * unique alignment id (may be null - all viewports returned in that
1754 * @return all viewports on the alignment bound to sequenceSetId
1756 public static AlignmentViewport[] getViewports(String sequenceSetId)
1758 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1759 if (desktop != null)
1761 AlignFrame[] frames = Desktop.getAlignFrames();
1763 for (AlignFrame afr : frames)
1765 if (sequenceSetId == null
1766 || afr.getViewport().getSequenceSetId()
1767 .equals(sequenceSetId))
1769 if (afr.alignPanels != null)
1771 for (AlignmentPanel ap : afr.alignPanels)
1773 if (sequenceSetId == null
1774 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1782 viewp.add(afr.getViewport());
1786 if (viewp.size() > 0)
1788 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1795 * Explode the views in the given frame into separate AlignFrame
1799 public void explodeViews(AlignFrame af)
1801 int size = af.alignPanels.size();
1807 for (int i = 0; i < size; i++)
1809 AlignmentPanel ap = af.alignPanels.get(i);
1810 AlignFrame newaf = new AlignFrame(ap);
1813 * Restore the view's last exploded frame geometry if known. Multiple
1814 * views from one exploded frame share and restore the same (frame)
1815 * position and size.
1817 Rectangle geometry = ap.av.getExplodedGeometry();
1818 if (geometry != null)
1820 newaf.setBounds(geometry);
1823 ap.av.setGatherViewsHere(false);
1825 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1826 AlignFrame.DEFAULT_HEIGHT);
1829 af.alignPanels.clear();
1830 af.closeMenuItem_actionPerformed(true);
1835 * Gather expanded views (separate AlignFrame's) with the same sequence set
1836 * identifier back in to this frame as additional views, and close the
1837 * expanded views. Note the expanded frames may themselves have multiple
1838 * views. We take the lot.
1842 public void gatherViews(AlignFrame source)
1844 source.viewport.setGatherViewsHere(true);
1845 source.viewport.setExplodedGeometry(source.getBounds());
1846 JInternalFrame[] frames = desktop.getAllFrames();
1847 String viewId = source.viewport.getSequenceSetId();
1849 for (int t = 0; t < frames.length; t++)
1851 if (frames[t] instanceof AlignFrame && frames[t] != source)
1853 AlignFrame af = (AlignFrame) frames[t];
1854 boolean gatherThis = false;
1855 for (int a = 0; a < af.alignPanels.size(); a++)
1857 AlignmentPanel ap = af.alignPanels.get(a);
1858 if (viewId.equals(ap.av.getSequenceSetId()))
1861 ap.av.setGatherViewsHere(false);
1862 ap.av.setExplodedGeometry(af.getBounds());
1863 source.addAlignmentPanel(ap, false);
1869 af.alignPanels.clear();
1870 af.closeMenuItem_actionPerformed(true);
1877 jalview.gui.VamsasApplication v_client = null;
1880 public void vamsasImport_actionPerformed(ActionEvent e)
1882 if (v_client == null)
1884 // Load and try to start a session.
1885 JalviewFileChooser chooser = new JalviewFileChooser(
1886 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1888 chooser.setFileView(new JalviewFileView());
1889 chooser.setDialogTitle(MessageManager
1890 .getString("label.open_saved_vamsas_session"));
1891 chooser.setToolTipText(MessageManager
1892 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1894 int value = chooser.showOpenDialog(this);
1896 if (value == JalviewFileChooser.APPROVE_OPTION)
1898 String fle = chooser.getSelectedFile().toString();
1899 if (!vamsasImport(chooser.getSelectedFile()))
1902 .showInternalMessageDialog(
1904 MessageManager.formatMessage(
1905 "label.couldnt_import_as_vamsas_session",
1906 new Object[] { fle }),
1908 .getString("label.vamsas_document_import_failed"),
1909 JOptionPane.ERROR_MESSAGE);
1915 jalview.bin.Cache.log
1916 .error("Implementation error - load session from a running session is not supported.");
1921 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1924 * @return true if import was a success and a session was started.
1926 public boolean vamsasImport(URL url)
1928 // TODO: create progress bar
1929 if (v_client != null)
1932 jalview.bin.Cache.log
1933 .error("Implementation error - load session from a running session is not supported.");
1939 // copy the URL content to a temporary local file
1940 // TODO: be a bit cleverer here with nio (?!)
1941 File file = File.createTempFile("vdocfromurl", ".vdj");
1942 FileOutputStream fos = new FileOutputStream(file);
1943 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1944 byte[] buffer = new byte[2048];
1946 while ((ln = bis.read(buffer)) > -1)
1948 fos.write(buffer, 0, ln);
1952 v_client = new jalview.gui.VamsasApplication(this, file,
1953 url.toExternalForm());
1954 } catch (Exception ex)
1956 jalview.bin.Cache.log.error(
1957 "Failed to create new vamsas session from contents of URL "
1961 setupVamsasConnectedGui();
1962 v_client.initial_update(); // TODO: thread ?
1963 return v_client.inSession();
1967 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1970 * @return true if import was a success and a session was started.
1972 public boolean vamsasImport(File file)
1974 if (v_client != null)
1977 jalview.bin.Cache.log
1978 .error("Implementation error - load session from a running session is not supported.");
1982 setProgressBar(MessageManager.formatMessage(
1983 "status.importing_vamsas_session_from",
1984 new Object[] { file.getName() }), file.hashCode());
1987 v_client = new jalview.gui.VamsasApplication(this, file, null);
1988 } catch (Exception ex)
1990 setProgressBar(MessageManager.formatMessage(
1991 "status.importing_vamsas_session_from",
1992 new Object[] { file.getName() }), file.hashCode());
1993 jalview.bin.Cache.log.error(
1994 "New vamsas session from existing session file failed:", ex);
1997 setupVamsasConnectedGui();
1998 v_client.initial_update(); // TODO: thread ?
1999 setProgressBar(MessageManager.formatMessage(
2000 "status.importing_vamsas_session_from",
2001 new Object[] { file.getName() }), file.hashCode());
2002 return v_client.inSession();
2005 public boolean joinVamsasSession(String mysesid)
2007 if (v_client != null)
2011 .getString("error.try_join_vamsas_session_another"));
2013 if (mysesid == null)
2016 MessageManager.getString("error.invalid_vamsas_session_id"));
2018 v_client = new VamsasApplication(this, mysesid);
2019 setupVamsasConnectedGui();
2020 v_client.initial_update();
2021 return (v_client.inSession());
2025 public void vamsasStart_actionPerformed(ActionEvent e)
2027 if (v_client == null)
2030 // we just start a default session for moment.
2032 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2033 * getProperty("LAST_DIRECTORY"));
2035 * chooser.setFileView(new JalviewFileView());
2036 * chooser.setDialogTitle("Load Vamsas file");
2037 * chooser.setToolTipText("Import");
2039 * int value = chooser.showOpenDialog(this);
2041 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2042 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2044 v_client = new VamsasApplication(this);
2045 setupVamsasConnectedGui();
2046 v_client.initial_update(); // TODO: thread ?
2050 // store current data in session.
2051 v_client.push_update(); // TODO: thread
2055 protected void setupVamsasConnectedGui()
2057 vamsasStart.setText(MessageManager.getString("label.session_update"));
2058 vamsasSave.setVisible(true);
2059 vamsasStop.setVisible(true);
2060 vamsasImport.setVisible(false); // Document import to existing session is
2061 // not possible for vamsas-client-1.0.
2064 protected void setupVamsasDisconnectedGui()
2066 vamsasSave.setVisible(false);
2067 vamsasStop.setVisible(false);
2068 vamsasImport.setVisible(true);
2069 vamsasStart.setText(MessageManager
2070 .getString("label.new_vamsas_session"));
2074 public void vamsasStop_actionPerformed(ActionEvent e)
2076 if (v_client != null)
2078 v_client.end_session();
2080 setupVamsasDisconnectedGui();
2084 protected void buildVamsasStMenu()
2086 if (v_client == null)
2088 String[] sess = null;
2091 sess = VamsasApplication.getSessionList();
2092 } catch (Exception e)
2094 jalview.bin.Cache.log.warn(
2095 "Problem getting current sessions list.", e);
2100 jalview.bin.Cache.log.debug("Got current sessions list: "
2101 + sess.length + " entries.");
2102 VamsasStMenu.removeAll();
2103 for (int i = 0; i < sess.length; i++)
2105 JMenuItem sessit = new JMenuItem();
2106 sessit.setText(sess[i]);
2107 sessit.setToolTipText(MessageManager.formatMessage(
2108 "label.connect_to_session", new Object[] { sess[i] }));
2109 final Desktop dsktp = this;
2110 final String mysesid = sess[i];
2111 sessit.addActionListener(new ActionListener()
2114 public void actionPerformed(ActionEvent e)
2116 if (dsktp.v_client == null)
2118 Thread rthr = new Thread(new Runnable()
2123 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2124 dsktp.setupVamsasConnectedGui();
2125 dsktp.v_client.initial_update();
2133 VamsasStMenu.add(sessit);
2135 // don't show an empty menu.
2136 VamsasStMenu.setVisible(sess.length > 0);
2141 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2142 VamsasStMenu.removeAll();
2143 VamsasStMenu.setVisible(false);
2148 // Not interested in the content. Just hide ourselves.
2149 VamsasStMenu.setVisible(false);
2154 public void vamsasSave_actionPerformed(ActionEvent e)
2156 if (v_client != null)
2158 JalviewFileChooser chooser = new JalviewFileChooser(
2159 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2160 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2161 new String[] { "Vamsas Document" }, "Vamsas Document");
2163 chooser.setFileView(new JalviewFileView());
2164 chooser.setDialogTitle(MessageManager
2165 .getString("label.save_vamsas_document_archive"));
2167 int value = chooser.showSaveDialog(this);
2169 if (value == JalviewFileChooser.APPROVE_OPTION)
2171 java.io.File choice = chooser.getSelectedFile();
2172 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2173 "label.saving_vamsas_doc",
2174 new Object[] { choice.getName() }));
2175 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2176 String warnmsg = null;
2177 String warnttl = null;
2180 v_client.vclient.storeDocument(choice);
2183 warnttl = "Serious Problem saving Vamsas Document";
2184 warnmsg = ex.toString();
2185 jalview.bin.Cache.log.error("Error Whilst saving document to "
2188 } catch (Exception ex)
2190 warnttl = "Problem saving Vamsas Document.";
2191 warnmsg = ex.toString();
2192 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2196 removeProgressPanel(progpanel);
2197 if (warnmsg != null)
2199 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2201 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2207 JPanel vamUpdate = null;
2210 * hide vamsas user gui bits when a vamsas document event is being handled.
2213 * true to hide gui, false to reveal gui
2215 public void setVamsasUpdate(boolean b)
2217 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2218 + (b ? "in progress" : "finished"));
2220 if (vamUpdate != null)
2222 this.removeProgressPanel(vamUpdate);
2226 vamUpdate = this.addProgressPanel(MessageManager
2227 .getString("label.updating_vamsas_session"));
2229 vamsasStart.setVisible(!b);
2230 vamsasStop.setVisible(!b);
2231 vamsasSave.setVisible(!b);
2234 public JInternalFrame[] getAllFrames()
2236 return desktop.getAllFrames();
2240 * Checks the given url to see if it gives a response indicating that the user
2241 * should be informed of a new questionnaire.
2245 public void checkForQuestionnaire(String url)
2247 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2248 // javax.swing.SwingUtilities.invokeLater(jvq);
2249 new Thread(jvq).start();
2253 * Proxy class for JDesktopPane which optionally displays the current memory
2254 * usage and highlights the desktop area with a red bar if free memory runs
2259 public class MyDesktopPane extends JDesktopPane implements Runnable
2262 private static final float ONE_MB = 1048576f;
2264 boolean showMemoryUsage = false;
2268 java.text.NumberFormat df;
2270 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2273 public MyDesktopPane(boolean showMemoryUsage)
2275 showMemoryUsage(showMemoryUsage);
2278 public void showMemoryUsage(boolean showMemory)
2280 this.showMemoryUsage = showMemory;
2283 Thread worker = new Thread(this);
2288 public boolean isShowMemoryUsage()
2290 return showMemoryUsage;
2295 df = java.text.NumberFormat.getNumberInstance();
2296 df.setMaximumFractionDigits(2);
2297 runtime = Runtime.getRuntime();
2299 while (showMemoryUsage)
2303 maxMemory = runtime.maxMemory() / ONE_MB;
2304 allocatedMemory = runtime.totalMemory() / ONE_MB;
2305 freeMemory = runtime.freeMemory() / ONE_MB;
2306 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2308 percentUsage = (totalFreeMemory / maxMemory) * 100;
2310 // if (percentUsage < 20)
2312 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2314 // instance.set.setBorder(border1);
2317 // sleep after showing usage
2319 } catch (Exception ex)
2321 ex.printStackTrace();
2327 public void paintComponent(Graphics g)
2329 if (showMemoryUsage && g != null && df != null)
2331 if (percentUsage < 20)
2333 g.setColor(Color.red);
2335 FontMetrics fm = g.getFontMetrics();
2338 g.drawString(MessageManager.formatMessage(
2339 "label.memory_stats",
2340 new Object[] { df.format(totalFreeMemory),
2341 df.format(maxMemory), df.format(percentUsage) }), 10,
2342 getHeight() - fm.getHeight());
2349 * fixes stacking order after a modal dialog to ensure windows that should be
2350 * on top actually are
2352 public void relayerWindows()
2357 protected JMenuItem groovyShell;
2359 public void doGroovyCheck()
2361 if (jalview.bin.Cache.groovyJarsPresent())
2363 groovyShell = new JMenuItem();
2364 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2365 groovyShell.addActionListener(new ActionListener()
2367 public void actionPerformed(ActionEvent e)
2369 groovyShell_actionPerformed();
2372 toolsMenu.add(groovyShell);
2373 groovyShell.setVisible(true);
2378 * Accessor method to quickly get all the AlignmentFrames loaded.
2380 * @return an array of AlignFrame, or null if none found
2382 public static AlignFrame[] getAlignFrames()
2384 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2390 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2392 for (int i = frames.length - 1; i > -1; i--)
2394 if (frames[i] instanceof AlignFrame)
2396 avp.add((AlignFrame) frames[i]);
2398 else if (frames[i] instanceof SplitFrame)
2401 * Also check for a split frame containing an AlignFrame
2403 GSplitFrame sf = (GSplitFrame) frames[i];
2404 if (sf.getTopFrame() instanceof AlignFrame)
2406 avp.add((AlignFrame) sf.getTopFrame());
2408 if (sf.getBottomFrame() instanceof AlignFrame)
2410 avp.add((AlignFrame) sf.getBottomFrame());
2414 if (avp.size() == 0)
2418 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2423 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2427 public GStructureViewer[] getJmols()
2429 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2435 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2437 for (int i = frames.length - 1; i > -1; i--)
2439 if (frames[i] instanceof AppJmol)
2441 GStructureViewer af = (GStructureViewer) frames[i];
2445 if (avp.size() == 0)
2449 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2454 * Add Groovy Support to Jalview
2456 public void groovyShell_actionPerformed()
2458 // use reflection to avoid creating compilation dependency.
2459 if (!jalview.bin.Cache.groovyJarsPresent())
2463 .getString("error.implementation_error_cannot_create_groovyshell"));
2467 Class<?> gcClass = Desktop.class.getClassLoader().loadClass(
2468 "groovy.ui.Console");
2469 Constructor<?> gccons = gcClass.getConstructor();
2470 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2471 new Class[] { String.class, Object.class });
2472 java.lang.reflect.Method run = gcClass.getMethod("run");
2473 Object gc = gccons.newInstance();
2474 setvar.invoke(gc, new Object[] { "Jalview", this });
2476 } catch (Exception ex)
2478 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2479 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2481 MessageManager.getString("label.couldnt_create_groovy_shell"),
2482 MessageManager.getString("label.groovy_support_failed"),
2483 JOptionPane.ERROR_MESSAGE);
2488 * Progress bars managed by the IProgressIndicator method.
2490 private Hashtable<Long, JPanel> progressBars;
2492 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2497 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2499 public void setProgressBar(String message, long id)
2501 if (progressBars == null)
2503 progressBars = new Hashtable<Long, JPanel>();
2504 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2507 if (progressBars.get(new Long(id)) != null)
2509 JPanel panel = progressBars.remove(new Long(id));
2510 if (progressBarHandlers.contains(new Long(id)))
2512 progressBarHandlers.remove(new Long(id));
2514 removeProgressPanel(panel);
2518 progressBars.put(new Long(id), addProgressPanel(message));
2525 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2526 * jalview.gui.IProgressIndicatorHandler)
2528 public void registerHandler(final long id,
2529 final IProgressIndicatorHandler handler)
2531 if (progressBarHandlers == null
2532 || !progressBars.containsKey(new Long(id)))
2536 .getString("error.call_setprogressbar_before_registering_handler"));
2538 progressBarHandlers.put(new Long(id), handler);
2539 final JPanel progressPanel = progressBars.get(new Long(id));
2540 if (handler.canCancel())
2542 JButton cancel = new JButton(
2543 MessageManager.getString("action.cancel"));
2544 final IProgressIndicator us = this;
2545 cancel.addActionListener(new ActionListener()
2548 public void actionPerformed(ActionEvent e)
2550 handler.cancelActivity(id);
2551 us.setProgressBar(MessageManager.formatMessage(
2552 "label.cancelled_params",
2553 new Object[] { ((JLabel) progressPanel.getComponent(0))
2557 progressPanel.add(cancel, BorderLayout.EAST);
2563 * @return true if any progress bars are still active
2566 public boolean operationInProgress()
2568 if (progressBars != null && progressBars.size() > 0)
2576 * This will return the first AlignFrame holding the given viewport instance.
2577 * It will break if there are more than one AlignFrames viewing a particular
2581 * @return alignFrame for viewport
2583 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2585 if (desktop != null)
2587 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2588 for (int panel = 0; aps != null && panel < aps.length; panel++)
2590 if (aps[panel] != null && aps[panel].av == viewport)
2592 return aps[panel].alignFrame;
2599 public VamsasApplication getVamsasApplication()
2606 * flag set if jalview GUI is being operated programmatically
2608 private boolean inBatchMode = false;
2611 * check if jalview GUI is being operated programmatically
2613 * @return inBatchMode
2615 public boolean isInBatchMode()
2621 * set flag if jalview GUI is being operated programmatically
2623 * @param inBatchMode
2625 public void setInBatchMode(boolean inBatchMode)
2627 this.inBatchMode = inBatchMode;
2630 public void startServiceDiscovery()
2632 startServiceDiscovery(false);
2635 public void startServiceDiscovery(boolean blocking)
2637 boolean alive = true;
2638 Thread t0 = null, t1 = null, t2 = null;
2639 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2642 // todo: changesupport handlers need to be transferred
2643 if (discoverer == null)
2645 discoverer = new jalview.ws.jws1.Discoverer();
2646 // register PCS handler for desktop.
2647 discoverer.addPropertyChangeListener(changeSupport);
2649 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2650 // until we phase out completely
2651 (t0 = new Thread(discoverer)).start();
2654 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2656 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2658 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2660 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2666 // TODO: do rest service discovery
2675 } catch (Exception e)
2678 alive = (t1 != null && t1.isAlive())
2679 || (t2 != null && t2.isAlive())
2680 || (t3 != null && t3.isAlive())
2681 || (t0 != null && t0.isAlive());
2687 * called to check if the service discovery process completed successfully.
2691 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2693 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2695 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2696 .getErrorMessages();
2699 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2701 if (serviceChangedDialog == null)
2703 // only run if we aren't already displaying one of these.
2704 addDialogThread(serviceChangedDialog = new Runnable()
2710 * JalviewDialog jd =new JalviewDialog() {
2712 * @Override protected void cancelPressed() { // TODO
2713 * Auto-generated method stub
2715 * }@Override protected void okPressed() { // TODO
2716 * Auto-generated method stub
2718 * }@Override protected void raiseClosed() { // TODO
2719 * Auto-generated method stub
2721 * } }; jd.initDialogFrame(new
2722 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2723 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2724 * + " or mis-configured HTTP proxy settings.<br/>" +
2725 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2727 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2728 * ), true, true, "Web Service Configuration Problem", 450,
2731 * jd.waitForInput();
2737 "<html><table width=\"450\"><tr><td>"
2739 + "</td></tr></table>"
2740 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2741 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2742 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2743 + " Tools->Preferences dialog box to change them.</p></html>"),
2744 "Web Service Configuration Problem",
2745 JOptionPane.DEFAULT_OPTION,
2746 JOptionPane.ERROR_MESSAGE);
2747 serviceChangedDialog = null;
2756 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2763 private Runnable serviceChangedDialog = null;
2766 * start a thread to open a URL in the configured browser. Pops up a warning
2767 * dialog to the user if there is an exception when calling out to the browser
2772 public static void showUrl(final String url)
2774 showUrl(url, Desktop.instance);
2778 * Like showUrl but allows progress handler to be specified
2782 * (null) or object implementing IProgressIndicator
2784 public static void showUrl(final String url,
2785 final IProgressIndicator progress)
2787 new Thread(new Runnable()
2793 if (progress != null)
2795 progress.setProgressBar(MessageManager.formatMessage(
2796 "status.opening_params", new Object[] { url }), this
2799 jalview.util.BrowserLauncher.openURL(url);
2800 } catch (Exception ex)
2802 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2804 .getString("label.web_browser_not_found_unix"),
2805 MessageManager.getString("label.web_browser_not_found"),
2806 JOptionPane.WARNING_MESSAGE);
2808 ex.printStackTrace();
2810 if (progress != null)
2812 progress.setProgressBar(null, this.hashCode());
2818 public static WsParamSetManager wsparamManager = null;
2820 public static ParamManager getUserParameterStore()
2822 if (wsparamManager == null)
2824 wsparamManager = new WsParamSetManager();
2826 return wsparamManager;
2830 * static hyperlink handler proxy method for use by Jalview's internal windows
2834 public static void hyperlinkUpdate(HyperlinkEvent e)
2836 if (e.getEventType() == EventType.ACTIVATED)
2841 url = e.getURL().toString();
2842 Desktop.showUrl(url);
2843 } catch (Exception x)
2847 if (Cache.log != null)
2849 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2853 System.err.println("Couldn't handle string " + url
2857 // ignore any exceptions due to dud links.
2864 * single thread that handles display of dialogs to user.
2866 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2869 * flag indicating if dialogExecutor should try to acquire a permit
2871 private volatile boolean dialogPause = true;
2876 private java.util.concurrent.Semaphore block = new Semaphore(0);
2879 * add another dialog thread to the queue
2883 public void addDialogThread(final Runnable prompter)
2885 dialogExecutor.submit(new Runnable()
2894 } catch (InterruptedException x)
2899 if (instance == null)
2905 SwingUtilities.invokeAndWait(prompter);
2906 } catch (Exception q)
2908 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2914 public void startDialogQueue()
2916 // set the flag so we don't pause waiting for another permit and semaphore
2917 // the current task to begin
2918 dialogPause = false;
2923 protected void snapShotWindow_actionPerformed(ActionEvent e)
2927 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2928 "View of Desktop", getWidth(), getHeight(), of = new File(
2929 "Jalview_snapshot" + System.currentTimeMillis()
2930 + ".eps"), "View of desktop");
2933 paintAll(im.getGraphics());
2935 } catch (Exception q)
2937 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
2941 Cache.log.info("Successfully written snapshot to file "
2942 + of.getAbsolutePath());
2946 * Explode the views in the given SplitFrame into separate SplitFrame windows.
2947 * This respects (remembers) any previous 'exploded geometry' i.e. the size
2948 * and location last time the view was expanded (if any). However it does not
2949 * remember the split pane divider location - this is set to match the
2950 * 'exploding' frame.
2954 public void explodeViews(SplitFrame sf)
2956 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
2957 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
2958 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
2960 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
2962 int viewCount = topPanels.size();
2969 * Processing in reverse order works, forwards order leaves the first panels
2970 * not visible. I don't know why!
2972 for (int i = viewCount - 1; i >= 0; i--)
2975 * Make new top and bottom frames. These take over the respective
2976 * AlignmentPanel objects, including their AlignmentViewports, so the
2977 * cdna/protein relationships between the viewports is carried over to the
2980 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
2981 AlignFrame newTopFrame = new AlignFrame(topPanel);
2982 newTopFrame.setSize(oldTopFrame.getSize());
2983 newTopFrame.setVisible(true);
2984 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
2985 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
2986 newBottomFrame.setSize(oldBottomFrame.getSize());
2987 newBottomFrame.setVisible(true);
2988 topPanel.av.setGatherViewsHere(false);
2989 bottomPanel.av.setGatherViewsHere(false);
2990 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
2992 // either panel may hold previous exploded frame geometry
2993 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
2994 .getExplodedGeometry();
2995 if (geometry != null)
2997 splitFrame.setBounds(geometry);
2999 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3003 * Clear references to the panels (now relocated in the new SplitFrames)
3004 * before closing the old SplitFrame.
3007 bottomPanels.clear();
3012 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3013 * back into the given SplitFrame as additional views. Note that the gathered
3014 * frames may themselves have multiple views.
3018 public void gatherViews(GSplitFrame source)
3020 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3021 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3022 myTopFrame.viewport.setExplodedGeometry(source.getBounds());
3023 myBottomFrame.viewport.setExplodedGeometry(source.getBounds());
3024 myTopFrame.viewport.setGatherViewsHere(true);
3025 myBottomFrame.viewport.setGatherViewsHere(true);
3026 String topViewId = myTopFrame.viewport.getSequenceSetId();
3027 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3029 JInternalFrame[] frames = desktop.getAllFrames();
3030 for (JInternalFrame frame : frames)
3032 if (frame instanceof SplitFrame && frame != source)
3034 SplitFrame sf = (SplitFrame) frame;
3035 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3036 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3037 boolean gatherThis = false;
3038 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3040 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3041 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3042 if (topViewId.equals(topPanel.av.getSequenceSetId())
3043 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3046 topPanel.av.setGatherViewsHere(false);
3047 bottomPanel.av.setGatherViewsHere(false);
3048 // both panels refer to the same split frame geometry
3049 Rectangle position = sf.getBounds();
3050 topPanel.av.setExplodedGeometry(position);
3051 bottomPanel.av.setExplodedGeometry(position);
3052 myTopFrame.addAlignmentPanel(topPanel, false);
3053 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3059 topFrame.getAlignPanels().clear();
3060 bottomFrame.getAlignPanels().clear();
3067 * The dust settles...give focus to the tab we did this from.
3069 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3073 public static AlignFrame getCurrentAlignFrame()
3075 return currentAlignFrame;
3078 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
3080 Desktop.currentAlignFrame = currentAlignFrame;