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.viewmodel.AlignmentViewport;
37 import jalview.ws.params.ParamManager;
39 import java.awt.BorderLayout;
40 import java.awt.Color;
41 import java.awt.Dimension;
42 import java.awt.FontMetrics;
43 import java.awt.Graphics;
44 import java.awt.GridLayout;
45 import java.awt.Point;
46 import java.awt.Rectangle;
47 import java.awt.Toolkit;
48 import java.awt.datatransfer.Clipboard;
49 import java.awt.datatransfer.ClipboardOwner;
50 import java.awt.datatransfer.DataFlavor;
51 import java.awt.datatransfer.Transferable;
52 import java.awt.dnd.DnDConstants;
53 import java.awt.dnd.DropTargetDragEvent;
54 import java.awt.dnd.DropTargetDropEvent;
55 import java.awt.dnd.DropTargetEvent;
56 import java.awt.dnd.DropTargetListener;
57 import java.awt.event.ActionEvent;
58 import java.awt.event.ActionListener;
59 import java.awt.event.FocusEvent;
60 import java.awt.event.FocusListener;
61 import java.awt.event.MouseAdapter;
62 import java.awt.event.MouseEvent;
63 import java.awt.event.MouseListener;
64 import java.awt.event.WindowAdapter;
65 import java.awt.event.WindowEvent;
66 import java.beans.PropertyChangeEvent;
67 import java.beans.PropertyChangeListener;
68 import java.beans.PropertyVetoException;
69 import java.io.BufferedInputStream;
71 import java.io.FileOutputStream;
72 import java.lang.reflect.Constructor;
74 import java.util.ArrayList;
75 import java.util.Hashtable;
76 import java.util.List;
77 import java.util.StringTokenizer;
78 import java.util.Vector;
79 import java.util.concurrent.ExecutorService;
80 import java.util.concurrent.Executors;
81 import java.util.concurrent.Semaphore;
83 import javax.swing.DefaultDesktopManager;
84 import javax.swing.DesktopManager;
85 import javax.swing.JButton;
86 import javax.swing.JComboBox;
87 import javax.swing.JComponent;
88 import javax.swing.JDesktopPane;
89 import javax.swing.JFrame;
90 import javax.swing.JInternalFrame;
91 import javax.swing.JLabel;
92 import javax.swing.JMenuItem;
93 import javax.swing.JOptionPane;
94 import javax.swing.JPanel;
95 import javax.swing.JPopupMenu;
96 import javax.swing.JProgressBar;
97 import javax.swing.SwingUtilities;
98 import javax.swing.event.HyperlinkEvent;
99 import javax.swing.event.HyperlinkEvent.EventType;
100 import javax.swing.event.MenuEvent;
101 import javax.swing.event.MenuListener;
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 AlignFrame currentAlignFrame;
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);
267 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
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 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.");
473 protected void showNews_actionPerformed(ActionEvent e)
475 showNews(showNews.isSelected());
478 void showNews(boolean visible)
481 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
482 showNews.setSelected(visible);
483 if (visible && !jvnews.isVisible())
485 new Thread(new Runnable()
490 long now = System.currentTimeMillis();
491 Desktop.instance.setProgressBar(
492 MessageManager.getString("status.refreshing_news"), now);
493 jvnews.refreshNews();
494 Desktop.instance.setProgressBar(null, now);
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)
887 public void dropActionChanged(DropTargetDragEvent evt)
897 public void drop(DropTargetDropEvent evt)
899 boolean success = true;
900 Transferable t = evt.getTransferable();
901 java.util.List files = null;
902 java.util.List protocols = null;
906 DataFlavor uriListFlavor = new DataFlavor(
907 "text/uri-list;class=java.lang.String");
908 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
910 // Works on Windows and MacOSX
911 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
912 files = (java.util.List) t
913 .getTransferData(DataFlavor.javaFileListFlavor);
915 else if (t.isDataFlavorSupported(uriListFlavor))
917 // This is used by Unix drag system
918 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
919 String data = (String) t.getTransferData(uriListFlavor);
920 files = new java.util.ArrayList(1);
921 protocols = new java.util.ArrayList(1);
922 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
923 data, "\r\n"); st.hasMoreTokens();)
925 String s = st.nextToken();
926 if (s.startsWith("#"))
928 // the line is a comment (as per the RFC 2483)
931 java.net.URI uri = new java.net.URI(s);
932 if (uri.getScheme().toLowerCase().startsWith("http"))
934 protocols.add(FormatAdapter.URL);
935 files.add(uri.toString());
939 // otherwise preserve old behaviour: catch all for file objects
940 java.io.File file = new java.io.File(uri);
941 protocols.add(FormatAdapter.FILE);
942 files.add(file.toString());
946 } catch (Exception e)
955 for (int i = 0; i < files.size(); i++)
957 String file = files.get(i).toString();
958 String protocol = (protocols == null) ? FormatAdapter.FILE
959 : (String) protocols.get(i);
960 String format = null;
962 if (file.endsWith(".jar"))
969 format = new IdentifyFile().Identify(file, protocol);
972 new FileLoader().LoadFile(file, protocol, format);
975 } catch (Exception ex)
980 evt.dropComplete(success); // need this to ensure input focus is properly
981 // transfered to any new windows created
991 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
993 JalviewFileChooser chooser = new JalviewFileChooser(
994 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
995 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
996 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
997 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
999 chooser.setFileView(new JalviewFileView());
1000 chooser.setDialogTitle(MessageManager
1001 .getString("label.open_local_file"));
1002 chooser.setToolTipText(MessageManager.getString("action.open"));
1004 int value = chooser.showOpenDialog(this);
1006 if (value == JalviewFileChooser.APPROVE_OPTION)
1008 String choice = chooser.getSelectedFile().getPath();
1009 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1010 .getSelectedFile().getParent());
1012 String format = null;
1013 if (chooser.getSelectedFormat() != null
1014 && chooser.getSelectedFormat().equals("Jalview"))
1020 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1023 if (viewport != null)
1025 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1027 // viewport.setShowSequenceFeatures(JSONFile.isSeqFeaturesEnabled());
1028 // AlignFrame af = viewport.getAlignPanel().alignFrame;
1031 // af.changeColour(JSONFile.getColourScheme());
1032 // af.setMenusForViewport();
1037 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1049 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1051 // This construct allows us to have a wider textfield
1053 JLabel label = new JLabel(
1054 MessageManager.getString("label.input_file_url"));
1055 final JComboBox history = new JComboBox();
1057 JPanel panel = new JPanel(new GridLayout(2, 1));
1060 history.setPreferredSize(new Dimension(400, 20));
1061 history.setEditable(true);
1062 history.addItem("http://www.");
1064 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1068 if (historyItems != null)
1070 st = new StringTokenizer(historyItems, "\t");
1072 while (st.hasMoreTokens())
1074 history.addItem(st.nextElement());
1078 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1079 MessageManager.getString("label.input_alignment_from_url"),
1080 JOptionPane.OK_CANCEL_OPTION);
1082 if (reply != JOptionPane.OK_OPTION)
1087 String url = history.getSelectedItem().toString();
1089 if (url.toLowerCase().endsWith(".jar"))
1091 if (viewport != null)
1093 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1098 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1103 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1105 if (format.equals("URL NOT FOUND"))
1107 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1108 MessageManager.formatMessage("label.couldnt_locate",
1110 { url }), MessageManager
1111 .getString("label.url_not_found"),
1112 JOptionPane.WARNING_MESSAGE);
1117 if (viewport != null)
1119 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1123 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1129 * Opens the CutAndPaste window for the user to paste an alignment in to
1132 * - if not null, the pasted alignment is added to the current
1133 * alignment; if null, to a new alignment window
1136 public void inputTextboxMenuItem_actionPerformed(
1137 AlignmentViewPanel viewPanel)
1139 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1140 cap.setForInput(viewPanel);
1141 Desktop.addInternalFrame(cap,
1142 MessageManager.getString("label.cut_paste_alignmen_file"),
1152 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1154 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1155 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1157 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1158 getBounds().y, getWidth(), getHeight()));
1160 if (jconsole != null)
1162 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1163 jconsole.stopConsole();
1167 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1170 if (dialogExecutor != null)
1172 dialogExecutor.shutdownNow();
1174 closeAll_actionPerformed(null);
1178 private void storeLastKnownDimensions(String string, Rectangle jc)
1180 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1181 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1182 + " height:" + jc.height);
1184 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1185 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1186 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1187 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1197 public void aboutMenuItem_actionPerformed(ActionEvent e)
1199 // StringBuffer message = getAboutMessage(false);
1200 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1202 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1203 new Thread(new Runnable()
1207 new SplashScreen(true);
1212 public StringBuffer getAboutMessage(boolean shortv)
1214 StringBuffer message = new StringBuffer();
1215 message.append("<html>");
1218 message.append("<h1><strong>Version: "
1219 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1220 message.append("<strong>Last Updated: <em>"
1221 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1222 + "</em></strong>");
1228 message.append("<strong>Version "
1229 + jalview.bin.Cache.getProperty("VERSION")
1230 + "; last updated: "
1231 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1234 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1237 message.append("<br>...Checking latest version...</br>");
1239 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1240 .equals(jalview.bin.Cache.getProperty("VERSION")))
1242 boolean red = false;
1243 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1244 .indexOf("automated build") == -1)
1247 // Displayed when code version and jnlp version do not match and code
1248 // version is not a development build
1249 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1252 message.append("<br>!! Version "
1253 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1255 + " is available for download from "
1256 + jalview.bin.Cache.getDefault("www.jalview.org",
1257 "http://www.jalview.org") + " !!");
1260 message.append("</div>");
1263 message.append("<br>Authors: "
1265 .getDefault("AUTHORFNAMES",
1266 "The Jalview Authors (See AUTHORS file for current list)")
1267 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1268 + "<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"
1269 + "<br><br>If you use Jalview, please cite:"
1270 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1271 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1272 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1284 public void documentationMenuItem_actionPerformed(ActionEvent e)
1288 Help.showHelpWindow();
1289 } catch (Exception ex)
1295 public void closeAll_actionPerformed(ActionEvent e)
1297 JInternalFrame[] frames = desktop.getAllFrames();
1298 for (int i = 0; i < frames.length; i++)
1302 frames[i].setClosed(true);
1303 } catch (java.beans.PropertyVetoException ex)
1307 System.out.println("ALL CLOSED");
1308 if (v_client != null)
1310 // TODO clear binding to vamsas document objects on close_all
1314 * reset state of singleton objects as appropriate (clear down session state
1315 * when all windows are closed)
1317 StructureSelectionManager ssm = StructureSelectionManager
1318 .getStructureSelectionManager(this);
1326 public void raiseRelated_actionPerformed(ActionEvent e)
1328 reorderAssociatedWindows(false, false);
1332 public void minimizeAssociated_actionPerformed(ActionEvent e)
1334 reorderAssociatedWindows(true, false);
1337 void closeAssociatedWindows()
1339 reorderAssociatedWindows(false, true);
1345 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1349 protected void garbageCollect_actionPerformed(ActionEvent e)
1351 // We simply collect the garbage
1352 jalview.bin.Cache.log.debug("Collecting garbage...");
1354 jalview.bin.Cache.log.debug("Finished garbage collection.");
1361 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1365 protected void showMemusage_actionPerformed(ActionEvent e)
1367 desktop.showMemoryUsage(showMemusage.isSelected());
1374 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1378 protected void showConsole_actionPerformed(ActionEvent e)
1380 showConsole(showConsole.isSelected());
1383 Console jconsole = null;
1386 * control whether the java console is visible or not
1390 void showConsole(boolean selected)
1392 showConsole.setSelected(selected);
1393 // TODO: decide if we should update properties file
1394 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1396 jconsole.setVisible(selected);
1399 void reorderAssociatedWindows(boolean minimize, boolean close)
1401 JInternalFrame[] frames = desktop.getAllFrames();
1402 if (frames == null || frames.length < 1)
1407 AlignmentViewport source = null, target = null;
1408 if (frames[0] instanceof AlignFrame)
1410 source = ((AlignFrame) frames[0]).getCurrentView();
1412 else if (frames[0] instanceof TreePanel)
1414 source = ((TreePanel) frames[0]).getViewPort();
1416 else if (frames[0] instanceof PCAPanel)
1418 source = ((PCAPanel) frames[0]).av;
1420 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1422 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1427 for (int i = 0; i < frames.length; i++)
1430 if (frames[i] == null)
1434 if (frames[i] instanceof AlignFrame)
1436 target = ((AlignFrame) frames[i]).getCurrentView();
1438 else if (frames[i] instanceof TreePanel)
1440 target = ((TreePanel) frames[i]).getViewPort();
1442 else if (frames[i] instanceof PCAPanel)
1444 target = ((PCAPanel) frames[i]).av;
1446 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1448 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1451 if (source == target)
1457 frames[i].setClosed(true);
1461 frames[i].setIcon(minimize);
1464 frames[i].toFront();
1468 } catch (java.beans.PropertyVetoException ex)
1483 protected void preferences_actionPerformed(ActionEvent e)
1495 public void saveState_actionPerformed(ActionEvent e)
1497 JalviewFileChooser chooser = new JalviewFileChooser(
1498 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1499 { "jvp" }, new String[]
1500 { "Jalview Project" }, "Jalview Project");
1502 chooser.setFileView(new JalviewFileView());
1503 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1505 int value = chooser.showSaveDialog(this);
1507 if (value == JalviewFileChooser.APPROVE_OPTION)
1509 final Desktop me = this;
1510 final java.io.File choice = chooser.getSelectedFile();
1511 setProjectFile(choice);
1513 new Thread(new Runnable()
1517 // TODO: refactor to Jalview desktop session controller action.
1518 setProgressBar(MessageManager.formatMessage(
1519 "label.saving_jalview_project", new Object[]
1520 { choice.getName() }), choice.hashCode());
1521 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1522 choice.getParent());
1523 // TODO catch and handle errors for savestate
1524 // TODO prevent user from messing with the Desktop whilst we're saving
1527 new Jalview2XML().saveState(choice);
1528 } catch (OutOfMemoryError oom)
1530 new OOMWarning("Whilst saving current state to "
1531 + choice.getName(), oom);
1532 } catch (Exception ex)
1535 "Problems whilst trying to save to " + choice.getName(),
1537 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1538 "label.error_whilst_saving_current_state_to",
1540 { choice.getName() }), MessageManager
1541 .getString("label.couldnt_save_project"),
1542 JOptionPane.WARNING_MESSAGE);
1544 setProgressBar(null, choice.hashCode());
1550 private void setProjectFile(File choice)
1552 this.projectFile = choice;
1555 public File getProjectFile()
1557 return this.projectFile;
1567 public void loadState_actionPerformed(ActionEvent e)
1569 JalviewFileChooser chooser = new JalviewFileChooser(
1570 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1571 { "jvp", "jar" }, new String[]
1572 { "Jalview Project", "Jalview Project (old)" },
1574 chooser.setFileView(new JalviewFileView());
1575 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1577 int value = chooser.showOpenDialog(this);
1579 if (value == JalviewFileChooser.APPROVE_OPTION)
1581 final File selectedFile = chooser.getSelectedFile();
1582 setProjectFile(selectedFile);
1583 final String choice = selectedFile.getAbsolutePath();
1584 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1585 selectedFile.getParent());
1586 new Thread(new Runnable()
1590 setProgressBar(MessageManager.formatMessage(
1591 "label.loading_jalview_project", new Object[]
1592 { choice }), choice.hashCode());
1595 new Jalview2XML().loadJalviewAlign(choice);
1596 } catch (OutOfMemoryError oom)
1598 new OOMWarning("Whilst loading project from " + choice, oom);
1599 } catch (Exception ex)
1601 Cache.log.error("Problems whilst loading project from "
1603 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1605 "label.error_whilst_loading_project_from",
1607 { choice }), MessageManager
1608 .getString("label.couldnt_load_project"),
1609 JOptionPane.WARNING_MESSAGE);
1611 setProgressBar(null, choice.hashCode());
1618 public void inputSequence_actionPerformed(ActionEvent e)
1620 new SequenceFetcher(this);
1623 JPanel progressPanel;
1625 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1627 public void startLoading(final String fileName)
1629 if (fileLoadingCount == 0)
1631 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1632 "label.loading_file", new Object[]
1638 private JPanel addProgressPanel(String string)
1640 if (progressPanel == null)
1642 progressPanel = new JPanel(new GridLayout(1, 1));
1643 totalProgressCount = 0;
1644 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1646 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1647 JProgressBar progressBar = new JProgressBar();
1648 progressBar.setIndeterminate(true);
1650 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1652 thisprogress.add(progressBar, BorderLayout.CENTER);
1653 progressPanel.add(thisprogress);
1654 ((GridLayout) progressPanel.getLayout())
1655 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1656 ++totalProgressCount;
1657 instance.validate();
1658 return thisprogress;
1661 int totalProgressCount = 0;
1663 private void removeProgressPanel(JPanel progbar)
1665 if (progressPanel != null)
1667 synchronized (progressPanel)
1669 progressPanel.remove(progbar);
1670 GridLayout gl = (GridLayout) progressPanel.getLayout();
1671 gl.setRows(gl.getRows() - 1);
1672 if (--totalProgressCount < 1)
1674 this.getContentPane().remove(progressPanel);
1675 progressPanel = null;
1682 public void stopLoading()
1685 if (fileLoadingCount < 1)
1687 while (fileLoadingPanels.size() > 0)
1689 removeProgressPanel(fileLoadingPanels.remove(0));
1691 fileLoadingPanels.clear();
1692 fileLoadingCount = 0;
1697 public static int getViewCount(String alignmentId)
1699 AlignmentViewport[] aps = getViewports(alignmentId);
1700 return (aps == null) ? 0 : aps.length;
1705 * @param alignmentId
1706 * - if null, all sets are returned
1707 * @return all AlignmentPanels concerning the alignmentId sequence set
1709 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1711 if (Desktop.desktop == null)
1713 // no frames created and in headless mode
1714 // TODO: verify that frames are recoverable when in headless mode
1717 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1718 AlignFrame[] frames = getAlignFrames();
1723 for (AlignFrame af : frames)
1725 for (AlignmentPanel ap : af.alignPanels)
1727 if (alignmentId==null || alignmentId.equals(ap.av.getSequenceSetId()))
1733 if (aps.size() == 0)
1737 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1742 * get all the viewports on an alignment.
1744 * @param sequenceSetId
1745 * unique alignment id (may be null - all viewports returned in that
1747 * @return all viewports on the alignment bound to sequenceSetId
1749 public static AlignmentViewport[] getViewports(String sequenceSetId)
1751 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1752 if (desktop != null)
1754 AlignFrame[] frames = Desktop.getAlignFrames();
1756 for (AlignFrame afr : frames)
1758 if (sequenceSetId==null || afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1760 if (afr.alignPanels != null)
1762 for (AlignmentPanel ap : afr.alignPanels)
1764 if (sequenceSetId == null
1765 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1773 viewp.add(afr.getViewport());
1777 if (viewp.size() > 0)
1779 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1786 * Explode the views in the given frame into separate AlignFrame
1790 public void explodeViews(AlignFrame af)
1792 int size = af.alignPanels.size();
1798 for (int i = 0; i < size; i++)
1800 AlignmentPanel ap = af.alignPanels.get(i);
1801 AlignFrame newaf = new AlignFrame(ap);
1804 * Restore the view's last exploded frame geometry if known. Multiple
1805 * views from one exploded frame share and restore the same (frame)
1806 * position and size.
1808 Rectangle geometry = ap.av.getExplodedGeometry();
1809 if (geometry != null)
1811 newaf.setBounds(geometry);
1814 ap.av.setGatherViewsHere(false);
1816 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1817 AlignFrame.DEFAULT_HEIGHT);
1820 af.alignPanels.clear();
1821 af.closeMenuItem_actionPerformed(true);
1826 * Gather expanded views (separate AlignFrame's) with the same sequence set
1827 * identifier back in to this frame as additional views, and close the
1828 * expanded views. Note the expanded frames may themselves have multiple
1829 * views. We take the lot.
1833 public void gatherViews(AlignFrame source)
1835 source.viewport.setGatherViewsHere(true);
1836 source.viewport.setExplodedGeometry(source.getBounds());
1837 JInternalFrame[] frames = desktop.getAllFrames();
1838 String viewId = source.viewport.getSequenceSetId();
1840 for (int t = 0; t < frames.length; t++)
1842 if (frames[t] instanceof AlignFrame && frames[t] != source)
1844 AlignFrame af = (AlignFrame) frames[t];
1845 boolean gatherThis = false;
1846 for (int a = 0; a < af.alignPanels.size(); a++)
1848 AlignmentPanel ap = af.alignPanels.get(a);
1849 if (viewId.equals(ap.av.getSequenceSetId()))
1852 ap.av.setGatherViewsHere(false);
1853 ap.av.setExplodedGeometry(af.getBounds());
1854 source.addAlignmentPanel(ap, false);
1860 af.alignPanels.clear();
1861 af.closeMenuItem_actionPerformed(true);
1868 jalview.gui.VamsasApplication v_client = null;
1871 public void vamsasImport_actionPerformed(ActionEvent e)
1873 if (v_client == null)
1875 // Load and try to start a session.
1876 JalviewFileChooser chooser = new JalviewFileChooser(
1877 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1879 chooser.setFileView(new JalviewFileView());
1880 chooser.setDialogTitle(MessageManager
1881 .getString("label.open_saved_vamsas_session"));
1882 chooser.setToolTipText(MessageManager
1883 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1885 int value = chooser.showOpenDialog(this);
1887 if (value == JalviewFileChooser.APPROVE_OPTION)
1889 String fle = chooser.getSelectedFile().toString();
1890 if (!vamsasImport(chooser.getSelectedFile()))
1893 .showInternalMessageDialog(
1895 MessageManager.formatMessage(
1896 "label.couldnt_import_as_vamsas_session",
1900 .getString("label.vamsas_document_import_failed"),
1901 JOptionPane.ERROR_MESSAGE);
1907 jalview.bin.Cache.log
1908 .error("Implementation error - load session from a running session is not supported.");
1913 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1916 * @return true if import was a success and a session was started.
1918 public boolean vamsasImport(URL url)
1920 // TODO: create progress bar
1921 if (v_client != null)
1924 jalview.bin.Cache.log
1925 .error("Implementation error - load session from a running session is not supported.");
1931 // copy the URL content to a temporary local file
1932 // TODO: be a bit cleverer here with nio (?!)
1933 File file = File.createTempFile("vdocfromurl", ".vdj");
1934 FileOutputStream fos = new FileOutputStream(file);
1935 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1936 byte[] buffer = new byte[2048];
1938 while ((ln = bis.read(buffer)) > -1)
1940 fos.write(buffer, 0, ln);
1944 v_client = new jalview.gui.VamsasApplication(this, file,
1945 url.toExternalForm());
1946 } catch (Exception ex)
1948 jalview.bin.Cache.log.error(
1949 "Failed to create new vamsas session from contents of URL "
1953 setupVamsasConnectedGui();
1954 v_client.initial_update(); // TODO: thread ?
1955 return v_client.inSession();
1959 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1962 * @return true if import was a success and a session was started.
1964 public boolean vamsasImport(File file)
1966 if (v_client != null)
1969 jalview.bin.Cache.log
1970 .error("Implementation error - load session from a running session is not supported.");
1974 setProgressBar(MessageManager.formatMessage(
1975 "status.importing_vamsas_session_from", new Object[]
1976 { file.getName() }), file.hashCode());
1979 v_client = new jalview.gui.VamsasApplication(this, file, null);
1980 } catch (Exception ex)
1982 setProgressBar(MessageManager.formatMessage(
1983 "status.importing_vamsas_session_from", new Object[]
1984 { file.getName() }), file.hashCode());
1985 jalview.bin.Cache.log.error(
1986 "New vamsas session from existing session file failed:", ex);
1989 setupVamsasConnectedGui();
1990 v_client.initial_update(); // TODO: thread ?
1991 setProgressBar(MessageManager.formatMessage(
1992 "status.importing_vamsas_session_from", new Object[]
1993 { file.getName() }), file.hashCode());
1994 return v_client.inSession();
1997 public boolean joinVamsasSession(String mysesid)
1999 if (v_client != null)
2003 .getString("error.try_join_vamsas_session_another"));
2005 if (mysesid == null)
2008 MessageManager.getString("error.invalid_vamsas_session_id"));
2010 v_client = new VamsasApplication(this, mysesid);
2011 setupVamsasConnectedGui();
2012 v_client.initial_update();
2013 return (v_client.inSession());
2017 public void vamsasStart_actionPerformed(ActionEvent e)
2019 if (v_client == null)
2022 // we just start a default session for moment.
2024 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2025 * getProperty("LAST_DIRECTORY"));
2027 * chooser.setFileView(new JalviewFileView());
2028 * chooser.setDialogTitle("Load Vamsas file");
2029 * chooser.setToolTipText("Import");
2031 * int value = chooser.showOpenDialog(this);
2033 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2034 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2036 v_client = new VamsasApplication(this);
2037 setupVamsasConnectedGui();
2038 v_client.initial_update(); // TODO: thread ?
2042 // store current data in session.
2043 v_client.push_update(); // TODO: thread
2047 protected void setupVamsasConnectedGui()
2049 vamsasStart.setText(MessageManager.getString("label.session_update"));
2050 vamsasSave.setVisible(true);
2051 vamsasStop.setVisible(true);
2052 vamsasImport.setVisible(false); // Document import to existing session is
2053 // not possible for vamsas-client-1.0.
2056 protected void setupVamsasDisconnectedGui()
2058 vamsasSave.setVisible(false);
2059 vamsasStop.setVisible(false);
2060 vamsasImport.setVisible(true);
2061 vamsasStart.setText(MessageManager
2062 .getString("label.new_vamsas_session"));
2066 public void vamsasStop_actionPerformed(ActionEvent e)
2068 if (v_client != null)
2070 v_client.end_session();
2072 setupVamsasDisconnectedGui();
2076 protected void buildVamsasStMenu()
2078 if (v_client == null)
2080 String[] sess = null;
2083 sess = VamsasApplication.getSessionList();
2084 } catch (Exception e)
2086 jalview.bin.Cache.log.warn(
2087 "Problem getting current sessions list.", e);
2092 jalview.bin.Cache.log.debug("Got current sessions list: "
2093 + sess.length + " entries.");
2094 VamsasStMenu.removeAll();
2095 for (int i = 0; i < sess.length; i++)
2097 JMenuItem sessit = new JMenuItem();
2098 sessit.setText(sess[i]);
2099 sessit.setToolTipText(MessageManager.formatMessage(
2100 "label.connect_to_session", new Object[]
2102 final Desktop dsktp = this;
2103 final String mysesid = sess[i];
2104 sessit.addActionListener(new ActionListener()
2107 public void actionPerformed(ActionEvent e)
2109 if (dsktp.v_client == null)
2111 Thread rthr = new Thread(new Runnable()
2116 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2117 dsktp.setupVamsasConnectedGui();
2118 dsktp.v_client.initial_update();
2126 VamsasStMenu.add(sessit);
2128 // don't show an empty menu.
2129 VamsasStMenu.setVisible(sess.length > 0);
2134 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2135 VamsasStMenu.removeAll();
2136 VamsasStMenu.setVisible(false);
2141 // Not interested in the content. Just hide ourselves.
2142 VamsasStMenu.setVisible(false);
2147 public void vamsasSave_actionPerformed(ActionEvent e)
2149 if (v_client != null)
2151 JalviewFileChooser chooser = new JalviewFileChooser(
2152 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2153 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2155 { "Vamsas Document" }, "Vamsas Document");
2157 chooser.setFileView(new JalviewFileView());
2158 chooser.setDialogTitle(MessageManager
2159 .getString("label.save_vamsas_document_archive"));
2161 int value = chooser.showSaveDialog(this);
2163 if (value == JalviewFileChooser.APPROVE_OPTION)
2165 java.io.File choice = chooser.getSelectedFile();
2166 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2167 "label.saving_vamsas_doc", new Object[]
2168 { choice.getName() }));
2169 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2170 String warnmsg = null;
2171 String warnttl = null;
2174 v_client.vclient.storeDocument(choice);
2177 warnttl = "Serious Problem saving Vamsas Document";
2178 warnmsg = ex.toString();
2179 jalview.bin.Cache.log.error("Error Whilst saving document to "
2182 } catch (Exception ex)
2184 warnttl = "Problem saving Vamsas Document.";
2185 warnmsg = ex.toString();
2186 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2190 removeProgressPanel(progpanel);
2191 if (warnmsg != null)
2193 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2195 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2201 JPanel vamUpdate = null;
2204 * hide vamsas user gui bits when a vamsas document event is being handled.
2207 * true to hide gui, false to reveal gui
2209 public void setVamsasUpdate(boolean b)
2211 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2212 + (b ? "in progress" : "finished"));
2214 if (vamUpdate != null)
2216 this.removeProgressPanel(vamUpdate);
2220 vamUpdate = this.addProgressPanel(MessageManager
2221 .getString("label.updating_vamsas_session"));
2223 vamsasStart.setVisible(!b);
2224 vamsasStop.setVisible(!b);
2225 vamsasSave.setVisible(!b);
2228 public JInternalFrame[] getAllFrames()
2230 return desktop.getAllFrames();
2234 * Checks the given url to see if it gives a response indicating that the user
2235 * should be informed of a new questionnaire.
2239 public void checkForQuestionnaire(String url)
2241 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2242 // javax.swing.SwingUtilities.invokeLater(jvq);
2243 new Thread(jvq).start();
2247 * Proxy class for JDesktopPane which optionally displays the current memory
2248 * usage and highlights the desktop area with a red bar if free memory runs
2253 public class MyDesktopPane extends JDesktopPane implements Runnable
2256 private static final float ONE_MB = 1048576f;
2258 boolean showMemoryUsage = false;
2262 java.text.NumberFormat df;
2264 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2267 public MyDesktopPane(boolean showMemoryUsage)
2269 showMemoryUsage(showMemoryUsage);
2272 public void showMemoryUsage(boolean showMemory)
2274 this.showMemoryUsage = showMemory;
2277 Thread worker = new Thread(this);
2282 public boolean isShowMemoryUsage()
2284 return showMemoryUsage;
2289 df = java.text.NumberFormat.getNumberInstance();
2290 df.setMaximumFractionDigits(2);
2291 runtime = Runtime.getRuntime();
2293 while (showMemoryUsage)
2297 maxMemory = runtime.maxMemory() / ONE_MB;
2298 allocatedMemory = runtime.totalMemory() / ONE_MB;
2299 freeMemory = runtime.freeMemory() / ONE_MB;
2300 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2302 percentUsage = (totalFreeMemory / maxMemory) * 100;
2304 // if (percentUsage < 20)
2306 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2308 // instance.set.setBorder(border1);
2311 // sleep after showing usage
2313 } catch (Exception ex)
2315 ex.printStackTrace();
2321 public void paintComponent(Graphics g)
2323 if (showMemoryUsage && g != null && df != null)
2325 if (percentUsage < 20)
2327 g.setColor(Color.red);
2329 FontMetrics fm = g.getFontMetrics();
2332 g.drawString(MessageManager.formatMessage(
2333 "label.memory_stats",
2335 { df.format(totalFreeMemory), df.format(maxMemory),
2336 df.format(percentUsage) }), 10,
2337 getHeight() - fm.getHeight());
2344 * fixes stacking order after a modal dialog to ensure windows that should be
2345 * on top actually are
2347 public void relayerWindows()
2352 protected JMenuItem groovyShell;
2354 public void doGroovyCheck()
2356 if (jalview.bin.Cache.groovyJarsPresent())
2358 groovyShell = new JMenuItem();
2359 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2360 groovyShell.addActionListener(new ActionListener()
2362 public void actionPerformed(ActionEvent e)
2364 groovyShell_actionPerformed();
2367 toolsMenu.add(groovyShell);
2368 groovyShell.setVisible(true);
2373 * Accessor method to quickly get all the AlignmentFrames loaded.
2375 * @return an array of AlignFrame, or null if none found
2377 public static AlignFrame[] getAlignFrames()
2379 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2385 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2387 for (int i = frames.length - 1; i > -1; i--)
2389 if (frames[i] instanceof AlignFrame)
2391 avp.add((AlignFrame) frames[i]);
2393 else if (frames[i] instanceof SplitFrame)
2396 * Also check for a split frame containing an AlignFrame
2398 GSplitFrame sf = (GSplitFrame) frames[i];
2399 if (sf.getTopFrame() instanceof AlignFrame)
2401 avp.add((AlignFrame) sf.getTopFrame());
2403 if (sf.getBottomFrame() instanceof AlignFrame)
2405 avp.add((AlignFrame) sf.getBottomFrame());
2409 if (avp.size() == 0)
2413 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2418 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2422 public GStructureViewer[] getJmols()
2424 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2430 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2432 for (int i = frames.length - 1; i > -1; i--)
2434 if (frames[i] instanceof AppJmol)
2436 GStructureViewer af = (GStructureViewer) frames[i];
2440 if (avp.size() == 0)
2444 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2449 * Add Groovy Support to Jalview
2451 public void groovyShell_actionPerformed()
2453 // use reflection to avoid creating compilation dependency.
2454 if (!jalview.bin.Cache.groovyJarsPresent())
2458 .getString("error.implementation_error_cannot_create_groovyshell"));
2462 Class<?> gcClass = Desktop.class.getClassLoader().loadClass(
2463 "groovy.ui.Console");
2464 Constructor<?> gccons = gcClass.getConstructor();
2465 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2467 { String.class, Object.class });
2468 java.lang.reflect.Method run = gcClass.getMethod("run");
2469 Object gc = gccons.newInstance();
2470 setvar.invoke(gc, new Object[]
2471 { "Jalview", this });
2473 } catch (Exception ex)
2475 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2476 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2478 MessageManager.getString("label.couldnt_create_groovy_shell"),
2479 MessageManager.getString("label.groovy_support_failed"),
2480 JOptionPane.ERROR_MESSAGE);
2485 * Progress bars managed by the IProgressIndicator method.
2487 private Hashtable<Long, JPanel> progressBars;
2489 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2494 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2496 public void setProgressBar(String message, long id)
2498 if (progressBars == null)
2500 progressBars = new Hashtable<Long, JPanel>();
2501 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2504 if (progressBars.get(new Long(id)) != null)
2506 JPanel panel = progressBars.remove(new Long(id));
2507 if (progressBarHandlers.contains(new Long(id)))
2509 progressBarHandlers.remove(new Long(id));
2511 removeProgressPanel(panel);
2515 progressBars.put(new Long(id), addProgressPanel(message));
2522 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2523 * jalview.gui.IProgressIndicatorHandler)
2525 public void registerHandler(final long id,
2526 final IProgressIndicatorHandler handler)
2528 if (progressBarHandlers == null
2529 || !progressBars.containsKey(new Long(id)))
2533 .getString("error.call_setprogressbar_before_registering_handler"));
2535 progressBarHandlers.put(new Long(id), handler);
2536 final JPanel progressPanel = progressBars.get(new Long(id));
2537 if (handler.canCancel())
2539 JButton cancel = new JButton(
2540 MessageManager.getString("action.cancel"));
2541 final IProgressIndicator us = this;
2542 cancel.addActionListener(new ActionListener()
2545 public void actionPerformed(ActionEvent e)
2547 handler.cancelActivity(id);
2548 us.setProgressBar(MessageManager.formatMessage(
2549 "label.cancelled_params", new Object[]
2550 { ((JLabel) progressPanel.getComponent(0)).getText() }),
2554 progressPanel.add(cancel, BorderLayout.EAST);
2560 * @return true if any progress bars are still active
2563 public boolean operationInProgress()
2565 if (progressBars != null && progressBars.size() > 0)
2573 * This will return the first AlignFrame holding the given viewport instance. It
2574 * will break if there are more than one AlignFrames viewing a particular av.
2577 * @return alignFrame for viewport
2579 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2581 if (desktop != null)
2583 AlignmentPanel[] aps = getAlignmentPanels(viewport
2584 .getSequenceSetId());
2585 for (int panel = 0; aps != null && panel < aps.length; panel++)
2587 if (aps[panel] != null && aps[panel].av == viewport)
2589 return aps[panel].alignFrame;
2596 public VamsasApplication getVamsasApplication()
2603 * flag set if jalview GUI is being operated programmatically
2605 private boolean inBatchMode = false;
2608 * check if jalview GUI is being operated programmatically
2610 * @return inBatchMode
2612 public boolean isInBatchMode()
2618 * set flag if jalview GUI is being operated programmatically
2620 * @param inBatchMode
2622 public void setInBatchMode(boolean inBatchMode)
2624 this.inBatchMode = inBatchMode;
2627 public void startServiceDiscovery()
2629 startServiceDiscovery(false);
2632 public void startServiceDiscovery(boolean blocking)
2634 boolean alive = true;
2635 Thread t0 = null, t1 = null, t2 = null;
2636 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2639 // todo: changesupport handlers need to be transferred
2640 if (discoverer == null)
2642 discoverer = new jalview.ws.jws1.Discoverer();
2643 // register PCS handler for desktop.
2644 discoverer.addPropertyChangeListener(changeSupport);
2646 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2647 // until we phase out completely
2648 (t0 = new Thread(discoverer)).start();
2651 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2653 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2655 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2657 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2663 // TODO: do rest service discovery
2672 } catch (Exception e)
2675 alive = (t1 != null && t1.isAlive())
2676 || (t2 != null && t2.isAlive())
2677 || (t3 != null && t3.isAlive())
2678 || (t0 != null && t0.isAlive());
2684 * called to check if the service discovery process completed successfully.
2688 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2690 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2692 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2693 .getErrorMessages();
2696 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2698 if (serviceChangedDialog == null)
2700 // only run if we aren't already displaying one of these.
2701 addDialogThread(serviceChangedDialog = new Runnable()
2707 * JalviewDialog jd =new JalviewDialog() {
2709 * @Override protected void cancelPressed() { // TODO
2710 * Auto-generated method stub
2712 * }@Override protected void okPressed() { // TODO
2713 * Auto-generated method stub
2715 * }@Override protected void raiseClosed() { // TODO
2716 * Auto-generated method stub
2718 * } }; jd.initDialogFrame(new
2719 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2720 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2721 * + " or mis-configured HTTP proxy settings.<br/>" +
2722 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2724 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2725 * ), true, true, "Web Service Configuration Problem", 450,
2728 * jd.waitForInput();
2734 "<html><table width=\"450\"><tr><td>"
2736 + "</td></tr></table>"
2737 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2738 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2739 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2740 + " Tools->Preferences dialog box to change them.</p></html>"),
2741 "Web Service Configuration Problem",
2742 JOptionPane.DEFAULT_OPTION,
2743 JOptionPane.ERROR_MESSAGE);
2744 serviceChangedDialog = null;
2753 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2760 private Runnable serviceChangedDialog = null;
2763 * start a thread to open a URL in the configured browser. Pops up a warning
2764 * dialog to the user if there is an exception when calling out to the browser
2769 public static void showUrl(final String url)
2771 showUrl(url, Desktop.instance);
2775 * Like showUrl but allows progress handler to be specified
2779 * (null) or object implementing IProgressIndicator
2781 public static void showUrl(final String url,
2782 final IProgressIndicator progress)
2784 new Thread(new Runnable()
2790 if (progress != null)
2792 progress.setProgressBar(MessageManager.formatMessage(
2793 "status.opening_params", new Object[]
2794 { url }), this.hashCode());
2796 jalview.util.BrowserLauncher.openURL(url);
2797 } catch (Exception ex)
2799 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2801 .getString("label.web_browser_not_found_unix"),
2802 MessageManager.getString("label.web_browser_not_found"),
2803 JOptionPane.WARNING_MESSAGE);
2805 ex.printStackTrace();
2807 if (progress != null)
2809 progress.setProgressBar(null, this.hashCode());
2815 public static WsParamSetManager wsparamManager = null;
2817 public static ParamManager getUserParameterStore()
2819 if (wsparamManager == null)
2821 wsparamManager = new WsParamSetManager();
2823 return wsparamManager;
2827 * static hyperlink handler proxy method for use by Jalview's internal windows
2831 public static void hyperlinkUpdate(HyperlinkEvent e)
2833 if (e.getEventType() == EventType.ACTIVATED)
2838 url = e.getURL().toString();
2839 Desktop.showUrl(url);
2840 } catch (Exception x)
2844 if (Cache.log != null)
2846 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2850 System.err.println("Couldn't handle string " + url
2854 // ignore any exceptions due to dud links.
2861 * single thread that handles display of dialogs to user.
2863 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2866 * flag indicating if dialogExecutor should try to acquire a permit
2868 private volatile boolean dialogPause = true;
2873 private java.util.concurrent.Semaphore block = new Semaphore(0);
2876 * add another dialog thread to the queue
2880 public void addDialogThread(final Runnable prompter)
2882 dialogExecutor.submit(new Runnable()
2891 } catch (InterruptedException x)
2896 if (instance == null)
2902 SwingUtilities.invokeAndWait(prompter);
2903 } catch (Exception q)
2905 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2911 public void startDialogQueue()
2913 // set the flag so we don't pause waiting for another permit and semaphore
2914 // the current task to begin
2915 dialogPause = false;
2920 protected void snapShotWindow_actionPerformed(ActionEvent e)
2924 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2925 "View of Desktop", getWidth(), getHeight(), of = new File(
2926 "Jalview_snapshot" + System.currentTimeMillis()
2927 + ".eps"), "View of desktop");
2930 paintAll(im.getGraphics());
2932 } catch (Exception q)
2934 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
2938 Cache.log.info("Successfully written snapshot to file "
2939 + of.getAbsolutePath());
2943 * Explode the views in the given frame into separate AlignFrame windows.
2947 public void explodeViews(SplitFrame sf)
2949 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
2950 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
2951 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
2953 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
2955 int viewCount = topPanels.size();
2962 * Processing in reverse order works, forwards order leaves the first panels
2963 * not visible. I don't know why!
2965 for (int i = viewCount - 1; i >= 0; i--)
2968 * Make new top and bottom frames. These take over the respective
2969 * AlignmentPanel objects, including their AlignmentViewports, so the
2970 * cdna/protein relationships between the viewports is carried over to the
2973 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
2974 AlignFrame newTopFrame = new AlignFrame(topPanel);
2975 newTopFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
2976 AlignFrame.DEFAULT_HEIGHT));
2977 newTopFrame.setVisible(true);
2978 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
2979 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
2980 newBottomFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
2981 AlignFrame.DEFAULT_HEIGHT));
2982 newBottomFrame.setVisible(true);
2983 topPanel.av.setGatherViewsHere(false);
2984 bottomPanel.av.setGatherViewsHere(false);
2985 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
2987 // either panel may hold previous exploded frame geometry
2988 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
2989 .getExplodedGeometry();
2990 if (geometry != null)
2992 splitFrame.setBounds(geometry);
2994 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
2998 * Clear references to the panels (now relocated in the new SplitFrames)
2999 * before closing the old SplitFrame.
3002 bottomPanels.clear();
3007 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3008 * back into the given SplitFrame as additional views. Note that the gathered
3009 * frames may themselves have multiple views.
3013 public void gatherViews(GSplitFrame source)
3015 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3016 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3017 myTopFrame.viewport.setExplodedGeometry(source.getBounds());
3018 myBottomFrame.viewport.setExplodedGeometry(source.getBounds());
3019 myTopFrame.viewport.setGatherViewsHere(true);
3020 myBottomFrame.viewport.setGatherViewsHere(true);
3021 String topViewId = myTopFrame.viewport.getSequenceSetId();
3022 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3024 JInternalFrame[] frames = desktop.getAllFrames();
3025 for (JInternalFrame frame : frames)
3027 if (frame instanceof SplitFrame && frame != source)
3029 SplitFrame sf = (SplitFrame) frame;
3030 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3031 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3032 boolean gatherThis = false;
3033 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3035 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3036 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3037 if (topViewId.equals(topPanel.av.getSequenceSetId())
3038 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3041 topPanel.av.setGatherViewsHere(false);
3042 bottomPanel.av.setGatherViewsHere(false);
3043 // both panels refer to the same split frame geometry
3044 Rectangle position = sf.getBounds();
3045 topPanel.av.setExplodedGeometry(position);
3046 bottomPanel.av.setExplodedGeometry(position);
3047 myTopFrame.addAlignmentPanel(topPanel, false);
3048 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3054 topFrame.getAlignPanels().clear();
3055 bottomFrame.getAlignPanels().clear();
3062 * The dust settles...give focus to the tab we did this from.
3064 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3068 public static AlignFrame getCurrentAlignFrame()
3070 return currentAlignFrame;
3073 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
3075 Desktop.currentAlignFrame = currentAlignFrame;