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",
1109 new Object[] { url }), MessageManager
1110 .getString("label.url_not_found"),
1111 JOptionPane.WARNING_MESSAGE);
1116 if (viewport != null)
1118 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1122 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1128 * Opens the CutAndPaste window for the user to paste an alignment in to
1131 * - if not null, the pasted alignment is added to the current
1132 * alignment; if null, to a new alignment window
1135 public void inputTextboxMenuItem_actionPerformed(
1136 AlignmentViewPanel viewPanel)
1138 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1139 cap.setForInput(viewPanel);
1140 Desktop.addInternalFrame(cap,
1141 MessageManager.getString("label.cut_paste_alignmen_file"),
1151 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1153 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1154 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1156 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1157 getBounds().y, getWidth(), getHeight()));
1159 if (jconsole != null)
1161 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1162 jconsole.stopConsole();
1166 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1169 if (dialogExecutor != null)
1171 dialogExecutor.shutdownNow();
1173 closeAll_actionPerformed(null);
1177 private void storeLastKnownDimensions(String string, Rectangle jc)
1179 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1180 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1181 + " height:" + jc.height);
1183 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1184 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1185 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1186 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1196 public void aboutMenuItem_actionPerformed(ActionEvent e)
1198 // StringBuffer message = getAboutMessage(false);
1199 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1201 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1202 new Thread(new Runnable()
1206 new SplashScreen(true);
1211 public StringBuffer getAboutMessage(boolean shortv)
1213 StringBuffer message = new StringBuffer();
1214 message.append("<html>");
1217 message.append("<h1><strong>Version: "
1218 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1219 message.append("<strong>Last Updated: <em>"
1220 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1221 + "</em></strong>");
1227 message.append("<strong>Version "
1228 + jalview.bin.Cache.getProperty("VERSION")
1229 + "; last updated: "
1230 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1233 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1236 message.append("<br>...Checking latest version...</br>");
1238 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1239 .equals(jalview.bin.Cache.getProperty("VERSION")))
1241 boolean red = false;
1242 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1243 .indexOf("automated build") == -1)
1246 // Displayed when code version and jnlp version do not match and code
1247 // version is not a development build
1248 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1251 message.append("<br>!! Version "
1252 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1254 + " is available for download from "
1255 + jalview.bin.Cache.getDefault("www.jalview.org",
1256 "http://www.jalview.org") + " !!");
1259 message.append("</div>");
1262 message.append("<br>Authors: "
1264 .getDefault("AUTHORFNAMES",
1265 "The Jalview Authors (See AUTHORS file for current list)")
1266 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1267 + "<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"
1268 + "<br><br>If you use Jalview, please cite:"
1269 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1270 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1271 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1283 public void documentationMenuItem_actionPerformed(ActionEvent e)
1287 Help.showHelpWindow();
1288 } catch (Exception ex)
1294 public void closeAll_actionPerformed(ActionEvent e)
1296 JInternalFrame[] frames = desktop.getAllFrames();
1297 for (int i = 0; i < frames.length; i++)
1301 frames[i].setClosed(true);
1302 } catch (java.beans.PropertyVetoException ex)
1306 System.out.println("ALL CLOSED");
1307 if (v_client != null)
1309 // TODO clear binding to vamsas document objects on close_all
1313 * reset state of singleton objects as appropriate (clear down session state
1314 * when all windows are closed)
1316 StructureSelectionManager ssm = StructureSelectionManager
1317 .getStructureSelectionManager(this);
1325 public void raiseRelated_actionPerformed(ActionEvent e)
1327 reorderAssociatedWindows(false, false);
1331 public void minimizeAssociated_actionPerformed(ActionEvent e)
1333 reorderAssociatedWindows(true, false);
1336 void closeAssociatedWindows()
1338 reorderAssociatedWindows(false, true);
1344 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1348 protected void garbageCollect_actionPerformed(ActionEvent e)
1350 // We simply collect the garbage
1351 jalview.bin.Cache.log.debug("Collecting garbage...");
1353 jalview.bin.Cache.log.debug("Finished garbage collection.");
1360 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1364 protected void showMemusage_actionPerformed(ActionEvent e)
1366 desktop.showMemoryUsage(showMemusage.isSelected());
1373 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1377 protected void showConsole_actionPerformed(ActionEvent e)
1379 showConsole(showConsole.isSelected());
1382 Console jconsole = null;
1385 * control whether the java console is visible or not
1389 void showConsole(boolean selected)
1391 showConsole.setSelected(selected);
1392 // TODO: decide if we should update properties file
1393 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1395 jconsole.setVisible(selected);
1398 void reorderAssociatedWindows(boolean minimize, boolean close)
1400 JInternalFrame[] frames = desktop.getAllFrames();
1401 if (frames == null || frames.length < 1)
1406 AlignmentViewport source = null, target = null;
1407 if (frames[0] instanceof AlignFrame)
1409 source = ((AlignFrame) frames[0]).getCurrentView();
1411 else if (frames[0] instanceof TreePanel)
1413 source = ((TreePanel) frames[0]).getViewPort();
1415 else if (frames[0] instanceof PCAPanel)
1417 source = ((PCAPanel) frames[0]).av;
1419 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1421 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1426 for (int i = 0; i < frames.length; i++)
1429 if (frames[i] == null)
1433 if (frames[i] instanceof AlignFrame)
1435 target = ((AlignFrame) frames[i]).getCurrentView();
1437 else if (frames[i] instanceof TreePanel)
1439 target = ((TreePanel) frames[i]).getViewPort();
1441 else if (frames[i] instanceof PCAPanel)
1443 target = ((PCAPanel) frames[i]).av;
1445 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1447 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1450 if (source == target)
1456 frames[i].setClosed(true);
1460 frames[i].setIcon(minimize);
1463 frames[i].toFront();
1467 } catch (java.beans.PropertyVetoException ex)
1482 protected void preferences_actionPerformed(ActionEvent e)
1494 public void saveState_actionPerformed(ActionEvent e)
1496 JalviewFileChooser chooser = new JalviewFileChooser(
1497 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1498 new String[] { "jvp" }, new String[] { "Jalview Project" },
1501 chooser.setFileView(new JalviewFileView());
1502 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1504 int value = chooser.showSaveDialog(this);
1506 if (value == JalviewFileChooser.APPROVE_OPTION)
1508 final Desktop me = this;
1509 final java.io.File choice = chooser.getSelectedFile();
1510 setProjectFile(choice);
1512 new Thread(new Runnable()
1516 // TODO: refactor to Jalview desktop session controller action.
1517 setProgressBar(MessageManager.formatMessage(
1518 "label.saving_jalview_project",
1519 new Object[] { choice.getName() }), choice.hashCode());
1520 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1521 choice.getParent());
1522 // TODO catch and handle errors for savestate
1523 // TODO prevent user from messing with the Desktop whilst we're saving
1526 new Jalview2XML().saveState(choice);
1527 } catch (OutOfMemoryError oom)
1529 new OOMWarning("Whilst saving current state to "
1530 + choice.getName(), oom);
1531 } catch (Exception ex)
1534 "Problems whilst trying to save to " + choice.getName(),
1536 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1537 "label.error_whilst_saving_current_state_to",
1538 new Object[] { choice.getName() }), MessageManager
1539 .getString("label.couldnt_save_project"),
1540 JOptionPane.WARNING_MESSAGE);
1542 setProgressBar(null, choice.hashCode());
1548 private void setProjectFile(File choice)
1550 this.projectFile = choice;
1553 public File getProjectFile()
1555 return this.projectFile;
1565 public void loadState_actionPerformed(ActionEvent e)
1567 JalviewFileChooser chooser = new JalviewFileChooser(
1568 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1569 "jvp", "jar" }, new String[] { "Jalview Project",
1570 "Jalview Project (old)" }, "Jalview Project");
1571 chooser.setFileView(new JalviewFileView());
1572 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1574 int value = chooser.showOpenDialog(this);
1576 if (value == JalviewFileChooser.APPROVE_OPTION)
1578 final File selectedFile = chooser.getSelectedFile();
1579 setProjectFile(selectedFile);
1580 final String choice = selectedFile.getAbsolutePath();
1581 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1582 selectedFile.getParent());
1583 new Thread(new Runnable()
1588 MessageManager.formatMessage(
1589 "label.loading_jalview_project",
1590 new Object[] { choice }), choice.hashCode());
1593 new Jalview2XML().loadJalviewAlign(choice);
1594 } catch (OutOfMemoryError oom)
1596 new OOMWarning("Whilst loading project from " + choice, oom);
1597 } catch (Exception ex)
1599 Cache.log.error("Problems whilst loading project from "
1601 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1603 "label.error_whilst_loading_project_from",
1604 new Object[] { choice }), MessageManager
1605 .getString("label.couldnt_load_project"),
1606 JOptionPane.WARNING_MESSAGE);
1608 setProgressBar(null, choice.hashCode());
1615 public void inputSequence_actionPerformed(ActionEvent e)
1617 new SequenceFetcher(this);
1620 JPanel progressPanel;
1622 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1624 public void startLoading(final String fileName)
1626 if (fileLoadingCount == 0)
1628 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1629 "label.loading_file", new Object[] { fileName })));
1634 private JPanel addProgressPanel(String string)
1636 if (progressPanel == null)
1638 progressPanel = new JPanel(new GridLayout(1, 1));
1639 totalProgressCount = 0;
1640 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1642 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1643 JProgressBar progressBar = new JProgressBar();
1644 progressBar.setIndeterminate(true);
1646 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1648 thisprogress.add(progressBar, BorderLayout.CENTER);
1649 progressPanel.add(thisprogress);
1650 ((GridLayout) progressPanel.getLayout())
1651 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1652 ++totalProgressCount;
1653 instance.validate();
1654 return thisprogress;
1657 int totalProgressCount = 0;
1659 private void removeProgressPanel(JPanel progbar)
1661 if (progressPanel != null)
1663 synchronized (progressPanel)
1665 progressPanel.remove(progbar);
1666 GridLayout gl = (GridLayout) progressPanel.getLayout();
1667 gl.setRows(gl.getRows() - 1);
1668 if (--totalProgressCount < 1)
1670 this.getContentPane().remove(progressPanel);
1671 progressPanel = null;
1678 public void stopLoading()
1681 if (fileLoadingCount < 1)
1683 while (fileLoadingPanels.size() > 0)
1685 removeProgressPanel(fileLoadingPanels.remove(0));
1687 fileLoadingPanels.clear();
1688 fileLoadingCount = 0;
1693 public static int getViewCount(String alignmentId)
1695 AlignmentViewport[] aps = getViewports(alignmentId);
1696 return (aps == null) ? 0 : aps.length;
1701 * @param alignmentId
1702 * - if null, all sets are returned
1703 * @return all AlignmentPanels concerning the alignmentId sequence set
1705 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1707 if (Desktop.desktop == null)
1709 // no frames created and in headless mode
1710 // TODO: verify that frames are recoverable when in headless mode
1713 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1714 AlignFrame[] frames = getAlignFrames();
1719 for (AlignFrame af : frames)
1721 for (AlignmentPanel ap : af.alignPanels)
1723 if (alignmentId == null
1724 || alignmentId.equals(ap.av.getSequenceSetId()))
1730 if (aps.size() == 0)
1734 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1739 * get all the viewports on an alignment.
1741 * @param sequenceSetId
1742 * unique alignment id (may be null - all viewports returned in that
1744 * @return all viewports on the alignment bound to sequenceSetId
1746 public static AlignmentViewport[] getViewports(String sequenceSetId)
1748 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1749 if (desktop != null)
1751 AlignFrame[] frames = Desktop.getAlignFrames();
1753 for (AlignFrame afr : frames)
1755 if (sequenceSetId == null
1756 || afr.getViewport().getSequenceSetId()
1757 .equals(sequenceSetId))
1759 if (afr.alignPanels != null)
1761 for (AlignmentPanel ap : afr.alignPanels)
1763 if (sequenceSetId == null
1764 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1772 viewp.add(afr.getViewport());
1776 if (viewp.size() > 0)
1778 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1785 * Explode the views in the given frame into separate AlignFrame
1789 public void explodeViews(AlignFrame af)
1791 int size = af.alignPanels.size();
1797 for (int i = 0; i < size; i++)
1799 AlignmentPanel ap = af.alignPanels.get(i);
1800 AlignFrame newaf = new AlignFrame(ap);
1803 * Restore the view's last exploded frame geometry if known. Multiple
1804 * views from one exploded frame share and restore the same (frame)
1805 * position and size.
1807 Rectangle geometry = ap.av.getExplodedGeometry();
1808 if (geometry != null)
1810 newaf.setBounds(geometry);
1813 ap.av.setGatherViewsHere(false);
1815 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1816 AlignFrame.DEFAULT_HEIGHT);
1819 af.alignPanels.clear();
1820 af.closeMenuItem_actionPerformed(true);
1825 * Gather expanded views (separate AlignFrame's) with the same sequence set
1826 * identifier back in to this frame as additional views, and close the
1827 * expanded views. Note the expanded frames may themselves have multiple
1828 * views. We take the lot.
1832 public void gatherViews(AlignFrame source)
1834 source.viewport.setGatherViewsHere(true);
1835 source.viewport.setExplodedGeometry(source.getBounds());
1836 JInternalFrame[] frames = desktop.getAllFrames();
1837 String viewId = source.viewport.getSequenceSetId();
1839 for (int t = 0; t < frames.length; t++)
1841 if (frames[t] instanceof AlignFrame && frames[t] != source)
1843 AlignFrame af = (AlignFrame) frames[t];
1844 boolean gatherThis = false;
1845 for (int a = 0; a < af.alignPanels.size(); a++)
1847 AlignmentPanel ap = af.alignPanels.get(a);
1848 if (viewId.equals(ap.av.getSequenceSetId()))
1851 ap.av.setGatherViewsHere(false);
1852 ap.av.setExplodedGeometry(af.getBounds());
1853 source.addAlignmentPanel(ap, false);
1859 af.alignPanels.clear();
1860 af.closeMenuItem_actionPerformed(true);
1867 jalview.gui.VamsasApplication v_client = null;
1870 public void vamsasImport_actionPerformed(ActionEvent e)
1872 if (v_client == null)
1874 // Load and try to start a session.
1875 JalviewFileChooser chooser = new JalviewFileChooser(
1876 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1878 chooser.setFileView(new JalviewFileView());
1879 chooser.setDialogTitle(MessageManager
1880 .getString("label.open_saved_vamsas_session"));
1881 chooser.setToolTipText(MessageManager
1882 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1884 int value = chooser.showOpenDialog(this);
1886 if (value == JalviewFileChooser.APPROVE_OPTION)
1888 String fle = chooser.getSelectedFile().toString();
1889 if (!vamsasImport(chooser.getSelectedFile()))
1892 .showInternalMessageDialog(
1894 MessageManager.formatMessage(
1895 "label.couldnt_import_as_vamsas_session",
1896 new Object[] { fle }),
1898 .getString("label.vamsas_document_import_failed"),
1899 JOptionPane.ERROR_MESSAGE);
1905 jalview.bin.Cache.log
1906 .error("Implementation error - load session from a running session is not supported.");
1911 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1914 * @return true if import was a success and a session was started.
1916 public boolean vamsasImport(URL url)
1918 // TODO: create progress bar
1919 if (v_client != null)
1922 jalview.bin.Cache.log
1923 .error("Implementation error - load session from a running session is not supported.");
1929 // copy the URL content to a temporary local file
1930 // TODO: be a bit cleverer here with nio (?!)
1931 File file = File.createTempFile("vdocfromurl", ".vdj");
1932 FileOutputStream fos = new FileOutputStream(file);
1933 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1934 byte[] buffer = new byte[2048];
1936 while ((ln = bis.read(buffer)) > -1)
1938 fos.write(buffer, 0, ln);
1942 v_client = new jalview.gui.VamsasApplication(this, file,
1943 url.toExternalForm());
1944 } catch (Exception ex)
1946 jalview.bin.Cache.log.error(
1947 "Failed to create new vamsas session from contents of URL "
1951 setupVamsasConnectedGui();
1952 v_client.initial_update(); // TODO: thread ?
1953 return v_client.inSession();
1957 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1960 * @return true if import was a success and a session was started.
1962 public boolean vamsasImport(File file)
1964 if (v_client != null)
1967 jalview.bin.Cache.log
1968 .error("Implementation error - load session from a running session is not supported.");
1972 setProgressBar(MessageManager.formatMessage(
1973 "status.importing_vamsas_session_from",
1974 new Object[] { file.getName() }), file.hashCode());
1977 v_client = new jalview.gui.VamsasApplication(this, file, null);
1978 } catch (Exception ex)
1980 setProgressBar(MessageManager.formatMessage(
1981 "status.importing_vamsas_session_from",
1982 new Object[] { file.getName() }), file.hashCode());
1983 jalview.bin.Cache.log.error(
1984 "New vamsas session from existing session file failed:", ex);
1987 setupVamsasConnectedGui();
1988 v_client.initial_update(); // TODO: thread ?
1989 setProgressBar(MessageManager.formatMessage(
1990 "status.importing_vamsas_session_from",
1991 new Object[] { file.getName() }), file.hashCode());
1992 return v_client.inSession();
1995 public boolean joinVamsasSession(String mysesid)
1997 if (v_client != null)
2001 .getString("error.try_join_vamsas_session_another"));
2003 if (mysesid == null)
2006 MessageManager.getString("error.invalid_vamsas_session_id"));
2008 v_client = new VamsasApplication(this, mysesid);
2009 setupVamsasConnectedGui();
2010 v_client.initial_update();
2011 return (v_client.inSession());
2015 public void vamsasStart_actionPerformed(ActionEvent e)
2017 if (v_client == null)
2020 // we just start a default session for moment.
2022 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2023 * getProperty("LAST_DIRECTORY"));
2025 * chooser.setFileView(new JalviewFileView());
2026 * chooser.setDialogTitle("Load Vamsas file");
2027 * chooser.setToolTipText("Import");
2029 * int value = chooser.showOpenDialog(this);
2031 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2032 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2034 v_client = new VamsasApplication(this);
2035 setupVamsasConnectedGui();
2036 v_client.initial_update(); // TODO: thread ?
2040 // store current data in session.
2041 v_client.push_update(); // TODO: thread
2045 protected void setupVamsasConnectedGui()
2047 vamsasStart.setText(MessageManager.getString("label.session_update"));
2048 vamsasSave.setVisible(true);
2049 vamsasStop.setVisible(true);
2050 vamsasImport.setVisible(false); // Document import to existing session is
2051 // not possible for vamsas-client-1.0.
2054 protected void setupVamsasDisconnectedGui()
2056 vamsasSave.setVisible(false);
2057 vamsasStop.setVisible(false);
2058 vamsasImport.setVisible(true);
2059 vamsasStart.setText(MessageManager
2060 .getString("label.new_vamsas_session"));
2064 public void vamsasStop_actionPerformed(ActionEvent e)
2066 if (v_client != null)
2068 v_client.end_session();
2070 setupVamsasDisconnectedGui();
2074 protected void buildVamsasStMenu()
2076 if (v_client == null)
2078 String[] sess = null;
2081 sess = VamsasApplication.getSessionList();
2082 } catch (Exception e)
2084 jalview.bin.Cache.log.warn(
2085 "Problem getting current sessions list.", e);
2090 jalview.bin.Cache.log.debug("Got current sessions list: "
2091 + sess.length + " entries.");
2092 VamsasStMenu.removeAll();
2093 for (int i = 0; i < sess.length; i++)
2095 JMenuItem sessit = new JMenuItem();
2096 sessit.setText(sess[i]);
2097 sessit.setToolTipText(MessageManager.formatMessage(
2098 "label.connect_to_session", new Object[] { sess[i] }));
2099 final Desktop dsktp = this;
2100 final String mysesid = sess[i];
2101 sessit.addActionListener(new ActionListener()
2104 public void actionPerformed(ActionEvent e)
2106 if (dsktp.v_client == null)
2108 Thread rthr = new Thread(new Runnable()
2113 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2114 dsktp.setupVamsasConnectedGui();
2115 dsktp.v_client.initial_update();
2123 VamsasStMenu.add(sessit);
2125 // don't show an empty menu.
2126 VamsasStMenu.setVisible(sess.length > 0);
2131 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2132 VamsasStMenu.removeAll();
2133 VamsasStMenu.setVisible(false);
2138 // Not interested in the content. Just hide ourselves.
2139 VamsasStMenu.setVisible(false);
2144 public void vamsasSave_actionPerformed(ActionEvent e)
2146 if (v_client != null)
2148 JalviewFileChooser chooser = new JalviewFileChooser(
2149 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2150 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2151 new String[] { "Vamsas Document" }, "Vamsas Document");
2153 chooser.setFileView(new JalviewFileView());
2154 chooser.setDialogTitle(MessageManager
2155 .getString("label.save_vamsas_document_archive"));
2157 int value = chooser.showSaveDialog(this);
2159 if (value == JalviewFileChooser.APPROVE_OPTION)
2161 java.io.File choice = chooser.getSelectedFile();
2162 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2163 "label.saving_vamsas_doc",
2164 new Object[] { choice.getName() }));
2165 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2166 String warnmsg = null;
2167 String warnttl = null;
2170 v_client.vclient.storeDocument(choice);
2173 warnttl = "Serious Problem saving Vamsas Document";
2174 warnmsg = ex.toString();
2175 jalview.bin.Cache.log.error("Error Whilst saving document to "
2178 } catch (Exception ex)
2180 warnttl = "Problem saving Vamsas Document.";
2181 warnmsg = ex.toString();
2182 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2186 removeProgressPanel(progpanel);
2187 if (warnmsg != null)
2189 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2191 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2197 JPanel vamUpdate = null;
2200 * hide vamsas user gui bits when a vamsas document event is being handled.
2203 * true to hide gui, false to reveal gui
2205 public void setVamsasUpdate(boolean b)
2207 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2208 + (b ? "in progress" : "finished"));
2210 if (vamUpdate != null)
2212 this.removeProgressPanel(vamUpdate);
2216 vamUpdate = this.addProgressPanel(MessageManager
2217 .getString("label.updating_vamsas_session"));
2219 vamsasStart.setVisible(!b);
2220 vamsasStop.setVisible(!b);
2221 vamsasSave.setVisible(!b);
2224 public JInternalFrame[] getAllFrames()
2226 return desktop.getAllFrames();
2230 * Checks the given url to see if it gives a response indicating that the user
2231 * should be informed of a new questionnaire.
2235 public void checkForQuestionnaire(String url)
2237 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2238 // javax.swing.SwingUtilities.invokeLater(jvq);
2239 new Thread(jvq).start();
2243 * Proxy class for JDesktopPane which optionally displays the current memory
2244 * usage and highlights the desktop area with a red bar if free memory runs
2249 public class MyDesktopPane extends JDesktopPane implements Runnable
2252 private static final float ONE_MB = 1048576f;
2254 boolean showMemoryUsage = false;
2258 java.text.NumberFormat df;
2260 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2263 public MyDesktopPane(boolean showMemoryUsage)
2265 showMemoryUsage(showMemoryUsage);
2268 public void showMemoryUsage(boolean showMemory)
2270 this.showMemoryUsage = showMemory;
2273 Thread worker = new Thread(this);
2278 public boolean isShowMemoryUsage()
2280 return showMemoryUsage;
2285 df = java.text.NumberFormat.getNumberInstance();
2286 df.setMaximumFractionDigits(2);
2287 runtime = Runtime.getRuntime();
2289 while (showMemoryUsage)
2293 maxMemory = runtime.maxMemory() / ONE_MB;
2294 allocatedMemory = runtime.totalMemory() / ONE_MB;
2295 freeMemory = runtime.freeMemory() / ONE_MB;
2296 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2298 percentUsage = (totalFreeMemory / maxMemory) * 100;
2300 // if (percentUsage < 20)
2302 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2304 // instance.set.setBorder(border1);
2307 // sleep after showing usage
2309 } catch (Exception ex)
2311 ex.printStackTrace();
2317 public void paintComponent(Graphics g)
2319 if (showMemoryUsage && g != null && df != null)
2321 if (percentUsage < 20)
2323 g.setColor(Color.red);
2325 FontMetrics fm = g.getFontMetrics();
2328 g.drawString(MessageManager.formatMessage(
2329 "label.memory_stats",
2330 new Object[] { df.format(totalFreeMemory),
2331 df.format(maxMemory), df.format(percentUsage) }), 10,
2332 getHeight() - fm.getHeight());
2339 * fixes stacking order after a modal dialog to ensure windows that should be
2340 * on top actually are
2342 public void relayerWindows()
2347 protected JMenuItem groovyShell;
2349 public void doGroovyCheck()
2351 if (jalview.bin.Cache.groovyJarsPresent())
2353 groovyShell = new JMenuItem();
2354 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2355 groovyShell.addActionListener(new ActionListener()
2357 public void actionPerformed(ActionEvent e)
2359 groovyShell_actionPerformed();
2362 toolsMenu.add(groovyShell);
2363 groovyShell.setVisible(true);
2368 * Accessor method to quickly get all the AlignmentFrames loaded.
2370 * @return an array of AlignFrame, or null if none found
2372 public static AlignFrame[] getAlignFrames()
2374 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2380 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2382 for (int i = frames.length - 1; i > -1; i--)
2384 if (frames[i] instanceof AlignFrame)
2386 avp.add((AlignFrame) frames[i]);
2388 else if (frames[i] instanceof SplitFrame)
2391 * Also check for a split frame containing an AlignFrame
2393 GSplitFrame sf = (GSplitFrame) frames[i];
2394 if (sf.getTopFrame() instanceof AlignFrame)
2396 avp.add((AlignFrame) sf.getTopFrame());
2398 if (sf.getBottomFrame() instanceof AlignFrame)
2400 avp.add((AlignFrame) sf.getBottomFrame());
2404 if (avp.size() == 0)
2408 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2413 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2417 public GStructureViewer[] getJmols()
2419 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2425 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2427 for (int i = frames.length - 1; i > -1; i--)
2429 if (frames[i] instanceof AppJmol)
2431 GStructureViewer af = (GStructureViewer) frames[i];
2435 if (avp.size() == 0)
2439 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2444 * Add Groovy Support to Jalview
2446 public void groovyShell_actionPerformed()
2448 // use reflection to avoid creating compilation dependency.
2449 if (!jalview.bin.Cache.groovyJarsPresent())
2453 .getString("error.implementation_error_cannot_create_groovyshell"));
2457 Class<?> gcClass = Desktop.class.getClassLoader().loadClass(
2458 "groovy.ui.Console");
2459 Constructor<?> gccons = gcClass.getConstructor();
2460 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2461 new Class[] { String.class, Object.class });
2462 java.lang.reflect.Method run = gcClass.getMethod("run");
2463 Object gc = gccons.newInstance();
2464 setvar.invoke(gc, new Object[] { "Jalview", this });
2466 } catch (Exception ex)
2468 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2469 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2471 MessageManager.getString("label.couldnt_create_groovy_shell"),
2472 MessageManager.getString("label.groovy_support_failed"),
2473 JOptionPane.ERROR_MESSAGE);
2478 * Progress bars managed by the IProgressIndicator method.
2480 private Hashtable<Long, JPanel> progressBars;
2482 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2487 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2489 public void setProgressBar(String message, long id)
2491 if (progressBars == null)
2493 progressBars = new Hashtable<Long, JPanel>();
2494 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2497 if (progressBars.get(new Long(id)) != null)
2499 JPanel panel = progressBars.remove(new Long(id));
2500 if (progressBarHandlers.contains(new Long(id)))
2502 progressBarHandlers.remove(new Long(id));
2504 removeProgressPanel(panel);
2508 progressBars.put(new Long(id), addProgressPanel(message));
2515 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2516 * jalview.gui.IProgressIndicatorHandler)
2518 public void registerHandler(final long id,
2519 final IProgressIndicatorHandler handler)
2521 if (progressBarHandlers == null
2522 || !progressBars.containsKey(new Long(id)))
2526 .getString("error.call_setprogressbar_before_registering_handler"));
2528 progressBarHandlers.put(new Long(id), handler);
2529 final JPanel progressPanel = progressBars.get(new Long(id));
2530 if (handler.canCancel())
2532 JButton cancel = new JButton(
2533 MessageManager.getString("action.cancel"));
2534 final IProgressIndicator us = this;
2535 cancel.addActionListener(new ActionListener()
2538 public void actionPerformed(ActionEvent e)
2540 handler.cancelActivity(id);
2541 us.setProgressBar(MessageManager.formatMessage(
2542 "label.cancelled_params",
2543 new Object[] { ((JLabel) progressPanel.getComponent(0))
2547 progressPanel.add(cancel, BorderLayout.EAST);
2553 * @return true if any progress bars are still active
2556 public boolean operationInProgress()
2558 if (progressBars != null && progressBars.size() > 0)
2566 * This will return the first AlignFrame holding the given viewport instance.
2567 * It will break if there are more than one AlignFrames viewing a particular
2571 * @return alignFrame for viewport
2573 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2575 if (desktop != null)
2577 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2578 for (int panel = 0; aps != null && panel < aps.length; panel++)
2580 if (aps[panel] != null && aps[panel].av == viewport)
2582 return aps[panel].alignFrame;
2589 public VamsasApplication getVamsasApplication()
2596 * flag set if jalview GUI is being operated programmatically
2598 private boolean inBatchMode = false;
2601 * check if jalview GUI is being operated programmatically
2603 * @return inBatchMode
2605 public boolean isInBatchMode()
2611 * set flag if jalview GUI is being operated programmatically
2613 * @param inBatchMode
2615 public void setInBatchMode(boolean inBatchMode)
2617 this.inBatchMode = inBatchMode;
2620 public void startServiceDiscovery()
2622 startServiceDiscovery(false);
2625 public void startServiceDiscovery(boolean blocking)
2627 boolean alive = true;
2628 Thread t0 = null, t1 = null, t2 = null;
2629 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2632 // todo: changesupport handlers need to be transferred
2633 if (discoverer == null)
2635 discoverer = new jalview.ws.jws1.Discoverer();
2636 // register PCS handler for desktop.
2637 discoverer.addPropertyChangeListener(changeSupport);
2639 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2640 // until we phase out completely
2641 (t0 = new Thread(discoverer)).start();
2644 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2646 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2648 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2650 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2656 // TODO: do rest service discovery
2665 } catch (Exception e)
2668 alive = (t1 != null && t1.isAlive())
2669 || (t2 != null && t2.isAlive())
2670 || (t3 != null && t3.isAlive())
2671 || (t0 != null && t0.isAlive());
2677 * called to check if the service discovery process completed successfully.
2681 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2683 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2685 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2686 .getErrorMessages();
2689 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2691 if (serviceChangedDialog == null)
2693 // only run if we aren't already displaying one of these.
2694 addDialogThread(serviceChangedDialog = new Runnable()
2700 * JalviewDialog jd =new JalviewDialog() {
2702 * @Override protected void cancelPressed() { // TODO
2703 * Auto-generated method stub
2705 * }@Override protected void okPressed() { // TODO
2706 * Auto-generated method stub
2708 * }@Override protected void raiseClosed() { // TODO
2709 * Auto-generated method stub
2711 * } }; jd.initDialogFrame(new
2712 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2713 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2714 * + " or mis-configured HTTP proxy settings.<br/>" +
2715 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2717 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2718 * ), true, true, "Web Service Configuration Problem", 450,
2721 * jd.waitForInput();
2727 "<html><table width=\"450\"><tr><td>"
2729 + "</td></tr></table>"
2730 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2731 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2732 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2733 + " Tools->Preferences dialog box to change them.</p></html>"),
2734 "Web Service Configuration Problem",
2735 JOptionPane.DEFAULT_OPTION,
2736 JOptionPane.ERROR_MESSAGE);
2737 serviceChangedDialog = null;
2746 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2753 private Runnable serviceChangedDialog = null;
2756 * start a thread to open a URL in the configured browser. Pops up a warning
2757 * dialog to the user if there is an exception when calling out to the browser
2762 public static void showUrl(final String url)
2764 showUrl(url, Desktop.instance);
2768 * Like showUrl but allows progress handler to be specified
2772 * (null) or object implementing IProgressIndicator
2774 public static void showUrl(final String url,
2775 final IProgressIndicator progress)
2777 new Thread(new Runnable()
2783 if (progress != null)
2785 progress.setProgressBar(MessageManager.formatMessage(
2786 "status.opening_params", new Object[] { url }), this
2789 jalview.util.BrowserLauncher.openURL(url);
2790 } catch (Exception ex)
2792 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2794 .getString("label.web_browser_not_found_unix"),
2795 MessageManager.getString("label.web_browser_not_found"),
2796 JOptionPane.WARNING_MESSAGE);
2798 ex.printStackTrace();
2800 if (progress != null)
2802 progress.setProgressBar(null, this.hashCode());
2808 public static WsParamSetManager wsparamManager = null;
2810 public static ParamManager getUserParameterStore()
2812 if (wsparamManager == null)
2814 wsparamManager = new WsParamSetManager();
2816 return wsparamManager;
2820 * static hyperlink handler proxy method for use by Jalview's internal windows
2824 public static void hyperlinkUpdate(HyperlinkEvent e)
2826 if (e.getEventType() == EventType.ACTIVATED)
2831 url = e.getURL().toString();
2832 Desktop.showUrl(url);
2833 } catch (Exception x)
2837 if (Cache.log != null)
2839 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2843 System.err.println("Couldn't handle string " + url
2847 // ignore any exceptions due to dud links.
2854 * single thread that handles display of dialogs to user.
2856 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2859 * flag indicating if dialogExecutor should try to acquire a permit
2861 private volatile boolean dialogPause = true;
2866 private java.util.concurrent.Semaphore block = new Semaphore(0);
2869 * add another dialog thread to the queue
2873 public void addDialogThread(final Runnable prompter)
2875 dialogExecutor.submit(new Runnable()
2884 } catch (InterruptedException x)
2889 if (instance == null)
2895 SwingUtilities.invokeAndWait(prompter);
2896 } catch (Exception q)
2898 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2904 public void startDialogQueue()
2906 // set the flag so we don't pause waiting for another permit and semaphore
2907 // the current task to begin
2908 dialogPause = false;
2913 protected void snapShotWindow_actionPerformed(ActionEvent e)
2917 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2918 "View of Desktop", getWidth(), getHeight(), of = new File(
2919 "Jalview_snapshot" + System.currentTimeMillis()
2920 + ".eps"), "View of desktop");
2923 paintAll(im.getGraphics());
2925 } catch (Exception q)
2927 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
2931 Cache.log.info("Successfully written snapshot to file "
2932 + of.getAbsolutePath());
2936 * Explode the views in the given frame into separate AlignFrame windows.
2940 public void explodeViews(SplitFrame sf)
2942 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
2943 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
2944 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
2946 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
2948 int viewCount = topPanels.size();
2955 * Processing in reverse order works, forwards order leaves the first panels
2956 * not visible. I don't know why!
2958 for (int i = viewCount - 1; i >= 0; i--)
2961 * Make new top and bottom frames. These take over the respective
2962 * AlignmentPanel objects, including their AlignmentViewports, so the
2963 * cdna/protein relationships between the viewports is carried over to the
2966 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
2967 AlignFrame newTopFrame = new AlignFrame(topPanel);
2968 newTopFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
2969 AlignFrame.DEFAULT_HEIGHT));
2970 newTopFrame.setVisible(true);
2971 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
2972 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
2973 newBottomFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
2974 AlignFrame.DEFAULT_HEIGHT));
2975 newBottomFrame.setVisible(true);
2976 topPanel.av.setGatherViewsHere(false);
2977 bottomPanel.av.setGatherViewsHere(false);
2978 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
2980 // either panel may hold previous exploded frame geometry
2981 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
2982 .getExplodedGeometry();
2983 if (geometry != null)
2985 splitFrame.setBounds(geometry);
2987 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
2991 * Clear references to the panels (now relocated in the new SplitFrames)
2992 * before closing the old SplitFrame.
2995 bottomPanels.clear();
3000 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3001 * back into the given SplitFrame as additional views. Note that the gathered
3002 * frames may themselves have multiple views.
3006 public void gatherViews(GSplitFrame source)
3008 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3009 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3010 myTopFrame.viewport.setExplodedGeometry(source.getBounds());
3011 myBottomFrame.viewport.setExplodedGeometry(source.getBounds());
3012 myTopFrame.viewport.setGatherViewsHere(true);
3013 myBottomFrame.viewport.setGatherViewsHere(true);
3014 String topViewId = myTopFrame.viewport.getSequenceSetId();
3015 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3017 JInternalFrame[] frames = desktop.getAllFrames();
3018 for (JInternalFrame frame : frames)
3020 if (frame instanceof SplitFrame && frame != source)
3022 SplitFrame sf = (SplitFrame) frame;
3023 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3024 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3025 boolean gatherThis = false;
3026 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3028 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3029 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3030 if (topViewId.equals(topPanel.av.getSequenceSetId())
3031 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3034 topPanel.av.setGatherViewsHere(false);
3035 bottomPanel.av.setGatherViewsHere(false);
3036 // both panels refer to the same split frame geometry
3037 Rectangle position = sf.getBounds();
3038 topPanel.av.setExplodedGeometry(position);
3039 bottomPanel.av.setExplodedGeometry(position);
3040 myTopFrame.addAlignmentPanel(topPanel, false);
3041 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3047 topFrame.getAlignPanels().clear();
3048 bottomFrame.getAlignPanels().clear();
3055 * The dust settles...give focus to the tab we did this from.
3057 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3061 public static AlignFrame getCurrentAlignFrame()
3063 return currentAlignFrame;
3066 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
3068 Desktop.currentAlignFrame = currentAlignFrame;