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 final int THREE = 3;
172 private static AlignFrame currentAlignFrame;
174 public static jalview.ws.jws1.Discoverer discoverer;
176 public static Object[] jalviewClipboard;
178 public static boolean internalCopy = false;
180 static int fileLoadingCount = 0;
182 class MyDesktopManager implements DesktopManager
185 private DesktopManager delegate;
187 public MyDesktopManager(DesktopManager delegate)
189 this.delegate = delegate;
192 public void activateFrame(JInternalFrame f)
196 delegate.activateFrame(f);
197 } catch (NullPointerException npe)
199 Point p = getMousePosition();
200 instance.showPasteMenu(p.x, p.y);
204 public void beginDraggingFrame(JComponent f)
206 delegate.beginDraggingFrame(f);
209 public void beginResizingFrame(JComponent f, int direction)
211 delegate.beginResizingFrame(f, direction);
214 public void closeFrame(JInternalFrame f)
216 delegate.closeFrame(f);
219 public void deactivateFrame(JInternalFrame f)
221 delegate.deactivateFrame(f);
224 public void deiconifyFrame(JInternalFrame f)
226 delegate.deiconifyFrame(f);
229 public void dragFrame(JComponent f, int newX, int newY)
235 delegate.dragFrame(f, newX, newY);
238 public void endDraggingFrame(JComponent f)
240 delegate.endDraggingFrame(f);
243 public void endResizingFrame(JComponent f)
245 delegate.endResizingFrame(f);
248 public void iconifyFrame(JInternalFrame f)
250 delegate.iconifyFrame(f);
253 public void maximizeFrame(JInternalFrame f)
255 delegate.maximizeFrame(f);
258 public void minimizeFrame(JInternalFrame f)
260 delegate.minimizeFrame(f);
263 public void openFrame(JInternalFrame f)
265 delegate.openFrame(f);
268 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
271 Rectangle b = desktop.getBounds();
276 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
279 public void setBoundsForFrame(JComponent f, int newX, int newY,
280 int newWidth, int newHeight)
282 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
285 // All other methods, simply delegate
290 * Creates a new Desktop object.
295 * A note to implementors. It is ESSENTIAL that any activities that might
296 * block are spawned off as threads rather than waited for during this
300 doVamsasClientCheck();
302 doConfigureStructurePrefs();
303 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
304 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
305 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
307 boolean showjconsole = jalview.bin.Cache.getDefault(
308 "SHOW_JAVA_CONSOLE", false);
309 desktop = new MyDesktopPane(selmemusage);
310 showMemusage.setSelected(selmemusage);
311 desktop.setBackground(Color.white);
312 getContentPane().setLayout(new BorderLayout());
313 // alternate config - have scrollbars - see notes in JAL-153
314 // JScrollPane sp = new JScrollPane();
315 // sp.getViewport().setView(desktop);
316 // getContentPane().add(sp, BorderLayout.CENTER);
317 getContentPane().add(desktop, BorderLayout.CENTER);
318 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
320 // This line prevents Windows Look&Feel resizing all new windows to maximum
321 // if previous window was maximised
322 desktop.setDesktopManager(new MyDesktopManager(
323 new DefaultDesktopManager()));
325 Rectangle dims = getLastKnownDimensions("");
332 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
333 setBounds((screenSize.width - 900) / 2,
334 (screenSize.height - 650) / 2, 900, 650);
336 jconsole = new Console(this, showjconsole);
337 // add essential build information
338 jconsole.setHeader("Jalview Version: "
339 + jalview.bin.Cache.getProperty("VERSION") + "\n"
340 + "Jalview Installation: "
341 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
342 + "\n" + "Build Date: "
343 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
344 + "Java version: " + System.getProperty("java.version") + "\n"
345 + System.getProperty("os.arch") + " "
346 + System.getProperty("os.name") + " "
347 + System.getProperty("os.version"));
349 showConsole(showjconsole);
351 showNews.setVisible(false);
353 this.addWindowListener(new WindowAdapter()
355 public void windowClosing(WindowEvent evt)
362 this.addMouseListener(ma = new MouseAdapter()
364 public void mousePressed(MouseEvent evt)
366 if (SwingUtilities.isRightMouseButton(evt))
368 showPasteMenu(evt.getX(), evt.getY());
372 desktop.addMouseListener(ma);
374 this.addFocusListener(new FocusListener()
378 public void focusLost(FocusEvent e)
380 // TODO Auto-generated method stub
385 public void focusGained(FocusEvent e)
387 Cache.log.debug("Relaying windows after focus gain");
388 // make sure that we sort windows properly after we gain focus
389 instance.relayerWindows();
392 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
393 // Spawn a thread that shows the splashscreen
394 SwingUtilities.invokeLater(new Runnable()
403 // Thread off a new instance of the file chooser - this reduces the time it
404 // takes to open it later on.
405 new Thread(new Runnable()
409 Cache.log.debug("Filechooser init thread started.");
410 JalviewFileChooser chooser = new JalviewFileChooser(
411 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
412 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
413 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
414 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
415 Cache.log.debug("Filechooser init thread finished.");
418 // Add the service change listener
419 changeSupport.addJalviewPropertyChangeListener("services",
420 new PropertyChangeListener()
424 public void propertyChange(PropertyChangeEvent evt)
426 Cache.log.debug("Firing service changed event for "
427 + evt.getNewValue());
428 JalviewServicesChanged(evt);
434 public void doConfigureStructurePrefs()
436 // configure services
437 StructureSelectionManager ssm = StructureSelectionManager
438 .getStructureSelectionManager(this);
439 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
441 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
442 Preferences.ADD_TEMPFACT_ANN, true));
443 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
444 Preferences.STRUCT_FROM_PDB, true));
445 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
446 Preferences.USE_RNAVIEW, true));
450 ssm.setAddTempFacAnnot(false);
451 ssm.setProcessSecondaryStructure(false);
452 ssm.setSecStructServices(false);
456 public void checkForNews()
458 final Desktop me = this;
459 // Thread off the news reader, in case there are connection problems.
460 addDialogThread(new Runnable()
465 Cache.log.debug("Starting news thread.");
467 jvnews = new BlogReader(me);
468 showNews.setVisible(true);
469 Cache.log.debug("Completed news thread.");
474 protected void showNews_actionPerformed(ActionEvent e)
476 showNews(showNews.isSelected());
479 void showNews(boolean visible)
482 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
483 showNews.setSelected(visible);
484 if (visible && !jvnews.isVisible())
486 new Thread(new Runnable()
491 long instance = System.currentTimeMillis();
492 Desktop.instance.setProgressBar(
493 MessageManager.getString("status.refreshing_news"),
495 jvnews.refreshNews();
496 Desktop.instance.setProgressBar(null, instance);
505 * recover the last known dimensions for a jalview window
508 * - empty string is desktop, all other windows have unique prefix
509 * @return null or last known dimensions scaled to current geometry (if last
510 * window geom was known)
512 Rectangle getLastKnownDimensions(String windowName)
514 // TODO: lock aspect ratio for scaling desktop Bug #0058199
515 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
516 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
517 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
518 String width = jalview.bin.Cache.getProperty(windowName
520 String height = jalview.bin.Cache.getProperty(windowName
522 if ((x != null) && (y != null) && (width != null) && (height != null))
524 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
525 .parseInt(width), ih = Integer.parseInt(height);
526 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
528 // attempt #1 - try to cope with change in screen geometry - this
529 // version doesn't preserve original jv aspect ratio.
530 // take ratio of current screen size vs original screen size.
531 double sw = ((1f * screenSize.width) / (1f * Integer
532 .parseInt(jalview.bin.Cache
533 .getProperty("SCREENGEOMETRY_WIDTH"))));
534 double sh = ((1f * screenSize.height) / (1f * Integer
535 .parseInt(jalview.bin.Cache
536 .getProperty("SCREENGEOMETRY_HEIGHT"))));
537 // rescale the bounds depending upon the current screen geometry.
538 ix = (int) (ix * sw);
539 iw = (int) (iw * sw);
540 iy = (int) (iy * sh);
541 ih = (int) (ih * sh);
542 while (ix >= screenSize.width)
544 jalview.bin.Cache.log
545 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
546 ix -= screenSize.width;
548 while (iy >= screenSize.height)
550 jalview.bin.Cache.log
551 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
552 iy -= screenSize.height;
554 jalview.bin.Cache.log.debug("Got last known dimensions for "
555 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
558 // return dimensions for new instance
559 return new Rectangle(ix, iy, iw, ih);
564 private void doVamsasClientCheck()
566 if (jalview.bin.Cache.vamsasJarsPresent())
568 setupVamsasDisconnectedGui();
569 VamsasMenu.setVisible(true);
570 final Desktop us = this;
571 VamsasMenu.addMenuListener(new MenuListener()
573 // this listener remembers when the menu was first selected, and
574 // doesn't rebuild the session list until it has been cleared and
576 boolean refresh = true;
578 public void menuCanceled(MenuEvent e)
583 public void menuDeselected(MenuEvent e)
588 public void menuSelected(MenuEvent e)
592 us.buildVamsasStMenu();
597 vamsasStart.setVisible(true);
601 void showPasteMenu(int x, int y)
603 JPopupMenu popup = new JPopupMenu();
604 JMenuItem item = new JMenuItem(
605 MessageManager.getString("label.paste_new_window"));
606 item.addActionListener(new ActionListener()
608 public void actionPerformed(ActionEvent evt)
615 popup.show(this, x, y);
622 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
623 Transferable contents = c.getContents(this);
625 if (contents != null)
627 String file = (String) contents
628 .getTransferData(DataFlavor.stringFlavor);
630 String format = new IdentifyFile().Identify(file,
631 FormatAdapter.PASTE);
633 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
636 } catch (Exception ex)
639 .println("Unable to paste alignment from system clipboard:\n"
645 * Adds and opens the given frame to the desktop
656 public static synchronized void addInternalFrame(
657 final JInternalFrame frame, String title, int w, int h)
659 addInternalFrame(frame, title, true, w, h, true);
663 * Add an internal frame to the Jalview desktop
670 * When true, display frame immediately, otherwise, caller must call
671 * setVisible themselves.
677 public static synchronized void addInternalFrame(
678 final JInternalFrame frame, String title, boolean makeVisible,
681 addInternalFrame(frame, title, makeVisible, w, h, true);
685 * Add an internal frame to the Jalview desktop and make it visible
698 public static synchronized void addInternalFrame(
699 final JInternalFrame frame, String title, int w, int h,
702 addInternalFrame(frame, title, true, w, h, resizable);
706 * Add an internal frame to the Jalview desktop
713 * When true, display frame immediately, otherwise, caller must call
714 * setVisible themselves.
722 public static synchronized void addInternalFrame(
723 final JInternalFrame frame, String title, boolean makeVisible,
724 int w, int h, boolean resizable)
727 // TODO: allow callers to determine X and Y position of frame (eg. via
729 // TODO: consider fixing method to update entries in the window submenu with
730 // the current window title
732 frame.setTitle(title);
733 if (frame.getWidth() < 1 || frame.getHeight() < 1)
737 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
738 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
739 // IF JALVIEW IS RUNNING HEADLESS
740 // ///////////////////////////////////////////////
742 || (System.getProperty("java.awt.headless") != null && System
743 .getProperty("java.awt.headless").equals("true")))
750 frame.setVisible(makeVisible);
751 frame.setClosable(true);
752 frame.setResizable(resizable);
753 frame.setMaximizable(resizable);
754 frame.setIconifiable(resizable);
755 frame.setFrameIcon(null);
757 if (frame.getX() < 1 && frame.getY() < 1)
759 frame.setLocation(xOffset * openFrameCount, yOffset
760 * ((openFrameCount - 1) % 10) + yOffset);
763 final JMenuItem menuItem = new JMenuItem(title);
764 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
766 public void internalFrameActivated(
767 javax.swing.event.InternalFrameEvent evt)
769 JInternalFrame itf = desktop.getSelectedFrame();
777 public void internalFrameClosed(
778 javax.swing.event.InternalFrameEvent evt)
780 PaintRefresher.RemoveComponent(frame);
782 windowMenu.remove(menuItem);
783 JInternalFrame itf = desktop.getSelectedFrame();
792 menuItem.addActionListener(new ActionListener()
794 public void actionPerformed(ActionEvent e)
798 frame.setSelected(true);
799 frame.setIcon(false);
800 } catch (java.beans.PropertyVetoException ex)
806 menuItem.addMouseListener(new MouseListener()
810 public void mouseReleased(MouseEvent e)
815 public void mousePressed(MouseEvent e)
820 public void mouseExited(MouseEvent e)
824 frame.setSelected(false);
825 } catch (PropertyVetoException e1)
831 public void mouseEntered(MouseEvent e)
835 frame.setSelected(true);
836 } catch (PropertyVetoException e1)
842 public void mouseClicked(MouseEvent e)
848 windowMenu.add(menuItem);
854 frame.setSelected(true);
855 frame.requestFocus();
856 } catch (java.beans.PropertyVetoException ve)
858 } catch (java.lang.ClassCastException cex)
861 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
866 public void lostOwnership(Clipboard clipboard, Transferable contents)
870 Desktop.jalviewClipboard = null;
873 internalCopy = false;
876 public void dragEnter(DropTargetDragEvent evt)
880 public void dragExit(DropTargetEvent evt)
884 public void dragOver(DropTargetDragEvent evt)
888 public void dropActionChanged(DropTargetDragEvent evt)
898 public void drop(DropTargetDropEvent evt)
900 boolean success = true;
901 Transferable t = evt.getTransferable();
902 java.util.List files = null;
903 java.util.List protocols = null;
907 DataFlavor uriListFlavor = new DataFlavor(
908 "text/uri-list;class=java.lang.String");
909 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
911 // Works on Windows and MacOSX
912 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
913 files = (java.util.List) t
914 .getTransferData(DataFlavor.javaFileListFlavor);
916 else if (t.isDataFlavorSupported(uriListFlavor))
918 // This is used by Unix drag system
919 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
920 String data = (String) t.getTransferData(uriListFlavor);
921 files = new java.util.ArrayList(1);
922 protocols = new java.util.ArrayList(1);
923 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
924 data, "\r\n"); st.hasMoreTokens();)
926 String s = st.nextToken();
927 if (s.startsWith("#"))
929 // the line is a comment (as per the RFC 2483)
932 java.net.URI uri = new java.net.URI(s);
933 if (uri.getScheme().toLowerCase().startsWith("http"))
935 protocols.add(FormatAdapter.URL);
936 files.add(uri.toString());
940 // otherwise preserve old behaviour: catch all for file objects
941 java.io.File file = new java.io.File(uri);
942 protocols.add(FormatAdapter.FILE);
943 files.add(file.toString());
947 } catch (Exception e)
956 for (int i = 0; i < files.size(); i++)
958 String file = files.get(i).toString();
959 String protocol = (protocols == null) ? FormatAdapter.FILE
960 : (String) protocols.get(i);
961 String format = null;
963 if (file.endsWith(".jar"))
970 format = new IdentifyFile().Identify(file, protocol);
973 new FileLoader().LoadFile(file, protocol, format);
976 } catch (Exception ex)
981 evt.dropComplete(success); // need this to ensure input focus is properly
982 // transfered to any new windows created
991 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
993 JalviewFileChooser chooser = new JalviewFileChooser(
994 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
995 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
996 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
997 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
999 chooser.setFileView(new JalviewFileView());
1000 chooser.setDialogTitle(MessageManager
1001 .getString("label.open_local_file"));
1002 chooser.setToolTipText(MessageManager.getString("action.open"));
1004 int value = chooser.showOpenDialog(this);
1006 if (value == JalviewFileChooser.APPROVE_OPTION)
1008 String choice = chooser.getSelectedFile().getPath();
1009 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1010 .getSelectedFile().getParent());
1012 String format = null;
1013 if (chooser.getSelectedFormat() != null
1014 && chooser.getSelectedFormat().equals("Jalview"))
1020 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1023 if (viewport != null)
1025 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1027 // viewport.setShowSequenceFeatures(JSONFile.isSeqFeaturesEnabled());
1028 // AlignFrame af = viewport.getAlignPanel().alignFrame;
1031 // af.changeColour(JSONFile.getColourScheme());
1032 // af.setMenusForViewport();
1037 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1048 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1050 // This construct allows us to have a wider textfield
1052 JLabel label = new JLabel(
1053 MessageManager.getString("label.input_file_url"));
1054 final JComboBox history = new JComboBox();
1056 JPanel panel = new JPanel(new GridLayout(2, 1));
1059 history.setPreferredSize(new Dimension(400, 20));
1060 history.setEditable(true);
1061 history.addItem("http://www.");
1063 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1067 if (historyItems != null)
1069 st = new StringTokenizer(historyItems, "\t");
1071 while (st.hasMoreTokens())
1073 history.addItem(st.nextElement());
1077 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1078 MessageManager.getString("label.input_alignment_from_url"),
1079 JOptionPane.OK_CANCEL_OPTION);
1081 if (reply != JOptionPane.OK_OPTION)
1086 String url = history.getSelectedItem().toString();
1088 if (url.toLowerCase().endsWith(".jar"))
1090 if (viewport != null)
1092 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1097 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1102 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1104 if (format.equals("URL NOT FOUND"))
1106 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1107 MessageManager.formatMessage("label.couldnt_locate",
1109 { url }), MessageManager
1110 .getString("label.url_not_found"),
1111 JOptionPane.WARNING_MESSAGE);
1116 if (viewport != null)
1118 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1122 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1133 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1135 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1136 cap.setForInput(viewport);
1137 Desktop.addInternalFrame(cap,
1138 MessageManager.getString("label.cut_paste_alignmen_file"),
1147 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1149 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1150 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1152 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1153 getBounds().y, getWidth(), getHeight()));
1155 if (jconsole != null)
1157 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1158 jconsole.stopConsole();
1162 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1165 if (dialogExecutor != null)
1167 dialogExecutor.shutdownNow();
1173 private void storeLastKnownDimensions(String string, Rectangle jc)
1175 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1176 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1177 + " height:" + jc.height);
1179 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1180 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1181 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1182 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1191 public void aboutMenuItem_actionPerformed(ActionEvent e)
1193 // StringBuffer message = getAboutMessage(false);
1194 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1196 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1197 new Thread(new Runnable()
1201 new SplashScreen(true);
1206 public StringBuffer getAboutMessage(boolean shortv)
1208 StringBuffer message = new StringBuffer();
1209 message.append("<html>");
1212 message.append("<h1><strong>Version: "
1213 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1214 message.append("<strong>Last Updated: <em>"
1215 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1216 + "</em></strong>");
1222 message.append("<strong>Version "
1223 + jalview.bin.Cache.getProperty("VERSION")
1224 + "; last updated: "
1225 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1228 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1231 message.append("<br>...Checking latest version...</br>");
1233 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1234 .equals(jalview.bin.Cache.getProperty("VERSION")))
1236 boolean red = false;
1237 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1238 .indexOf("automated build") == -1)
1241 // Displayed when code version and jnlp version do not match and code
1242 // version is not a development build
1243 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1246 message.append("<br>!! Version "
1247 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1249 + " is available for download from "
1250 + jalview.bin.Cache.getDefault("www.jalview.org",
1251 "http://www.jalview.org") + " !!");
1254 message.append("</div>");
1257 message.append("<br>Authors: "
1259 .getDefault("AUTHORFNAMES",
1260 "The Jalview Authors (See AUTHORS file for current list)")
1261 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1262 + "<br><br>For help, see the FAQ at <a href=\"http://www.jalview.org/faq\">www.jalview.org/faq</a> and/or join the jalview-discuss@jalview.org mailing list"
1263 + "<br><br>If you use Jalview, please cite:"
1264 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1265 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1266 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1277 public void documentationMenuItem_actionPerformed(ActionEvent e)
1281 Help.showHelpWindow();
1282 } catch (Exception ex)
1287 public void closeAll_actionPerformed(ActionEvent e)
1289 JInternalFrame[] frames = desktop.getAllFrames();
1290 for (int i = 0; i < frames.length; i++)
1294 frames[i].setClosed(true);
1295 } catch (java.beans.PropertyVetoException ex)
1299 System.out.println("ALL CLOSED");
1300 if (v_client != null)
1302 // TODO clear binding to vamsas document objects on close_all
1307 public void raiseRelated_actionPerformed(ActionEvent e)
1309 reorderAssociatedWindows(false, false);
1312 public void minimizeAssociated_actionPerformed(ActionEvent e)
1314 reorderAssociatedWindows(true, false);
1317 void closeAssociatedWindows()
1319 reorderAssociatedWindows(false, true);
1325 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1328 protected void garbageCollect_actionPerformed(ActionEvent e)
1330 // We simply collect the garbage
1331 jalview.bin.Cache.log.debug("Collecting garbage...");
1333 jalview.bin.Cache.log.debug("Finished garbage collection.");
1340 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1343 protected void showMemusage_actionPerformed(ActionEvent e)
1345 desktop.showMemoryUsage(showMemusage.isSelected());
1352 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1355 protected void showConsole_actionPerformed(ActionEvent e)
1357 showConsole(showConsole.isSelected());
1360 Console jconsole = null;
1363 * control whether the java console is visible or not
1367 void showConsole(boolean selected)
1369 showConsole.setSelected(selected);
1370 // TODO: decide if we should update properties file
1371 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1373 jconsole.setVisible(selected);
1376 void reorderAssociatedWindows(boolean minimize, boolean close)
1378 JInternalFrame[] frames = desktop.getAllFrames();
1379 if (frames == null || frames.length < 1)
1384 AlignmentViewport source = null, target = null;
1385 if (frames[0] instanceof AlignFrame)
1387 source = ((AlignFrame) frames[0]).getCurrentView();
1389 else if (frames[0] instanceof TreePanel)
1391 source = ((TreePanel) frames[0]).getViewPort();
1393 else if (frames[0] instanceof PCAPanel)
1395 source = ((PCAPanel) frames[0]).av;
1397 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1399 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1404 for (int i = 0; i < frames.length; i++)
1407 if (frames[i] == null)
1411 if (frames[i] instanceof AlignFrame)
1413 target = ((AlignFrame) frames[i]).getCurrentView();
1415 else if (frames[i] instanceof TreePanel)
1417 target = ((TreePanel) frames[i]).getViewPort();
1419 else if (frames[i] instanceof PCAPanel)
1421 target = ((PCAPanel) frames[i]).av;
1423 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1425 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1428 if (source == target)
1434 frames[i].setClosed(true);
1438 frames[i].setIcon(minimize);
1441 frames[i].toFront();
1445 } catch (java.beans.PropertyVetoException ex)
1459 protected void preferences_actionPerformed(ActionEvent e)
1470 public void saveState_actionPerformed(ActionEvent e)
1472 JalviewFileChooser chooser = new JalviewFileChooser(
1473 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1474 { "jvp" }, new String[]
1475 { "Jalview Project" }, "Jalview Project");
1477 chooser.setFileView(new JalviewFileView());
1478 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1480 int value = chooser.showSaveDialog(this);
1482 if (value == JalviewFileChooser.APPROVE_OPTION)
1484 final Desktop me = this;
1485 final java.io.File choice = chooser.getSelectedFile();
1486 setProjectFile(choice);
1488 // TODO or move inside the new Thread?
1489 saveChimeraSessions(choice.getAbsolutePath());
1491 new Thread(new Runnable()
1496 setProgressBar(MessageManager.formatMessage(
1497 "label.saving_jalview_project", new Object[]
1498 { choice.getName() }), choice.hashCode());
1499 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1500 choice.getParent());
1501 // TODO catch and handle errors for savestate
1502 // TODO prevent user from messing with the Desktop whilst we're saving
1505 new Jalview2XML().saveState(choice);
1506 } catch (OutOfMemoryError oom)
1508 new OOMWarning("Whilst saving current state to "
1509 + choice.getName(), oom);
1510 } catch (Exception ex)
1513 "Problems whilst trying to save to " + choice.getName(),
1515 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1516 "label.error_whilst_saving_current_state_to",
1518 { choice.getName() }), MessageManager
1519 .getString("label.couldnt_save_project"),
1520 JOptionPane.WARNING_MESSAGE);
1522 setProgressBar(null, choice.hashCode());
1529 * Request any open, linked Chimera sessions to save their state.
1531 * @param jalviewProjectFilename
1532 * the filename of the Jalview project; Chimera session files should
1533 * be given distinct, but obviously related, names.
1535 public void saveChimeraSessions(String jalviewProjectFilename)
1538 for (JInternalFrame frame : getAllFrames())
1540 if (frame instanceof ChimeraViewFrame)
1543 * Construct a filename for the Chimera session by append _chimera<n>.py
1544 * to the Jalview project file name.
1546 String chimeraPath = jalviewProjectFilename + "_chimera_" + i
1548 ((ChimeraViewFrame) frame).saveSession(chimeraPath);
1554 private void setProjectFile(File choice)
1556 this.projectFile = choice;
1559 public File getProjectFile()
1561 return this.projectFile;
1570 public void loadState_actionPerformed(ActionEvent e)
1572 JalviewFileChooser chooser = new JalviewFileChooser(
1573 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1574 { "jvp", "jar" }, new String[]
1575 { "Jalview Project", "Jalview Project (old)" },
1577 chooser.setFileView(new JalviewFileView());
1578 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1580 int value = chooser.showOpenDialog(this);
1582 if (value == JalviewFileChooser.APPROVE_OPTION)
1584 final File selectedFile = chooser.getSelectedFile();
1585 setProjectFile(selectedFile);
1586 final String choice = selectedFile.getAbsolutePath();
1587 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1588 selectedFile.getParent());
1589 new Thread(new Runnable()
1593 setProgressBar(MessageManager.formatMessage(
1594 "label.loading_jalview_project", new Object[]
1595 { choice }), choice.hashCode());
1598 new Jalview2XML().loadJalviewAlign(choice);
1599 } catch (OutOfMemoryError oom)
1601 new OOMWarning("Whilst loading project from " + choice, oom);
1602 } catch (Exception ex)
1604 Cache.log.error("Problems whilst loading project from "
1606 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1608 "label.error_whilst_loading_project_from",
1610 { choice }), MessageManager
1611 .getString("label.couldnt_load_project"),
1612 JOptionPane.WARNING_MESSAGE);
1614 setProgressBar(null, choice.hashCode());
1620 public void inputSequence_actionPerformed(ActionEvent e)
1622 new SequenceFetcher(this);
1625 JPanel progressPanel;
1627 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1629 public void startLoading(final String fileName)
1631 if (fileLoadingCount == 0)
1633 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1634 "label.loading_file", new Object[]
1640 private JPanel addProgressPanel(String string)
1642 if (progressPanel == null)
1644 progressPanel = new JPanel(new GridLayout(1, 1));
1645 totalProgressCount = 0;
1646 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1648 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1649 JProgressBar progressBar = new JProgressBar();
1650 progressBar.setIndeterminate(true);
1652 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1654 thisprogress.add(progressBar, BorderLayout.CENTER);
1655 progressPanel.add(thisprogress);
1656 ((GridLayout) progressPanel.getLayout())
1657 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1658 ++totalProgressCount;
1659 instance.validate();
1660 return thisprogress;
1663 int totalProgressCount = 0;
1665 private void removeProgressPanel(JPanel progbar)
1667 if (progressPanel != null)
1669 synchronized (progressPanel)
1671 progressPanel.remove(progbar);
1672 GridLayout gl = (GridLayout) progressPanel.getLayout();
1673 gl.setRows(gl.getRows() - 1);
1674 if (--totalProgressCount < 1)
1676 this.getContentPane().remove(progressPanel);
1677 progressPanel = null;
1684 public void stopLoading()
1687 if (fileLoadingCount < 1)
1689 while (fileLoadingPanels.size() > 0)
1691 removeProgressPanel(fileLoadingPanels.remove(0));
1693 fileLoadingPanels.clear();
1694 fileLoadingCount = 0;
1699 public static int getViewCount(String alignmentId)
1701 AlignmentViewport[] aps = getViewports(alignmentId);
1702 return (aps == null) ? 0 : aps.length;
1707 * @param alignmentId
1708 * - if null, all sets are returned
1709 * @return all AlignmentPanels concerning the alignmentId sequence set
1711 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1713 if (Desktop.desktop == null)
1715 // no frames created and in headless mode
1716 // TODO: verify that frames are recoverable when in headless mode
1719 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1720 AlignFrame[] frames = getAlignFrames();
1725 for (AlignFrame af : frames)
1727 for (AlignmentPanel ap : af.alignPanels)
1729 if (alignmentId==null || alignmentId.equals(ap.av.getSequenceSetId()))
1735 if (aps.size() == 0)
1739 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1744 * get all the viewports on an alignment.
1746 * @param sequenceSetId
1747 * unique alignment id (may be null - all viewports returned in that
1749 * @return all viewports on the alignment bound to sequenceSetId
1751 public static AlignmentViewport[] getViewports(String sequenceSetId)
1753 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1754 if (desktop != null)
1756 AlignFrame[] frames = Desktop.getAlignFrames();
1758 for (AlignFrame afr : frames)
1760 if (sequenceSetId==null || afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1762 if (afr.alignPanels != null)
1764 for (AlignmentPanel ap : afr.alignPanels)
1766 if (sequenceSetId == null
1767 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1775 viewp.add(afr.getViewport());
1779 if (viewp.size() > 0)
1781 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1788 * Explode the views in the given frame into separate AlignFrame
1792 public void explodeViews(AlignFrame af)
1794 int size = af.alignPanels.size();
1800 for (int i = 0; i < size; i++)
1802 AlignmentPanel ap = af.alignPanels.get(i);
1803 AlignFrame newaf = new AlignFrame(ap);
1806 * Restore the view's last exploded frame geometry if known. Multiple
1807 * views from one exploded frame share and restore the same (frame)
1808 * position and size.
1810 Rectangle geometry = ap.av.getExplodedGeometry();
1811 if (geometry != null)
1813 newaf.setBounds(geometry);
1816 ap.av.setGatherViewsHere(false);
1818 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1819 AlignFrame.DEFAULT_HEIGHT);
1822 af.alignPanels.clear();
1823 af.closeMenuItem_actionPerformed(true);
1828 * Gather expanded views (separate AlignFrame's) with the same sequence set
1829 * identifier back in to this frame as additional views, and close the
1830 * expanded views. Note the expanded frames may themselves have multiple
1831 * views. We take the lot.
1835 public void gatherViews(AlignFrame source)
1837 source.viewport.setGatherViewsHere(true);
1838 source.viewport.setExplodedGeometry(source.getBounds());
1839 JInternalFrame[] frames = desktop.getAllFrames();
1840 String viewId = source.viewport.getSequenceSetId();
1842 for (int t = 0; t < frames.length; t++)
1844 if (frames[t] instanceof AlignFrame && frames[t] != source)
1846 AlignFrame af = (AlignFrame) frames[t];
1847 boolean gatherThis = false;
1848 for (int a = 0; a < af.alignPanels.size(); a++)
1850 AlignmentPanel ap = af.alignPanels.get(a);
1851 if (viewId.equals(ap.av.getSequenceSetId()))
1854 ap.av.setGatherViewsHere(false);
1855 ap.av.setExplodedGeometry(af.getBounds());
1856 source.addAlignmentPanel(ap, false);
1862 af.alignPanels.clear();
1863 af.closeMenuItem_actionPerformed(true);
1870 jalview.gui.VamsasApplication v_client = null;
1872 public void vamsasImport_actionPerformed(ActionEvent e)
1874 if (v_client == null)
1876 // Load and try to start a session.
1877 JalviewFileChooser chooser = new JalviewFileChooser(
1878 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1880 chooser.setFileView(new JalviewFileView());
1881 chooser.setDialogTitle(MessageManager
1882 .getString("label.open_saved_vamsas_session"));
1883 chooser.setToolTipText(MessageManager
1884 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1886 int value = chooser.showOpenDialog(this);
1888 if (value == JalviewFileChooser.APPROVE_OPTION)
1890 String fle = chooser.getSelectedFile().toString();
1891 if (!vamsasImport(chooser.getSelectedFile()))
1894 .showInternalMessageDialog(
1896 MessageManager.formatMessage(
1897 "label.couldnt_import_as_vamsas_session",
1901 .getString("label.vamsas_document_import_failed"),
1902 JOptionPane.ERROR_MESSAGE);
1908 jalview.bin.Cache.log
1909 .error("Implementation error - load session from a running session is not supported.");
1914 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1917 * @return true if import was a success and a session was started.
1919 public boolean vamsasImport(URL url)
1921 // TODO: create progress bar
1922 if (v_client != null)
1925 jalview.bin.Cache.log
1926 .error("Implementation error - load session from a running session is not supported.");
1932 // copy the URL content to a temporary local file
1933 // TODO: be a bit cleverer here with nio (?!)
1934 File file = File.createTempFile("vdocfromurl", ".vdj");
1935 FileOutputStream fos = new FileOutputStream(file);
1936 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1937 byte[] buffer = new byte[2048];
1939 while ((ln = bis.read(buffer)) > -1)
1941 fos.write(buffer, 0, ln);
1945 v_client = new jalview.gui.VamsasApplication(this, file,
1946 url.toExternalForm());
1947 } catch (Exception ex)
1949 jalview.bin.Cache.log.error(
1950 "Failed to create new vamsas session from contents of URL "
1954 setupVamsasConnectedGui();
1955 v_client.initial_update(); // TODO: thread ?
1956 return v_client.inSession();
1960 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1963 * @return true if import was a success and a session was started.
1965 public boolean vamsasImport(File file)
1967 if (v_client != null)
1970 jalview.bin.Cache.log
1971 .error("Implementation error - load session from a running session is not supported.");
1975 setProgressBar(MessageManager.formatMessage(
1976 "status.importing_vamsas_session_from", new Object[]
1977 { file.getName() }), file.hashCode());
1980 v_client = new jalview.gui.VamsasApplication(this, file, null);
1981 } catch (Exception ex)
1983 setProgressBar(MessageManager.formatMessage(
1984 "status.importing_vamsas_session_from", new Object[]
1985 { file.getName() }), file.hashCode());
1986 jalview.bin.Cache.log.error(
1987 "New vamsas session from existing session file failed:", ex);
1990 setupVamsasConnectedGui();
1991 v_client.initial_update(); // TODO: thread ?
1992 setProgressBar(MessageManager.formatMessage(
1993 "status.importing_vamsas_session_from", new Object[]
1994 { file.getName() }), file.hashCode());
1995 return v_client.inSession();
1998 public boolean joinVamsasSession(String mysesid)
2000 if (v_client != null)
2004 .getString("error.try_join_vamsas_session_another"));
2006 if (mysesid == null)
2009 MessageManager.getString("error.invalid_vamsas_session_id"));
2011 v_client = new VamsasApplication(this, mysesid);
2012 setupVamsasConnectedGui();
2013 v_client.initial_update();
2014 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"));
2065 public void vamsasStop_actionPerformed(ActionEvent e)
2067 if (v_client != null)
2069 v_client.end_session();
2071 setupVamsasDisconnectedGui();
2075 protected void buildVamsasStMenu()
2077 if (v_client == null)
2079 String[] sess = null;
2082 sess = VamsasApplication.getSessionList();
2083 } catch (Exception e)
2085 jalview.bin.Cache.log.warn(
2086 "Problem getting current sessions list.", e);
2091 jalview.bin.Cache.log.debug("Got current sessions list: "
2092 + sess.length + " entries.");
2093 VamsasStMenu.removeAll();
2094 for (int i = 0; i < sess.length; i++)
2096 JMenuItem sessit = new JMenuItem();
2097 sessit.setText(sess[i]);
2098 sessit.setToolTipText(MessageManager.formatMessage(
2099 "label.connect_to_session", new Object[]
2101 final Desktop dsktp = this;
2102 final String mysesid = sess[i];
2103 sessit.addActionListener(new ActionListener()
2106 public void actionPerformed(ActionEvent e)
2108 if (dsktp.v_client == null)
2110 Thread rthr = new Thread(new Runnable()
2115 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2116 dsktp.setupVamsasConnectedGui();
2117 dsktp.v_client.initial_update();
2125 VamsasStMenu.add(sessit);
2127 // don't show an empty menu.
2128 VamsasStMenu.setVisible(sess.length > 0);
2133 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2134 VamsasStMenu.removeAll();
2135 VamsasStMenu.setVisible(false);
2140 // Not interested in the content. Just hide ourselves.
2141 VamsasStMenu.setVisible(false);
2145 public void vamsasSave_actionPerformed(ActionEvent e)
2147 if (v_client != null)
2149 JalviewFileChooser chooser = new JalviewFileChooser(
2150 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2151 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2153 { "Vamsas Document" }, "Vamsas Document");
2155 chooser.setFileView(new JalviewFileView());
2156 chooser.setDialogTitle(MessageManager
2157 .getString("label.save_vamsas_document_archive"));
2159 int value = chooser.showSaveDialog(this);
2161 if (value == JalviewFileChooser.APPROVE_OPTION)
2163 java.io.File choice = chooser.getSelectedFile();
2164 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2165 "label.saving_vamsas_doc", new Object[]
2166 { choice.getName() }));
2167 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2168 String warnmsg = null;
2169 String warnttl = null;
2172 v_client.vclient.storeDocument(choice);
2175 warnttl = "Serious Problem saving Vamsas Document";
2176 warnmsg = ex.toString();
2177 jalview.bin.Cache.log.error("Error Whilst saving document to "
2180 } catch (Exception ex)
2182 warnttl = "Problem saving Vamsas Document.";
2183 warnmsg = ex.toString();
2184 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2188 removeProgressPanel(progpanel);
2189 if (warnmsg != null)
2191 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2193 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2199 JPanel vamUpdate = null;
2202 * hide vamsas user gui bits when a vamsas document event is being handled.
2205 * true to hide gui, false to reveal gui
2207 public void setVamsasUpdate(boolean b)
2209 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2210 + (b ? "in progress" : "finished"));
2212 if (vamUpdate != null)
2214 this.removeProgressPanel(vamUpdate);
2218 vamUpdate = this.addProgressPanel(MessageManager
2219 .getString("label.updating_vamsas_session"));
2221 vamsasStart.setVisible(!b);
2222 vamsasStop.setVisible(!b);
2223 vamsasSave.setVisible(!b);
2226 public JInternalFrame[] getAllFrames()
2228 return desktop.getAllFrames();
2232 * Checks the given url to see if it gives a response indicating that the user
2233 * should be informed of a new questionnaire.
2237 public void checkForQuestionnaire(String url)
2239 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2240 // javax.swing.SwingUtilities.invokeLater(jvq);
2241 new Thread(jvq).start();
2245 * Proxy class for JDesktopPane which optionally displays the current memory
2246 * usage and highlights the desktop area with a red bar if free memory runs
2251 public class MyDesktopPane extends JDesktopPane implements Runnable
2254 private static final float ONE_MB = 1048576f;
2256 boolean showMemoryUsage = false;
2260 java.text.NumberFormat df;
2262 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2265 public MyDesktopPane(boolean showMemoryUsage)
2267 showMemoryUsage(showMemoryUsage);
2270 public void showMemoryUsage(boolean showMemoryUsage)
2272 this.showMemoryUsage = showMemoryUsage;
2273 if (showMemoryUsage)
2275 Thread worker = new Thread(this);
2280 public boolean isShowMemoryUsage()
2282 return showMemoryUsage;
2287 df = java.text.NumberFormat.getNumberInstance();
2288 df.setMaximumFractionDigits(2);
2289 runtime = Runtime.getRuntime();
2291 while (showMemoryUsage)
2295 maxMemory = runtime.maxMemory() / ONE_MB;
2296 allocatedMemory = runtime.totalMemory() / ONE_MB;
2297 freeMemory = runtime.freeMemory() / ONE_MB;
2298 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2300 percentUsage = (totalFreeMemory / maxMemory) * 100;
2302 // if (percentUsage < 20)
2304 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2306 // instance.set.setBorder(border1);
2309 // sleep after showing usage
2311 } catch (Exception ex)
2313 ex.printStackTrace();
2318 public void paintComponent(Graphics g)
2320 if (showMemoryUsage && g != null && df != null)
2322 if (percentUsage < 20)
2324 g.setColor(Color.red);
2326 FontMetrics fm = g.getFontMetrics();
2329 g.drawString(MessageManager.formatMessage(
2330 "label.memory_stats",
2332 { df.format(totalFreeMemory), df.format(maxMemory),
2333 df.format(percentUsage) }), 10,
2334 getHeight() - fm.getHeight());
2341 * fixes stacking order after a modal dialog to ensure windows that should be
2342 * on top actually are
2344 public void relayerWindows()
2349 protected JMenuItem groovyShell;
2351 public void doGroovyCheck()
2353 if (jalview.bin.Cache.groovyJarsPresent())
2355 groovyShell = new JMenuItem();
2356 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2357 groovyShell.addActionListener(new ActionListener()
2359 public void actionPerformed(ActionEvent e)
2361 groovyShell_actionPerformed(e);
2364 toolsMenu.add(groovyShell);
2365 groovyShell.setVisible(true);
2370 * Accessor method to quickly get all the AlignmentFrames loaded.
2372 * @return an array of AlignFrame, or null if none found
2374 public static AlignFrame[] getAlignFrames()
2376 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2382 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2384 for (int i = frames.length - 1; i > -1; i--)
2386 if (frames[i] instanceof AlignFrame)
2388 avp.add((AlignFrame) frames[i]);
2390 else if (frames[i] instanceof SplitFrame)
2393 * Also check for a split frame containing an AlignFrame
2395 GSplitFrame sf = (GSplitFrame) frames[i];
2396 if (sf.getTopFrame() instanceof AlignFrame)
2398 avp.add((AlignFrame) sf.getTopFrame());
2400 if (sf.getBottomFrame() instanceof AlignFrame)
2402 avp.add((AlignFrame) sf.getBottomFrame());
2406 if (avp.size() == 0)
2410 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2415 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2419 public GStructureViewer[] getJmols()
2421 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2427 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2429 for (int i = frames.length - 1; i > -1; i--)
2431 if (frames[i] instanceof AppJmol)
2433 GStructureViewer af = (GStructureViewer) frames[i];
2437 if (avp.size() == 0)
2441 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2446 * Add Groovy Support to Jalview
2448 public void groovyShell_actionPerformed(ActionEvent e)
2450 // use reflection to avoid creating compilation dependency.
2451 if (!jalview.bin.Cache.groovyJarsPresent())
2455 .getString("error.implementation_error_cannot_create_groovyshell"));
2459 Class<?> gcClass = Desktop.class.getClassLoader().loadClass(
2460 "groovy.ui.Console");
2461 Constructor<?> gccons = gcClass.getConstructor();
2462 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2464 { String.class, Object.class });
2465 java.lang.reflect.Method run = gcClass.getMethod("run");
2466 Object gc = gccons.newInstance();
2467 setvar.invoke(gc, new Object[]
2468 { "Jalview", this });
2470 } catch (Exception ex)
2472 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2473 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2475 MessageManager.getString("label.couldnt_create_groovy_shell"),
2476 MessageManager.getString("label.groovy_support_failed"),
2477 JOptionPane.ERROR_MESSAGE);
2482 * Progress bars managed by the IProgressIndicator method.
2484 private Hashtable<Long, JPanel> progressBars;
2486 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2491 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2493 public void setProgressBar(String message, long id)
2495 if (progressBars == null)
2497 progressBars = new Hashtable<Long, JPanel>();
2498 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2501 if (progressBars.get(new Long(id)) != null)
2503 JPanel progressPanel = progressBars.remove(new Long(id));
2504 if (progressBarHandlers.contains(new Long(id)))
2506 progressBarHandlers.remove(new Long(id));
2508 removeProgressPanel(progressPanel);
2512 progressBars.put(new Long(id), addProgressPanel(message));
2519 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2520 * jalview.gui.IProgressIndicatorHandler)
2522 public void registerHandler(final long id,
2523 final IProgressIndicatorHandler handler)
2525 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2529 .getString("error.call_setprogressbar_before_registering_handler"));
2531 progressBarHandlers.put(new Long(id), handler);
2532 final JPanel progressPanel = progressBars.get(new Long(id));
2533 if (handler.canCancel())
2535 JButton cancel = new JButton(
2536 MessageManager.getString("action.cancel"));
2537 final IProgressIndicator us = this;
2538 cancel.addActionListener(new ActionListener()
2541 public void actionPerformed(ActionEvent e)
2543 handler.cancelActivity(id);
2544 us.setProgressBar(MessageManager.formatMessage(
2545 "label.cancelled_params", new Object[]
2546 { ((JLabel) progressPanel.getComponent(0)).getText() }),
2550 progressPanel.add(cancel, BorderLayout.EAST);
2556 * @return true if any progress bars are still active
2559 public boolean operationInProgress()
2561 if (progressBars != null && progressBars.size() > 0)
2569 * This will return the first AlignFrame holding the given viewport instance. It
2570 * will break if there are more than one AlignFrames viewing a particular av.
2573 * @return alignFrame for viewport
2575 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2577 if (desktop != null)
2579 AlignmentPanel[] aps = getAlignmentPanels(viewport
2580 .getSequenceSetId());
2581 for (int panel = 0; aps != null && panel < aps.length; panel++)
2583 if (aps[panel] != null && aps[panel].av == viewport)
2585 return aps[panel].alignFrame;
2592 public VamsasApplication getVamsasApplication()
2599 * flag set if jalview GUI is being operated programmatically
2601 private boolean inBatchMode = false;
2604 * check if jalview GUI is being operated programmatically
2606 * @return inBatchMode
2608 public boolean isInBatchMode()
2614 * set flag if jalview GUI is being operated programmatically
2616 * @param inBatchMode
2618 public void setInBatchMode(boolean inBatchMode)
2620 this.inBatchMode = inBatchMode;
2623 public void startServiceDiscovery()
2625 startServiceDiscovery(false);
2628 public void startServiceDiscovery(boolean blocking)
2630 boolean alive = true;
2631 Thread t0 = null, t1 = null, t2 = null;
2632 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2635 // todo: changesupport handlers need to be transferred
2636 if (discoverer == null)
2638 discoverer = new jalview.ws.jws1.Discoverer();
2639 // register PCS handler for desktop.
2640 discoverer.addPropertyChangeListener(changeSupport);
2642 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2643 // until we phase out completely
2644 (t0 = new Thread(discoverer)).start();
2647 // ENFIN services are EOLed as of Jalview 2.8.1 release
2652 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2654 // EnfinEnvision web service menu entries are rebuild every time the
2655 // menu is shown, so no changeSupport events are needed.
2656 jalview.ws.EnfinEnvision2OneWay.getInstance();
2657 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2660 } catch (Exception e)
2663 .info("Exception when trying to launch Envision2 workflow discovery.",
2665 Cache.log.info(e.getStackTrace());
2669 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2671 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2673 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2675 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2681 // TODO: do rest service discovery
2690 } catch (Exception e)
2693 alive = (t1 != null && t1.isAlive())
2694 || (t2 != null && t2.isAlive())
2695 || (t3 != null && t3.isAlive())
2696 || (t0 != null && t0.isAlive());
2702 * called to check if the service discovery process completed successfully.
2706 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2708 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2710 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2711 .getErrorMessages();
2714 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2716 if (serviceChangedDialog == null)
2718 // only run if we aren't already displaying one of these.
2719 addDialogThread(serviceChangedDialog = new Runnable()
2725 * JalviewDialog jd =new JalviewDialog() {
2727 * @Override protected void cancelPressed() { // TODO
2728 * Auto-generated method stub
2730 * }@Override protected void okPressed() { // TODO
2731 * Auto-generated method stub
2733 * }@Override protected void raiseClosed() { // TODO
2734 * Auto-generated method stub
2736 * } }; jd.initDialogFrame(new
2737 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2738 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2739 * + " or mis-configured HTTP proxy settings.<br/>" +
2740 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2742 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2743 * ), true, true, "Web Service Configuration Problem", 450,
2746 * jd.waitForInput();
2752 "<html><table width=\"450\"><tr><td>"
2754 + "</td></tr></table>"
2755 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2756 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2757 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2758 + " Tools->Preferences dialog box to change them.</p></html>"),
2759 "Web Service Configuration Problem",
2760 JOptionPane.DEFAULT_OPTION,
2761 JOptionPane.ERROR_MESSAGE);
2762 serviceChangedDialog = null;
2771 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2778 private Runnable serviceChangedDialog = null;
2781 * start a thread to open a URL in the configured browser. Pops up a warning
2782 * dialog to the user if there is an exception when calling out to the browser
2787 public static void showUrl(final String url)
2789 showUrl(url, Desktop.instance);
2793 * Like showUrl but allows progress handler to be specified
2797 * (null) or object implementing IProgressIndicator
2799 public static void showUrl(final String url,
2800 final IProgressIndicator progress)
2802 new Thread(new Runnable()
2808 if (progress != null)
2810 progress.setProgressBar(MessageManager.formatMessage(
2811 "status.opening_params", new Object[]
2812 { url }), this.hashCode());
2814 jalview.util.BrowserLauncher.openURL(url);
2815 } catch (Exception ex)
2817 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2819 .getString("label.web_browser_not_found_unix"),
2820 MessageManager.getString("label.web_browser_not_found"),
2821 JOptionPane.WARNING_MESSAGE);
2823 ex.printStackTrace();
2825 if (progress != null)
2827 progress.setProgressBar(null, this.hashCode());
2833 public static WsParamSetManager wsparamManager = null;
2835 public static ParamManager getUserParameterStore()
2837 if (wsparamManager == null)
2839 wsparamManager = new WsParamSetManager();
2841 return wsparamManager;
2845 * static hyperlink handler proxy method for use by Jalview's internal windows
2849 public static void hyperlinkUpdate(HyperlinkEvent e)
2851 if (e.getEventType() == EventType.ACTIVATED)
2856 url = e.getURL().toString();
2857 Desktop.showUrl(url);
2858 } catch (Exception x)
2862 if (Cache.log != null)
2864 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2868 System.err.println("Couldn't handle string " + url
2872 // ignore any exceptions due to dud links.
2879 * single thread that handles display of dialogs to user.
2881 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2884 * flag indicating if dialogExecutor should try to acquire a permit
2886 private volatile boolean dialogPause = true;
2891 private java.util.concurrent.Semaphore block = new Semaphore(0);
2894 * add another dialog thread to the queue
2898 public void addDialogThread(final Runnable prompter)
2900 dialogExecutor.submit(new Runnable()
2909 } catch (InterruptedException x)
2914 if (instance == null)
2920 SwingUtilities.invokeAndWait(prompter);
2921 } catch (Exception q)
2923 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2929 public void startDialogQueue()
2931 // set the flag so we don't pause waiting for another permit and semaphore
2932 // the current task to begin
2933 dialogPause = false;
2938 protected void snapShotWindow_actionPerformed(ActionEvent e)
2942 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2943 "View of Desktop", getWidth(), getHeight(), of = new File(
2944 "Jalview_snapshot" + System.currentTimeMillis()
2945 + ".eps"), "View of desktop");
2948 paintAll(im.getGraphics());
2950 } catch (Exception q)
2952 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
2956 Cache.log.info("Successfully written snapshot to file "
2957 + of.getAbsolutePath());
2961 * Explode the views in the given frame into separate AlignFrame windows.
2965 public void explodeViews(SplitFrame sf)
2967 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
2968 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
2969 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
2971 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
2973 int viewCount = topPanels.size();
2980 * Processing in reverse order works, forwards order leaves the first panels
2981 * not visible. I don't know why!
2983 for (int i = viewCount - 1; i >= 0; i--)
2986 * Make new top and bottom frames. These take over the respective
2987 * AlignmentPanel objects, including their AlignmentViewports, so the
2988 * cdna/protein relationships between the viewports is carried over to the
2991 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
2992 AlignFrame newTopFrame = new AlignFrame(topPanel);
2993 newTopFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
2994 AlignFrame.DEFAULT_HEIGHT));
2995 newTopFrame.setVisible(true);
2996 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
2997 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
2998 newBottomFrame.setSize(new Dimension(AlignFrame.DEFAULT_WIDTH,
2999 AlignFrame.DEFAULT_HEIGHT));
3000 newBottomFrame.setVisible(true);
3001 topPanel.av.setGatherViewsHere(false);
3002 bottomPanel.av.setGatherViewsHere(false);
3003 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3005 // either panel may hold previous exploded frame geometry
3006 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3007 .getExplodedGeometry();
3008 if (geometry != null)
3010 splitFrame.setBounds(geometry);
3012 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3016 * Clear references to the panels (now relocated in the new SplitFrames)
3017 * before closing the old SplitFrame.
3020 bottomPanels.clear();
3025 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3026 * back into the given SplitFrame as additional views. Note that the gathered
3027 * frames may themselves have multiple views.
3031 public void gatherViews(GSplitFrame source)
3033 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3034 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3035 myTopFrame.viewport.setExplodedGeometry(source.getBounds());
3036 myBottomFrame.viewport.setExplodedGeometry(source.getBounds());
3037 myTopFrame.viewport.setGatherViewsHere(true);
3038 myBottomFrame.viewport.setGatherViewsHere(true);
3039 String topViewId = myTopFrame.viewport.getSequenceSetId();
3040 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3042 JInternalFrame[] frames = desktop.getAllFrames();
3043 for (JInternalFrame frame : frames)
3045 if (frame instanceof SplitFrame && frame != source)
3047 SplitFrame sf = (SplitFrame) frame;
3048 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3049 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3050 boolean gatherThis = false;
3051 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3053 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3054 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3055 if (topViewId.equals(topPanel.av.getSequenceSetId())
3056 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3059 topPanel.av.setGatherViewsHere(false);
3060 bottomPanel.av.setGatherViewsHere(false);
3061 // both panels refer to the same split frame geometry
3062 Rectangle position = sf.getBounds();
3063 topPanel.av.setExplodedGeometry(position);
3064 bottomPanel.av.setExplodedGeometry(position);
3065 myTopFrame.addAlignmentPanel(topPanel, false);
3066 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3072 topFrame.getAlignPanels().clear();
3073 bottomFrame.getAlignPanels().clear();
3080 * The dust settles...give focus to the tab we did this from.
3082 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3086 // public static AlignFrame getCurrentAlignFrame()
3088 // return currentAlignFrame;
3091 // public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
3093 // Desktop.currentAlignFrame = currentAlignFrame;