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.bin.Jalview;
27 import jalview.io.FileLoader;
28 import jalview.io.FormatAdapter;
29 import jalview.io.IdentifyFile;
30 import jalview.io.JalviewFileChooser;
31 import jalview.io.JalviewFileView;
32 import jalview.jbgui.GSplitFrame;
33 import jalview.jbgui.GStructureViewer;
34 import jalview.structure.StructureSelectionManager;
35 import jalview.util.ImageMaker;
36 import jalview.util.MessageManager;
37 import jalview.util.Platform;
38 import jalview.viewmodel.AlignmentViewport;
39 import jalview.ws.params.ParamManager;
41 import java.awt.BorderLayout;
42 import java.awt.Color;
43 import java.awt.Dimension;
44 import java.awt.FontMetrics;
45 import java.awt.Graphics;
46 import java.awt.GridLayout;
47 import java.awt.Point;
48 import java.awt.Rectangle;
49 import java.awt.Toolkit;
50 import java.awt.datatransfer.Clipboard;
51 import java.awt.datatransfer.ClipboardOwner;
52 import java.awt.datatransfer.DataFlavor;
53 import java.awt.datatransfer.Transferable;
54 import java.awt.dnd.DnDConstants;
55 import java.awt.dnd.DropTargetDragEvent;
56 import java.awt.dnd.DropTargetDropEvent;
57 import java.awt.dnd.DropTargetEvent;
58 import java.awt.dnd.DropTargetListener;
59 import java.awt.event.ActionEvent;
60 import java.awt.event.ActionListener;
61 import java.awt.event.FocusEvent;
62 import java.awt.event.FocusListener;
63 import java.awt.event.MouseAdapter;
64 import java.awt.event.MouseEvent;
65 import java.awt.event.MouseListener;
66 import java.awt.event.WindowAdapter;
67 import java.awt.event.WindowEvent;
68 import java.beans.PropertyChangeEvent;
69 import java.beans.PropertyChangeListener;
70 import java.beans.PropertyVetoException;
71 import java.io.BufferedInputStream;
73 import java.io.FileOutputStream;
74 import java.lang.reflect.Constructor;
76 import java.util.ArrayList;
77 import java.util.Hashtable;
78 import java.util.List;
79 import java.util.StringTokenizer;
80 import java.util.Vector;
81 import java.util.concurrent.ExecutorService;
82 import java.util.concurrent.Executors;
83 import java.util.concurrent.Semaphore;
85 import javax.swing.DefaultDesktopManager;
86 import javax.swing.DesktopManager;
87 import javax.swing.JButton;
88 import javax.swing.JComboBox;
89 import javax.swing.JComponent;
90 import javax.swing.JDesktopPane;
91 import javax.swing.JFrame;
92 import javax.swing.JInternalFrame;
93 import javax.swing.JLabel;
94 import javax.swing.JMenuItem;
95 import javax.swing.JOptionPane;
96 import javax.swing.JPanel;
97 import javax.swing.JPopupMenu;
98 import javax.swing.JProgressBar;
99 import javax.swing.SwingUtilities;
100 import javax.swing.event.HyperlinkEvent;
101 import javax.swing.event.HyperlinkEvent.EventType;
102 import javax.swing.event.MenuEvent;
103 import javax.swing.event.MenuListener;
110 * @version $Revision: 1.155 $
112 public class Desktop extends jalview.jbgui.GDesktop implements
113 DropTargetListener, ClipboardOwner, IProgressIndicator,
114 jalview.api.StructureSelectionManagerProvider
117 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
120 * news reader - null if it was never started.
122 private BlogReader jvnews = null;
124 private File projectFile;
128 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
130 public void addJalviewPropertyChangeListener(
131 PropertyChangeListener listener)
133 changeSupport.addJalviewPropertyChangeListener(listener);
137 * @param propertyName
139 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
140 * java.beans.PropertyChangeListener)
142 public void addJalviewPropertyChangeListener(String propertyName,
143 PropertyChangeListener listener)
145 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
149 * @param propertyName
151 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
152 * java.beans.PropertyChangeListener)
154 public void removeJalviewPropertyChangeListener(String propertyName,
155 PropertyChangeListener listener)
157 changeSupport.removeJalviewPropertyChangeListener(propertyName,
161 /** Singleton Desktop instance */
162 public static Desktop instance;
164 public static MyDesktopPane desktop;
166 static int openFrameCount = 0;
168 static final int xOffset = 30;
170 static final int yOffset = 30;
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;
193 public void activateFrame(JInternalFrame f)
197 delegate.activateFrame(f);
198 } catch (NullPointerException npe)
200 Point p = getMousePosition();
201 instance.showPasteMenu(p.x, p.y);
206 public void beginDraggingFrame(JComponent f)
208 delegate.beginDraggingFrame(f);
212 public void beginResizingFrame(JComponent f, int direction)
214 delegate.beginResizingFrame(f, direction);
218 public void closeFrame(JInternalFrame f)
220 delegate.closeFrame(f);
224 public void deactivateFrame(JInternalFrame f)
226 delegate.deactivateFrame(f);
230 public void deiconifyFrame(JInternalFrame f)
232 delegate.deiconifyFrame(f);
236 public void dragFrame(JComponent f, int newX, int newY)
242 delegate.dragFrame(f, newX, newY);
246 public void endDraggingFrame(JComponent f)
248 delegate.endDraggingFrame(f);
252 public void endResizingFrame(JComponent f)
254 delegate.endResizingFrame(f);
258 public void iconifyFrame(JInternalFrame f)
260 delegate.iconifyFrame(f);
264 public void maximizeFrame(JInternalFrame f)
266 delegate.maximizeFrame(f);
270 public void minimizeFrame(JInternalFrame f)
272 delegate.minimizeFrame(f);
276 public void openFrame(JInternalFrame f)
278 delegate.openFrame(f);
282 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
289 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
293 public void setBoundsForFrame(JComponent f, int newX, int newY,
294 int newWidth, int newHeight)
296 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
299 // All other methods, simply delegate
304 * Creates a new Desktop object.
309 * A note to implementors. It is ESSENTIAL that any activities that might
310 * block are spawned off as threads rather than waited for during this
314 doVamsasClientCheck();
316 doConfigureStructurePrefs();
317 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
318 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
319 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
321 boolean showjconsole = jalview.bin.Cache.getDefault(
322 "SHOW_JAVA_CONSOLE", false);
323 desktop = new MyDesktopPane(selmemusage);
324 if (Platform.isAMac())
326 desktop.setDoubleBuffered(false);
328 showMemusage.setSelected(selmemusage);
329 desktop.setBackground(Color.white);
330 getContentPane().setLayout(new BorderLayout());
331 // alternate config - have scrollbars - see notes in JAL-153
332 // JScrollPane sp = new JScrollPane();
333 // sp.getViewport().setView(desktop);
334 // getContentPane().add(sp, BorderLayout.CENTER);
335 getContentPane().add(desktop, BorderLayout.CENTER);
336 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
338 // This line prevents Windows Look&Feel resizing all new windows to maximum
339 // if previous window was maximised
340 desktop.setDesktopManager(new MyDesktopManager(
341 new DefaultDesktopManager()));
343 Rectangle dims = getLastKnownDimensions("");
350 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
351 setBounds((screenSize.width - 900) / 2,
352 (screenSize.height - 650) / 2, 900, 650);
354 jconsole = new Console(this, showjconsole);
355 // add essential build information
356 jconsole.setHeader("Jalview Version: "
357 + jalview.bin.Cache.getProperty("VERSION") + "\n"
358 + "Jalview Installation: "
359 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
360 + "\n" + "Build Date: "
361 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
362 + "Java version: " + System.getProperty("java.version") + "\n"
363 + System.getProperty("os.arch") + " "
364 + System.getProperty("os.name") + " "
365 + System.getProperty("os.version"));
367 showConsole(showjconsole);
369 showNews.setVisible(false);
371 this.addWindowListener(new WindowAdapter()
374 public void windowClosing(WindowEvent evt)
381 this.addMouseListener(ma = new MouseAdapter()
384 public void mousePressed(MouseEvent evt)
386 if (SwingUtilities.isRightMouseButton(evt))
388 showPasteMenu(evt.getX(), evt.getY());
392 desktop.addMouseListener(ma);
394 this.addFocusListener(new FocusListener()
398 public void focusLost(FocusEvent e)
400 // TODO Auto-generated method stub
405 public void focusGained(FocusEvent e)
407 Cache.log.debug("Relaying windows after focus gain");
408 // make sure that we sort windows properly after we gain focus
409 instance.relayerWindows();
412 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
413 // Spawn a thread that shows the splashscreen
414 SwingUtilities.invokeLater(new Runnable()
424 // Thread off a new instance of the file chooser - this reduces the time it
425 // takes to open it later on.
426 new Thread(new Runnable()
431 Cache.log.debug("Filechooser init thread started.");
432 new JalviewFileChooser(
433 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
434 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
435 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
436 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
437 Cache.log.debug("Filechooser init thread finished.");
440 // Add the service change listener
441 changeSupport.addJalviewPropertyChangeListener("services",
442 new PropertyChangeListener()
446 public void propertyChange(PropertyChangeEvent evt)
448 Cache.log.debug("Firing service changed event for "
449 + evt.getNewValue());
450 JalviewServicesChanged(evt);
456 public void doConfigureStructurePrefs()
458 // configure services
459 StructureSelectionManager ssm = StructureSelectionManager
460 .getStructureSelectionManager(this);
461 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
463 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
464 Preferences.ADD_TEMPFACT_ANN, true));
465 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
466 Preferences.STRUCT_FROM_PDB, true));
467 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
468 Preferences.USE_RNAVIEW, true));
472 ssm.setAddTempFacAnnot(false);
473 ssm.setProcessSecondaryStructure(false);
474 ssm.setSecStructServices(false);
478 public void checkForNews()
480 final Desktop me = this;
481 // Thread off the news reader, in case there are connection problems.
482 addDialogThread(new Runnable()
487 Cache.log.debug("Starting news thread.");
489 jvnews = new BlogReader(me);
490 showNews.setVisible(true);
491 Cache.log.debug("Completed news thread.");
497 protected void showNews_actionPerformed(ActionEvent e)
499 showNews(showNews.isSelected());
502 void showNews(boolean visible)
505 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
506 showNews.setSelected(visible);
507 if (visible && !jvnews.isVisible())
509 new Thread(new Runnable()
514 long now = System.currentTimeMillis();
515 Desktop.instance.setProgressBar(
516 MessageManager.getString("status.refreshing_news"), now);
517 jvnews.refreshNews();
518 Desktop.instance.setProgressBar(null, now);
527 * recover the last known dimensions for a jalview window
530 * - empty string is desktop, all other windows have unique prefix
531 * @return null or last known dimensions scaled to current geometry (if last
532 * window geom was known)
534 Rectangle getLastKnownDimensions(String windowName)
536 // TODO: lock aspect ratio for scaling desktop Bug #0058199
537 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
538 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
539 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
540 String width = jalview.bin.Cache.getProperty(windowName
542 String height = jalview.bin.Cache.getProperty(windowName
544 if ((x != null) && (y != null) && (width != null) && (height != null))
546 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
547 .parseInt(width), ih = Integer.parseInt(height);
548 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
550 // attempt #1 - try to cope with change in screen geometry - this
551 // version doesn't preserve original jv aspect ratio.
552 // take ratio of current screen size vs original screen size.
553 double sw = ((1f * screenSize.width) / (1f * Integer
554 .parseInt(jalview.bin.Cache
555 .getProperty("SCREENGEOMETRY_WIDTH"))));
556 double sh = ((1f * screenSize.height) / (1f * Integer
557 .parseInt(jalview.bin.Cache
558 .getProperty("SCREENGEOMETRY_HEIGHT"))));
559 // rescale the bounds depending upon the current screen geometry.
560 ix = (int) (ix * sw);
561 iw = (int) (iw * sw);
562 iy = (int) (iy * sh);
563 ih = (int) (ih * sh);
564 while (ix >= screenSize.width)
566 jalview.bin.Cache.log
567 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
568 ix -= screenSize.width;
570 while (iy >= screenSize.height)
572 jalview.bin.Cache.log
573 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
574 iy -= screenSize.height;
576 jalview.bin.Cache.log.debug("Got last known dimensions for "
577 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
580 // return dimensions for new instance
581 return new Rectangle(ix, iy, iw, ih);
586 private void doVamsasClientCheck()
588 if (jalview.bin.Cache.vamsasJarsPresent())
590 setupVamsasDisconnectedGui();
591 VamsasMenu.setVisible(true);
592 final Desktop us = this;
593 VamsasMenu.addMenuListener(new MenuListener()
595 // this listener remembers when the menu was first selected, and
596 // doesn't rebuild the session list until it has been cleared and
598 boolean refresh = true;
601 public void menuCanceled(MenuEvent e)
607 public void menuDeselected(MenuEvent e)
613 public void menuSelected(MenuEvent e)
617 us.buildVamsasStMenu();
622 vamsasStart.setVisible(true);
626 void showPasteMenu(int x, int y)
628 JPopupMenu popup = new JPopupMenu();
629 JMenuItem item = new JMenuItem(
630 MessageManager.getString("label.paste_new_window"));
631 item.addActionListener(new ActionListener()
634 public void actionPerformed(ActionEvent evt)
641 popup.show(this, x, y);
648 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
649 Transferable contents = c.getContents(this);
651 if (contents != null)
653 String file = (String) contents
654 .getTransferData(DataFlavor.stringFlavor);
656 String format = new IdentifyFile().identify(file,
657 FormatAdapter.PASTE);
659 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
662 } catch (Exception ex)
665 .println("Unable to paste alignment from system clipboard:\n"
671 * Adds and opens the given frame to the desktop
682 public static synchronized void addInternalFrame(
683 final JInternalFrame frame, String title, int w, int h)
685 addInternalFrame(frame, title, true, w, h, true);
689 * Add an internal frame to the Jalview desktop
696 * When true, display frame immediately, otherwise, caller must call
697 * setVisible themselves.
703 public static synchronized void addInternalFrame(
704 final JInternalFrame frame, String title, boolean makeVisible,
707 addInternalFrame(frame, title, makeVisible, w, h, true);
711 * Add an internal frame to the Jalview desktop and make it visible
724 public static synchronized void addInternalFrame(
725 final JInternalFrame frame, String title, int w, int h,
728 addInternalFrame(frame, title, true, w, h, resizable);
732 * Add an internal frame to the Jalview desktop
739 * When true, display frame immediately, otherwise, caller must call
740 * setVisible themselves.
748 public static synchronized void addInternalFrame(
749 final JInternalFrame frame, String title, boolean makeVisible,
750 int w, int h, boolean resizable)
753 // TODO: allow callers to determine X and Y position of frame (eg. via
755 // TODO: consider fixing method to update entries in the window submenu with
756 // the current window title
758 frame.setTitle(title);
759 if (frame.getWidth() < 1 || frame.getHeight() < 1)
763 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
764 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
765 // IF JALVIEW IS RUNNING HEADLESS
766 // ///////////////////////////////////////////////
768 || (System.getProperty("java.awt.headless") != null && System
769 .getProperty("java.awt.headless").equals("true")))
776 frame.setVisible(makeVisible);
777 frame.setClosable(true);
778 frame.setResizable(resizable);
779 frame.setMaximizable(resizable);
780 frame.setIconifiable(resizable);
781 if (Platform.isAMac())
783 frame.setIconifiable(false);
784 frame.setFrameIcon(null);
785 // frame.setDesktopIcon(null);
786 frame.setDoubleBuffered(false);
788 if (frame.getX() < 1 && frame.getY() < 1)
790 frame.setLocation(xOffset * openFrameCount, yOffset
791 * ((openFrameCount - 1) % 10) + yOffset);
794 final JMenuItem menuItem = new JMenuItem(title);
795 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
798 public void internalFrameActivated(
799 javax.swing.event.InternalFrameEvent evt)
801 JInternalFrame itf = desktop.getSelectedFrame();
810 public void internalFrameClosed(
811 javax.swing.event.InternalFrameEvent evt)
813 PaintRefresher.RemoveComponent(frame);
815 windowMenu.remove(menuItem);
816 JInternalFrame itf = desktop.getSelectedFrame();
825 menuItem.addActionListener(new ActionListener()
828 public void actionPerformed(ActionEvent e)
832 frame.setSelected(true);
833 frame.setIcon(false);
834 } catch (java.beans.PropertyVetoException ex)
840 menuItem.addMouseListener(new MouseListener()
844 public void mouseReleased(MouseEvent e)
849 public void mousePressed(MouseEvent e)
854 public void mouseExited(MouseEvent e)
858 frame.setSelected(false);
859 } catch (PropertyVetoException e1)
865 public void mouseEntered(MouseEvent e)
869 frame.setSelected(true);
870 } catch (PropertyVetoException e1)
876 public void mouseClicked(MouseEvent e)
882 windowMenu.add(menuItem);
888 frame.setSelected(true);
889 frame.requestFocus();
890 } catch (java.beans.PropertyVetoException ve)
892 } catch (java.lang.ClassCastException cex)
895 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
901 public void lostOwnership(Clipboard clipboard, Transferable contents)
905 Desktop.jalviewClipboard = null;
908 internalCopy = false;
912 public void dragEnter(DropTargetDragEvent evt)
917 public void dragExit(DropTargetEvent evt)
922 public void dragOver(DropTargetDragEvent evt)
927 public void dropActionChanged(DropTargetDragEvent evt)
938 public void drop(DropTargetDropEvent evt)
940 boolean success = true;
941 Transferable t = evt.getTransferable();
942 java.util.List files = null;
943 java.util.List protocols = null;
947 DataFlavor uriListFlavor = new DataFlavor(
948 "text/uri-list;class=java.lang.String");
949 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
951 // Works on Windows and MacOSX
952 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
953 files = (java.util.List) t
954 .getTransferData(DataFlavor.javaFileListFlavor);
956 else if (t.isDataFlavorSupported(uriListFlavor))
958 // This is used by Unix drag system
959 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
960 String data = (String) t.getTransferData(uriListFlavor);
961 files = new java.util.ArrayList(1);
962 protocols = new java.util.ArrayList(1);
963 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
964 data, "\r\n"); st.hasMoreTokens();)
966 String s = st.nextToken();
967 if (s.startsWith("#"))
969 // the line is a comment (as per the RFC 2483)
972 java.net.URI uri = new java.net.URI(s);
973 if (uri.getScheme().toLowerCase().startsWith("http"))
975 protocols.add(FormatAdapter.URL);
976 files.add(uri.toString());
980 // otherwise preserve old behaviour: catch all for file objects
981 java.io.File file = new java.io.File(uri);
982 protocols.add(FormatAdapter.FILE);
983 files.add(file.toString());
987 } catch (Exception e)
996 for (int i = 0; i < files.size(); i++)
998 String file = files.get(i).toString();
999 String protocol = (protocols == null) ? FormatAdapter.FILE
1000 : (String) protocols.get(i);
1001 String format = null;
1003 if (file.endsWith(".jar"))
1010 format = new IdentifyFile().identify(file, protocol);
1013 new FileLoader().LoadFile(file, protocol, format);
1016 } catch (Exception ex)
1021 evt.dropComplete(success); // need this to ensure input focus is properly
1022 // transfered to any new windows created
1032 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1034 JalviewFileChooser chooser = new JalviewFileChooser(
1035 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1036 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1037 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1038 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1040 chooser.setFileView(new JalviewFileView());
1041 chooser.setDialogTitle(MessageManager
1042 .getString("label.open_local_file"));
1043 chooser.setToolTipText(MessageManager.getString("action.open"));
1045 int value = chooser.showOpenDialog(this);
1047 if (value == JalviewFileChooser.APPROVE_OPTION)
1049 String choice = chooser.getSelectedFile().getPath();
1050 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1051 .getSelectedFile().getParent());
1053 String format = null;
1054 if (chooser.getSelectedFormat() != null
1055 && chooser.getSelectedFormat().equals("Jalview"))
1061 format = new IdentifyFile().identify(choice, FormatAdapter.FILE);
1064 if (viewport != null)
1066 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1071 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1083 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1085 // This construct allows us to have a wider textfield
1087 JLabel label = new JLabel(
1088 MessageManager.getString("label.input_file_url"));
1089 final JComboBox history = new JComboBox();
1091 JPanel panel = new JPanel(new GridLayout(2, 1));
1094 history.setPreferredSize(new Dimension(400, 20));
1095 history.setEditable(true);
1096 history.addItem("http://www.");
1098 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1102 if (historyItems != null)
1104 st = new StringTokenizer(historyItems, "\t");
1106 while (st.hasMoreTokens())
1108 history.addItem(st.nextElement());
1112 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1113 MessageManager.getString("label.input_alignment_from_url"),
1114 JOptionPane.OK_CANCEL_OPTION);
1116 if (reply != JOptionPane.OK_OPTION)
1121 String url = history.getSelectedItem().toString();
1123 if (url.toLowerCase().endsWith(".jar"))
1125 if (viewport != null)
1127 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1132 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1137 String format = new IdentifyFile().identify(url, FormatAdapter.URL);
1139 if (format.equals("URL NOT FOUND"))
1141 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1142 MessageManager.formatMessage("label.couldnt_locate",
1143 new Object[] { url }), MessageManager
1144 .getString("label.url_not_found"),
1145 JOptionPane.WARNING_MESSAGE);
1150 if (viewport != null)
1152 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1156 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1162 * Opens the CutAndPaste window for the user to paste an alignment in to
1165 * - if not null, the pasted alignment is added to the current
1166 * alignment; if null, to a new alignment window
1169 public void inputTextboxMenuItem_actionPerformed(
1170 AlignmentViewPanel viewPanel)
1172 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1173 cap.setForInput(viewPanel);
1174 Desktop.addInternalFrame(cap,
1175 MessageManager.getString("label.cut_paste_alignmen_file"),
1185 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1187 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1188 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1190 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1191 getBounds().y, getWidth(), getHeight()));
1193 if (jconsole != null)
1195 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1196 jconsole.stopConsole();
1200 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1203 if (dialogExecutor != null)
1205 dialogExecutor.shutdownNow();
1207 closeAll_actionPerformed(null);
1211 private void storeLastKnownDimensions(String string, Rectangle jc)
1213 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1214 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1215 + " height:" + jc.height);
1217 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1218 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1219 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1220 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1230 public void aboutMenuItem_actionPerformed(ActionEvent e)
1232 // StringBuffer message = getAboutMessage(false);
1233 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1235 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1236 new Thread(new Runnable()
1241 new SplashScreen(true);
1246 public StringBuffer getAboutMessage(boolean shortv)
1248 StringBuffer message = new StringBuffer();
1249 message.append("<html>");
1252 message.append("<h1><strong>Version: "
1253 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1254 message.append("<strong>Last Updated: <em>"
1255 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1256 + "</em></strong>");
1262 message.append("<strong>Version "
1263 + jalview.bin.Cache.getProperty("VERSION")
1264 + "; last updated: "
1265 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1268 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1271 message.append("<br>...Checking latest version...</br>");
1273 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1274 .equals(jalview.bin.Cache.getProperty("VERSION")))
1276 boolean red = false;
1277 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1278 .indexOf("automated build") == -1)
1281 // Displayed when code version and jnlp version do not match and code
1282 // version is not a development build
1283 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1286 message.append("<br>!! Version "
1287 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1289 + " is available for download from "
1290 + jalview.bin.Cache.getDefault("www.jalview.org",
1291 "http://www.jalview.org") + " !!");
1294 message.append("</div>");
1297 message.append("<br>Authors: "
1299 .getDefault("AUTHORFNAMES",
1300 "The Jalview Authors (See AUTHORS file for current list)")
1301 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1302 + "<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"
1303 + "<br><br>If you use Jalview, please cite:"
1304 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1305 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1306 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1318 public void documentationMenuItem_actionPerformed(ActionEvent e)
1322 Help.showHelpWindow();
1323 } catch (Exception ex)
1329 public void closeAll_actionPerformed(ActionEvent e)
1331 JInternalFrame[] frames = desktop.getAllFrames();
1332 for (int i = 0; i < frames.length; i++)
1336 frames[i].setClosed(true);
1337 } catch (java.beans.PropertyVetoException ex)
1341 System.out.println("ALL CLOSED");
1342 if (v_client != null)
1344 // TODO clear binding to vamsas document objects on close_all
1348 * reset state of singleton objects as appropriate (clear down session state
1349 * when all windows are closed)
1351 StructureSelectionManager ssm = StructureSelectionManager
1352 .getStructureSelectionManager(this);
1360 public void raiseRelated_actionPerformed(ActionEvent e)
1362 reorderAssociatedWindows(false, false);
1366 public void minimizeAssociated_actionPerformed(ActionEvent e)
1368 reorderAssociatedWindows(true, false);
1371 void closeAssociatedWindows()
1373 reorderAssociatedWindows(false, true);
1379 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1383 protected void garbageCollect_actionPerformed(ActionEvent e)
1385 // We simply collect the garbage
1386 jalview.bin.Cache.log.debug("Collecting garbage...");
1388 jalview.bin.Cache.log.debug("Finished garbage collection.");
1395 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1399 protected void showMemusage_actionPerformed(ActionEvent e)
1401 desktop.showMemoryUsage(showMemusage.isSelected());
1408 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1412 protected void showConsole_actionPerformed(ActionEvent e)
1414 showConsole(showConsole.isSelected());
1417 Console jconsole = null;
1420 * control whether the java console is visible or not
1424 void showConsole(boolean selected)
1426 showConsole.setSelected(selected);
1427 // TODO: decide if we should update properties file
1428 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1430 jconsole.setVisible(selected);
1433 void reorderAssociatedWindows(boolean minimize, boolean close)
1435 JInternalFrame[] frames = desktop.getAllFrames();
1436 if (frames == null || frames.length < 1)
1441 AlignmentViewport source = null, target = null;
1442 if (frames[0] instanceof AlignFrame)
1444 source = ((AlignFrame) frames[0]).getCurrentView();
1446 else if (frames[0] instanceof TreePanel)
1448 source = ((TreePanel) frames[0]).getViewPort();
1450 else if (frames[0] instanceof PCAPanel)
1452 source = ((PCAPanel) frames[0]).av;
1454 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1456 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1461 for (int i = 0; i < frames.length; i++)
1464 if (frames[i] == null)
1468 if (frames[i] instanceof AlignFrame)
1470 target = ((AlignFrame) frames[i]).getCurrentView();
1472 else if (frames[i] instanceof TreePanel)
1474 target = ((TreePanel) frames[i]).getViewPort();
1476 else if (frames[i] instanceof PCAPanel)
1478 target = ((PCAPanel) frames[i]).av;
1480 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1482 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1485 if (source == target)
1491 frames[i].setClosed(true);
1495 frames[i].setIcon(minimize);
1498 frames[i].toFront();
1502 } catch (java.beans.PropertyVetoException ex)
1517 protected void preferences_actionPerformed(ActionEvent e)
1529 public void saveState_actionPerformed(ActionEvent e)
1531 JalviewFileChooser chooser = new JalviewFileChooser(
1532 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1533 new String[] { "jvp" }, new String[] { "Jalview Project" },
1536 chooser.setFileView(new JalviewFileView());
1537 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1539 int value = chooser.showSaveDialog(this);
1541 if (value == JalviewFileChooser.APPROVE_OPTION)
1543 final Desktop me = this;
1544 final java.io.File choice = chooser.getSelectedFile();
1545 setProjectFile(choice);
1547 new Thread(new Runnable()
1552 // TODO: refactor to Jalview desktop session controller action.
1553 setProgressBar(MessageManager.formatMessage(
1554 "label.saving_jalview_project",
1555 new Object[] { choice.getName() }), choice.hashCode());
1556 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1557 choice.getParent());
1558 // TODO catch and handle errors for savestate
1559 // TODO prevent user from messing with the Desktop whilst we're saving
1562 new Jalview2XML().saveState(choice);
1563 } catch (OutOfMemoryError oom)
1565 new OOMWarning("Whilst saving current state to "
1566 + choice.getName(), oom);
1567 } catch (Exception ex)
1570 "Problems whilst trying to save to " + choice.getName(),
1572 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1573 "label.error_whilst_saving_current_state_to",
1574 new Object[] { choice.getName() }), MessageManager
1575 .getString("label.couldnt_save_project"),
1576 JOptionPane.WARNING_MESSAGE);
1578 setProgressBar(null, choice.hashCode());
1584 private void setProjectFile(File choice)
1586 this.projectFile = choice;
1589 public File getProjectFile()
1591 return this.projectFile;
1601 public void loadState_actionPerformed(ActionEvent e)
1603 JalviewFileChooser chooser = new JalviewFileChooser(
1604 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1605 "jvp", "jar" }, new String[] { "Jalview Project",
1606 "Jalview Project (old)" }, "Jalview Project");
1607 chooser.setFileView(new JalviewFileView());
1608 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1610 int value = chooser.showOpenDialog(this);
1612 if (value == JalviewFileChooser.APPROVE_OPTION)
1614 final File selectedFile = chooser.getSelectedFile();
1615 setProjectFile(selectedFile);
1616 final String choice = selectedFile.getAbsolutePath();
1617 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1618 selectedFile.getParent());
1619 new Thread(new Runnable()
1625 MessageManager.formatMessage(
1626 "label.loading_jalview_project",
1627 new Object[] { choice }), choice.hashCode());
1630 new Jalview2XML().loadJalviewAlign(choice);
1631 } catch (OutOfMemoryError oom)
1633 new OOMWarning("Whilst loading project from " + choice, oom);
1634 } catch (Exception ex)
1636 Cache.log.error("Problems whilst loading project from "
1638 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1640 "label.error_whilst_loading_project_from",
1641 new Object[] { choice }), MessageManager
1642 .getString("label.couldnt_load_project"),
1643 JOptionPane.WARNING_MESSAGE);
1645 setProgressBar(null, choice.hashCode());
1652 public void inputSequence_actionPerformed(ActionEvent e)
1654 new SequenceFetcher(this);
1657 JPanel progressPanel;
1659 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1661 public void startLoading(final String fileName)
1663 if (fileLoadingCount == 0)
1665 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1666 "label.loading_file", new Object[] { fileName })));
1671 private JPanel addProgressPanel(String string)
1673 if (progressPanel == null)
1675 progressPanel = new JPanel(new GridLayout(1, 1));
1676 totalProgressCount = 0;
1677 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1679 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1680 JProgressBar progressBar = new JProgressBar();
1681 progressBar.setIndeterminate(true);
1683 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1685 thisprogress.add(progressBar, BorderLayout.CENTER);
1686 progressPanel.add(thisprogress);
1687 ((GridLayout) progressPanel.getLayout())
1688 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1689 ++totalProgressCount;
1690 instance.validate();
1691 return thisprogress;
1694 int totalProgressCount = 0;
1696 private void removeProgressPanel(JPanel progbar)
1698 if (progressPanel != null)
1700 synchronized (progressPanel)
1702 progressPanel.remove(progbar);
1703 GridLayout gl = (GridLayout) progressPanel.getLayout();
1704 gl.setRows(gl.getRows() - 1);
1705 if (--totalProgressCount < 1)
1707 this.getContentPane().remove(progressPanel);
1708 progressPanel = null;
1715 public void stopLoading()
1718 if (fileLoadingCount < 1)
1720 while (fileLoadingPanels.size() > 0)
1722 removeProgressPanel(fileLoadingPanels.remove(0));
1724 fileLoadingPanels.clear();
1725 fileLoadingCount = 0;
1730 public static int getViewCount(String alignmentId)
1732 AlignmentViewport[] aps = getViewports(alignmentId);
1733 return (aps == null) ? 0 : aps.length;
1738 * @param alignmentId
1739 * - if null, all sets are returned
1740 * @return all AlignmentPanels concerning the alignmentId sequence set
1742 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1744 if (Desktop.desktop == null)
1746 // no frames created and in headless mode
1747 // TODO: verify that frames are recoverable when in headless mode
1750 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1751 AlignFrame[] frames = getAlignFrames();
1756 for (AlignFrame af : frames)
1758 for (AlignmentPanel ap : af.alignPanels)
1760 if (alignmentId == null
1761 || alignmentId.equals(ap.av.getSequenceSetId()))
1767 if (aps.size() == 0)
1771 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1776 * get all the viewports on an alignment.
1778 * @param sequenceSetId
1779 * unique alignment id (may be null - all viewports returned in that
1781 * @return all viewports on the alignment bound to sequenceSetId
1783 public static AlignmentViewport[] getViewports(String sequenceSetId)
1785 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1786 if (desktop != null)
1788 AlignFrame[] frames = Desktop.getAlignFrames();
1790 for (AlignFrame afr : frames)
1792 if (sequenceSetId == null
1793 || afr.getViewport().getSequenceSetId()
1794 .equals(sequenceSetId))
1796 if (afr.alignPanels != null)
1798 for (AlignmentPanel ap : afr.alignPanels)
1800 if (sequenceSetId == null
1801 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1809 viewp.add(afr.getViewport());
1813 if (viewp.size() > 0)
1815 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1822 * Explode the views in the given frame into separate AlignFrame
1826 public void explodeViews(AlignFrame af)
1828 int size = af.alignPanels.size();
1834 for (int i = 0; i < size; i++)
1836 AlignmentPanel ap = af.alignPanels.get(i);
1837 AlignFrame newaf = new AlignFrame(ap);
1840 * Restore the view's last exploded frame geometry if known. Multiple
1841 * views from one exploded frame share and restore the same (frame)
1842 * position and size.
1844 Rectangle geometry = ap.av.getExplodedGeometry();
1845 if (geometry != null)
1847 newaf.setBounds(geometry);
1850 ap.av.setGatherViewsHere(false);
1852 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1853 AlignFrame.DEFAULT_HEIGHT);
1856 af.alignPanels.clear();
1857 af.closeMenuItem_actionPerformed(true);
1862 * Gather expanded views (separate AlignFrame's) with the same sequence set
1863 * identifier back in to this frame as additional views, and close the
1864 * expanded views. Note the expanded frames may themselves have multiple
1865 * views. We take the lot.
1869 public void gatherViews(AlignFrame source)
1871 source.viewport.setGatherViewsHere(true);
1872 source.viewport.setExplodedGeometry(source.getBounds());
1873 JInternalFrame[] frames = desktop.getAllFrames();
1874 String viewId = source.viewport.getSequenceSetId();
1876 for (int t = 0; t < frames.length; t++)
1878 if (frames[t] instanceof AlignFrame && frames[t] != source)
1880 AlignFrame af = (AlignFrame) frames[t];
1881 boolean gatherThis = false;
1882 for (int a = 0; a < af.alignPanels.size(); a++)
1884 AlignmentPanel ap = af.alignPanels.get(a);
1885 if (viewId.equals(ap.av.getSequenceSetId()))
1888 ap.av.setGatherViewsHere(false);
1889 ap.av.setExplodedGeometry(af.getBounds());
1890 source.addAlignmentPanel(ap, false);
1896 af.alignPanels.clear();
1897 af.closeMenuItem_actionPerformed(true);
1904 jalview.gui.VamsasApplication v_client = null;
1907 public void vamsasImport_actionPerformed(ActionEvent e)
1909 if (v_client == null)
1911 // Load and try to start a session.
1912 JalviewFileChooser chooser = new JalviewFileChooser(
1913 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1915 chooser.setFileView(new JalviewFileView());
1916 chooser.setDialogTitle(MessageManager
1917 .getString("label.open_saved_vamsas_session"));
1918 chooser.setToolTipText(MessageManager
1919 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1921 int value = chooser.showOpenDialog(this);
1923 if (value == JalviewFileChooser.APPROVE_OPTION)
1925 String fle = chooser.getSelectedFile().toString();
1926 if (!vamsasImport(chooser.getSelectedFile()))
1929 .showInternalMessageDialog(
1931 MessageManager.formatMessage(
1932 "label.couldnt_import_as_vamsas_session",
1933 new Object[] { fle }),
1935 .getString("label.vamsas_document_import_failed"),
1936 JOptionPane.ERROR_MESSAGE);
1942 jalview.bin.Cache.log
1943 .error("Implementation error - load session from a running session is not supported.");
1948 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1951 * @return true if import was a success and a session was started.
1953 public boolean vamsasImport(URL url)
1955 // TODO: create progress bar
1956 if (v_client != null)
1959 jalview.bin.Cache.log
1960 .error("Implementation error - load session from a running session is not supported.");
1966 // copy the URL content to a temporary local file
1967 // TODO: be a bit cleverer here with nio (?!)
1968 File file = File.createTempFile("vdocfromurl", ".vdj");
1969 FileOutputStream fos = new FileOutputStream(file);
1970 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1971 byte[] buffer = new byte[2048];
1973 while ((ln = bis.read(buffer)) > -1)
1975 fos.write(buffer, 0, ln);
1979 v_client = new jalview.gui.VamsasApplication(this, file,
1980 url.toExternalForm());
1981 } catch (Exception ex)
1983 jalview.bin.Cache.log.error(
1984 "Failed to create new vamsas session from contents of URL "
1988 setupVamsasConnectedGui();
1989 v_client.initial_update(); // TODO: thread ?
1990 return v_client.inSession();
1994 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1997 * @return true if import was a success and a session was started.
1999 public boolean vamsasImport(File file)
2001 if (v_client != null)
2004 jalview.bin.Cache.log
2005 .error("Implementation error - load session from a running session is not supported.");
2009 setProgressBar(MessageManager.formatMessage(
2010 "status.importing_vamsas_session_from",
2011 new Object[] { file.getName() }), file.hashCode());
2014 v_client = new jalview.gui.VamsasApplication(this, file, null);
2015 } catch (Exception ex)
2017 setProgressBar(MessageManager.formatMessage(
2018 "status.importing_vamsas_session_from",
2019 new Object[] { file.getName() }), file.hashCode());
2020 jalview.bin.Cache.log.error(
2021 "New vamsas session from existing session file failed:", ex);
2024 setupVamsasConnectedGui();
2025 v_client.initial_update(); // TODO: thread ?
2026 setProgressBar(MessageManager.formatMessage(
2027 "status.importing_vamsas_session_from",
2028 new Object[] { file.getName() }), file.hashCode());
2029 return v_client.inSession();
2032 public boolean joinVamsasSession(String mysesid)
2034 if (v_client != null)
2038 .getString("error.try_join_vamsas_session_another"));
2040 if (mysesid == null)
2043 MessageManager.getString("error.invalid_vamsas_session_id"));
2045 v_client = new VamsasApplication(this, mysesid);
2046 setupVamsasConnectedGui();
2047 v_client.initial_update();
2048 return (v_client.inSession());
2052 public void vamsasStart_actionPerformed(ActionEvent e)
2054 if (v_client == null)
2057 // we just start a default session for moment.
2059 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2060 * getProperty("LAST_DIRECTORY"));
2062 * chooser.setFileView(new JalviewFileView());
2063 * chooser.setDialogTitle("Load Vamsas file");
2064 * chooser.setToolTipText("Import");
2066 * int value = chooser.showOpenDialog(this);
2068 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2069 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2071 v_client = new VamsasApplication(this);
2072 setupVamsasConnectedGui();
2073 v_client.initial_update(); // TODO: thread ?
2077 // store current data in session.
2078 v_client.push_update(); // TODO: thread
2082 protected void setupVamsasConnectedGui()
2084 vamsasStart.setText(MessageManager.getString("label.session_update"));
2085 vamsasSave.setVisible(true);
2086 vamsasStop.setVisible(true);
2087 vamsasImport.setVisible(false); // Document import to existing session is
2088 // not possible for vamsas-client-1.0.
2091 protected void setupVamsasDisconnectedGui()
2093 vamsasSave.setVisible(false);
2094 vamsasStop.setVisible(false);
2095 vamsasImport.setVisible(true);
2096 vamsasStart.setText(MessageManager
2097 .getString("label.new_vamsas_session"));
2101 public void vamsasStop_actionPerformed(ActionEvent e)
2103 if (v_client != null)
2105 v_client.end_session();
2107 setupVamsasDisconnectedGui();
2111 protected void buildVamsasStMenu()
2113 if (v_client == null)
2115 String[] sess = null;
2118 sess = VamsasApplication.getSessionList();
2119 } catch (Exception e)
2121 jalview.bin.Cache.log.warn(
2122 "Problem getting current sessions list.", e);
2127 jalview.bin.Cache.log.debug("Got current sessions list: "
2128 + sess.length + " entries.");
2129 VamsasStMenu.removeAll();
2130 for (int i = 0; i < sess.length; i++)
2132 JMenuItem sessit = new JMenuItem();
2133 sessit.setText(sess[i]);
2134 sessit.setToolTipText(MessageManager.formatMessage(
2135 "label.connect_to_session", new Object[] { sess[i] }));
2136 final Desktop dsktp = this;
2137 final String mysesid = sess[i];
2138 sessit.addActionListener(new ActionListener()
2142 public void actionPerformed(ActionEvent e)
2144 if (dsktp.v_client == null)
2146 Thread rthr = new Thread(new Runnable()
2152 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2153 dsktp.setupVamsasConnectedGui();
2154 dsktp.v_client.initial_update();
2162 VamsasStMenu.add(sessit);
2164 // don't show an empty menu.
2165 VamsasStMenu.setVisible(sess.length > 0);
2170 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2171 VamsasStMenu.removeAll();
2172 VamsasStMenu.setVisible(false);
2177 // Not interested in the content. Just hide ourselves.
2178 VamsasStMenu.setVisible(false);
2183 public void vamsasSave_actionPerformed(ActionEvent e)
2185 if (v_client != null)
2187 JalviewFileChooser chooser = new JalviewFileChooser(
2188 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2189 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2190 new String[] { "Vamsas Document" }, "Vamsas Document");
2192 chooser.setFileView(new JalviewFileView());
2193 chooser.setDialogTitle(MessageManager
2194 .getString("label.save_vamsas_document_archive"));
2196 int value = chooser.showSaveDialog(this);
2198 if (value == JalviewFileChooser.APPROVE_OPTION)
2200 java.io.File choice = chooser.getSelectedFile();
2201 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2202 "label.saving_vamsas_doc",
2203 new Object[] { choice.getName() }));
2204 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2205 String warnmsg = null;
2206 String warnttl = null;
2209 v_client.vclient.storeDocument(choice);
2212 warnttl = "Serious Problem saving Vamsas Document";
2213 warnmsg = ex.toString();
2214 jalview.bin.Cache.log.error("Error Whilst saving document to "
2217 } catch (Exception ex)
2219 warnttl = "Problem saving Vamsas Document.";
2220 warnmsg = ex.toString();
2221 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2225 removeProgressPanel(progpanel);
2226 if (warnmsg != null)
2228 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2230 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2236 JPanel vamUpdate = null;
2239 * hide vamsas user gui bits when a vamsas document event is being handled.
2242 * true to hide gui, false to reveal gui
2244 public void setVamsasUpdate(boolean b)
2246 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2247 + (b ? "in progress" : "finished"));
2249 if (vamUpdate != null)
2251 this.removeProgressPanel(vamUpdate);
2255 vamUpdate = this.addProgressPanel(MessageManager
2256 .getString("label.updating_vamsas_session"));
2258 vamsasStart.setVisible(!b);
2259 vamsasStop.setVisible(!b);
2260 vamsasSave.setVisible(!b);
2263 public JInternalFrame[] getAllFrames()
2265 return desktop.getAllFrames();
2269 * Checks the given url to see if it gives a response indicating that the user
2270 * should be informed of a new questionnaire.
2274 public void checkForQuestionnaire(String url)
2276 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2277 // javax.swing.SwingUtilities.invokeLater(jvq);
2278 new Thread(jvq).start();
2282 * Proxy class for JDesktopPane which optionally displays the current memory
2283 * usage and highlights the desktop area with a red bar if free memory runs
2288 public class MyDesktopPane extends JDesktopPane implements Runnable
2291 private static final float ONE_MB = 1048576f;
2293 boolean showMemoryUsage = false;
2297 java.text.NumberFormat df;
2299 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2302 public MyDesktopPane(boolean showMemoryUsage)
2304 showMemoryUsage(showMemoryUsage);
2307 public void showMemoryUsage(boolean showMemory)
2309 this.showMemoryUsage = showMemory;
2312 Thread worker = new Thread(this);
2317 public boolean isShowMemoryUsage()
2319 return showMemoryUsage;
2325 df = java.text.NumberFormat.getNumberInstance();
2326 df.setMaximumFractionDigits(2);
2327 runtime = Runtime.getRuntime();
2329 while (showMemoryUsage)
2333 maxMemory = runtime.maxMemory() / ONE_MB;
2334 allocatedMemory = runtime.totalMemory() / ONE_MB;
2335 freeMemory = runtime.freeMemory() / ONE_MB;
2336 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2338 percentUsage = (totalFreeMemory / maxMemory) * 100;
2340 // if (percentUsage < 20)
2342 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2344 // instance.set.setBorder(border1);
2347 // sleep after showing usage
2349 } catch (Exception ex)
2351 ex.printStackTrace();
2357 public void paintComponent(Graphics g)
2359 if (showMemoryUsage && g != null && df != null)
2361 if (percentUsage < 20)
2363 g.setColor(Color.red);
2365 FontMetrics fm = g.getFontMetrics();
2368 g.drawString(MessageManager.formatMessage(
2369 "label.memory_stats",
2370 new Object[] { df.format(totalFreeMemory),
2371 df.format(maxMemory), df.format(percentUsage) }), 10,
2372 getHeight() - fm.getHeight());
2379 * fixes stacking order after a modal dialog to ensure windows that should be
2380 * on top actually are
2382 public void relayerWindows()
2387 protected JMenuItem groovyShell;
2389 public void doGroovyCheck()
2391 if (jalview.bin.Cache.groovyJarsPresent())
2393 groovyShell = new JMenuItem();
2394 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2395 groovyShell.addActionListener(new ActionListener()
2398 public void actionPerformed(ActionEvent e)
2400 groovyShell_actionPerformed();
2403 toolsMenu.add(groovyShell);
2404 groovyShell.setVisible(true);
2409 * Accessor method to quickly get all the AlignmentFrames loaded.
2411 * @return an array of AlignFrame, or null if none found
2413 public static AlignFrame[] getAlignFrames()
2415 if (Jalview.isHeadlessMode())
2417 // Desktop.desktop is null in headless mode
2418 return new AlignFrame[] { currentAlignFrame };
2421 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2427 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2429 for (int i = frames.length - 1; i > -1; i--)
2431 if (frames[i] instanceof AlignFrame)
2433 avp.add((AlignFrame) frames[i]);
2435 else if (frames[i] instanceof SplitFrame)
2438 * Also check for a split frame containing an AlignFrame
2440 GSplitFrame sf = (GSplitFrame) frames[i];
2441 if (sf.getTopFrame() instanceof AlignFrame)
2443 avp.add((AlignFrame) sf.getTopFrame());
2445 if (sf.getBottomFrame() instanceof AlignFrame)
2447 avp.add((AlignFrame) sf.getBottomFrame());
2451 if (avp.size() == 0)
2455 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2460 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2464 public GStructureViewer[] getJmols()
2466 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2472 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2474 for (int i = frames.length - 1; i > -1; i--)
2476 if (frames[i] instanceof AppJmol)
2478 GStructureViewer af = (GStructureViewer) frames[i];
2482 if (avp.size() == 0)
2486 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2491 * Add Groovy Support to Jalview
2493 public void groovyShell_actionPerformed()
2495 // use reflection to avoid creating compilation dependency.
2496 if (!jalview.bin.Cache.groovyJarsPresent())
2500 .getString("error.implementation_error_cannot_create_groovyshell"));
2504 Class<?> gcClass = Desktop.class.getClassLoader().loadClass(
2505 "groovy.ui.Console");
2506 Constructor<?> gccons = gcClass.getConstructor();
2507 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2508 new Class[] { String.class, Object.class });
2509 java.lang.reflect.Method run = gcClass.getMethod("run");
2510 Object gc = gccons.newInstance();
2511 setvar.invoke(gc, new Object[] { "Jalview", this });
2513 } catch (Exception ex)
2515 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2516 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2518 MessageManager.getString("label.couldnt_create_groovy_shell"),
2519 MessageManager.getString("label.groovy_support_failed"),
2520 JOptionPane.ERROR_MESSAGE);
2525 * Progress bars managed by the IProgressIndicator method.
2527 private Hashtable<Long, JPanel> progressBars;
2529 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2534 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2537 public void setProgressBar(String message, long id)
2539 if (progressBars == null)
2541 progressBars = new Hashtable<Long, JPanel>();
2542 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2545 if (progressBars.get(new Long(id)) != null)
2547 JPanel panel = progressBars.remove(new Long(id));
2548 if (progressBarHandlers.contains(new Long(id)))
2550 progressBarHandlers.remove(new Long(id));
2552 removeProgressPanel(panel);
2556 progressBars.put(new Long(id), addProgressPanel(message));
2563 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2564 * jalview.gui.IProgressIndicatorHandler)
2567 public void registerHandler(final long id,
2568 final IProgressIndicatorHandler handler)
2570 if (progressBarHandlers == null
2571 || !progressBars.containsKey(new Long(id)))
2575 .getString("error.call_setprogressbar_before_registering_handler"));
2577 progressBarHandlers.put(new Long(id), handler);
2578 final JPanel progressPanel = progressBars.get(new Long(id));
2579 if (handler.canCancel())
2581 JButton cancel = new JButton(
2582 MessageManager.getString("action.cancel"));
2583 final IProgressIndicator us = this;
2584 cancel.addActionListener(new ActionListener()
2588 public void actionPerformed(ActionEvent e)
2590 handler.cancelActivity(id);
2591 us.setProgressBar(MessageManager.formatMessage(
2592 "label.cancelled_params",
2593 new Object[] { ((JLabel) progressPanel.getComponent(0))
2597 progressPanel.add(cancel, BorderLayout.EAST);
2603 * @return true if any progress bars are still active
2606 public boolean operationInProgress()
2608 if (progressBars != null && progressBars.size() > 0)
2616 * This will return the first AlignFrame holding the given viewport instance.
2617 * It will break if there are more than one AlignFrames viewing a particular
2621 * @return alignFrame for viewport
2623 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2625 if (desktop != null)
2627 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2628 for (int panel = 0; aps != null && panel < aps.length; panel++)
2630 if (aps[panel] != null && aps[panel].av == viewport)
2632 return aps[panel].alignFrame;
2639 public VamsasApplication getVamsasApplication()
2646 * flag set if jalview GUI is being operated programmatically
2648 private boolean inBatchMode = false;
2651 * check if jalview GUI is being operated programmatically
2653 * @return inBatchMode
2655 public boolean isInBatchMode()
2661 * set flag if jalview GUI is being operated programmatically
2663 * @param inBatchMode
2665 public void setInBatchMode(boolean inBatchMode)
2667 this.inBatchMode = inBatchMode;
2670 public void startServiceDiscovery()
2672 startServiceDiscovery(false);
2675 public void startServiceDiscovery(boolean blocking)
2677 boolean alive = true;
2678 Thread t0 = null, t1 = null, t2 = null;
2679 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2682 // todo: changesupport handlers need to be transferred
2683 if (discoverer == null)
2685 discoverer = new jalview.ws.jws1.Discoverer();
2686 // register PCS handler for desktop.
2687 discoverer.addPropertyChangeListener(changeSupport);
2689 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2690 // until we phase out completely
2691 (t0 = new Thread(discoverer)).start();
2694 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2696 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2698 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2700 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2706 // TODO: do rest service discovery
2715 } catch (Exception e)
2718 alive = (t1 != null && t1.isAlive())
2719 || (t2 != null && t2.isAlive())
2720 || (t3 != null && t3.isAlive())
2721 || (t0 != null && t0.isAlive());
2727 * called to check if the service discovery process completed successfully.
2731 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2733 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2735 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2736 .getErrorMessages();
2739 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2741 if (serviceChangedDialog == null)
2743 // only run if we aren't already displaying one of these.
2744 addDialogThread(serviceChangedDialog = new Runnable()
2751 * JalviewDialog jd =new JalviewDialog() {
2753 * @Override protected void cancelPressed() { // TODO
2754 * Auto-generated method stub
2756 * }@Override protected void okPressed() { // TODO
2757 * Auto-generated method stub
2759 * }@Override protected void raiseClosed() { // TODO
2760 * Auto-generated method stub
2762 * } }; jd.initDialogFrame(new
2763 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2764 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2765 * + " or mis-configured HTTP proxy settings.<br/>" +
2766 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2768 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2769 * ), true, true, "Web Service Configuration Problem", 450,
2772 * jd.waitForInput();
2778 "<html><table width=\"450\"><tr><td>"
2780 + "</td></tr></table>"
2781 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2782 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2783 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2784 + " Tools->Preferences dialog box to change them.</p></html>"),
2785 "Web Service Configuration Problem",
2786 JOptionPane.DEFAULT_OPTION,
2787 JOptionPane.ERROR_MESSAGE);
2788 serviceChangedDialog = null;
2797 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2804 private Runnable serviceChangedDialog = null;
2807 * start a thread to open a URL in the configured browser. Pops up a warning
2808 * dialog to the user if there is an exception when calling out to the browser
2813 public static void showUrl(final String url)
2815 showUrl(url, Desktop.instance);
2819 * Like showUrl but allows progress handler to be specified
2823 * (null) or object implementing IProgressIndicator
2825 public static void showUrl(final String url,
2826 final IProgressIndicator progress)
2828 new Thread(new Runnable()
2835 if (progress != null)
2837 progress.setProgressBar(MessageManager.formatMessage(
2838 "status.opening_params", new Object[] { url }), this
2841 jalview.util.BrowserLauncher.openURL(url);
2842 } catch (Exception ex)
2844 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2846 .getString("label.web_browser_not_found_unix"),
2847 MessageManager.getString("label.web_browser_not_found"),
2848 JOptionPane.WARNING_MESSAGE);
2850 ex.printStackTrace();
2852 if (progress != null)
2854 progress.setProgressBar(null, this.hashCode());
2860 public static WsParamSetManager wsparamManager = null;
2862 public static ParamManager getUserParameterStore()
2864 if (wsparamManager == null)
2866 wsparamManager = new WsParamSetManager();
2868 return wsparamManager;
2872 * static hyperlink handler proxy method for use by Jalview's internal windows
2876 public static void hyperlinkUpdate(HyperlinkEvent e)
2878 if (e.getEventType() == EventType.ACTIVATED)
2883 url = e.getURL().toString();
2884 Desktop.showUrl(url);
2885 } catch (Exception x)
2889 if (Cache.log != null)
2891 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2895 System.err.println("Couldn't handle string " + url
2899 // ignore any exceptions due to dud links.
2906 * single thread that handles display of dialogs to user.
2908 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2911 * flag indicating if dialogExecutor should try to acquire a permit
2913 private volatile boolean dialogPause = true;
2918 private java.util.concurrent.Semaphore block = new Semaphore(0);
2921 * add another dialog thread to the queue
2925 public void addDialogThread(final Runnable prompter)
2927 dialogExecutor.submit(new Runnable()
2937 } catch (InterruptedException x)
2942 if (instance == null)
2948 SwingUtilities.invokeAndWait(prompter);
2949 } catch (Exception q)
2951 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2957 public void startDialogQueue()
2959 // set the flag so we don't pause waiting for another permit and semaphore
2960 // the current task to begin
2961 dialogPause = false;
2966 protected void snapShotWindow_actionPerformed(ActionEvent e)
2970 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2971 "View of Desktop", getWidth(), getHeight(), of = new File(
2972 "Jalview_snapshot" + System.currentTimeMillis()
2973 + ".eps"), "View of desktop", null, 0, false);
2976 paintAll(im.getGraphics());
2978 } catch (Exception q)
2980 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
2984 Cache.log.info("Successfully written snapshot to file "
2985 + of.getAbsolutePath());
2989 * Explode the views in the given SplitFrame into separate SplitFrame windows.
2990 * This respects (remembers) any previous 'exploded geometry' i.e. the size
2991 * and location last time the view was expanded (if any). However it does not
2992 * remember the split pane divider location - this is set to match the
2993 * 'exploding' frame.
2997 public void explodeViews(SplitFrame sf)
2999 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3000 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3001 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3003 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3005 int viewCount = topPanels.size();
3012 * Processing in reverse order works, forwards order leaves the first panels
3013 * not visible. I don't know why!
3015 for (int i = viewCount - 1; i >= 0; i--)
3018 * Make new top and bottom frames. These take over the respective
3019 * AlignmentPanel objects, including their AlignmentViewports, so the
3020 * cdna/protein relationships between the viewports is carried over to the
3023 * explodedGeometry holds the (x, y) position of the previously exploded
3024 * SplitFrame, and the (width, height) of the AlignFrame component
3026 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3027 AlignFrame newTopFrame = new AlignFrame(topPanel);
3028 newTopFrame.setSize(oldTopFrame.getSize());
3029 newTopFrame.setVisible(true);
3030 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3031 .getExplodedGeometry();
3032 if (geometry != null)
3034 newTopFrame.setSize(geometry.getSize());
3037 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3038 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3039 newBottomFrame.setSize(oldBottomFrame.getSize());
3040 newBottomFrame.setVisible(true);
3041 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3042 .getExplodedGeometry();
3043 if (geometry != null)
3045 newBottomFrame.setSize(geometry.getSize());
3048 topPanel.av.setGatherViewsHere(false);
3049 bottomPanel.av.setGatherViewsHere(false);
3050 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3052 if (geometry != null)
3054 splitFrame.setLocation(geometry.getLocation());
3056 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3060 * Clear references to the panels (now relocated in the new SplitFrames)
3061 * before closing the old SplitFrame.
3064 bottomPanels.clear();
3069 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3070 * back into the given SplitFrame as additional views. Note that the gathered
3071 * frames may themselves have multiple views.
3075 public void gatherViews(GSplitFrame source)
3078 * special handling of explodedGeometry for a view within a SplitFrame: - it
3079 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3080 * height) of the AlignFrame component
3082 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3083 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3084 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3085 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3086 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3087 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3089 myTopFrame.viewport.setGatherViewsHere(true);
3090 myBottomFrame.viewport.setGatherViewsHere(true);
3091 String topViewId = myTopFrame.viewport.getSequenceSetId();
3092 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3094 JInternalFrame[] frames = desktop.getAllFrames();
3095 for (JInternalFrame frame : frames)
3097 if (frame instanceof SplitFrame && frame != source)
3099 SplitFrame sf = (SplitFrame) frame;
3100 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3101 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3102 boolean gatherThis = false;
3103 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3105 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3106 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3107 if (topViewId.equals(topPanel.av.getSequenceSetId())
3108 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3111 topPanel.av.setGatherViewsHere(false);
3112 bottomPanel.av.setGatherViewsHere(false);
3113 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3114 topFrame.getSize()));
3115 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3116 .getLocation(), bottomFrame.getSize()));
3117 myTopFrame.addAlignmentPanel(topPanel, false);
3118 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3124 topFrame.getAlignPanels().clear();
3125 bottomFrame.getAlignPanels().clear();
3132 * The dust settles...give focus to the tab we did this from.
3134 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3138 public static AlignFrame getCurrentAlignFrame()
3140 return currentAlignFrame;
3143 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
3145 Desktop.currentAlignFrame = currentAlignFrame;