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.Window;
51 import java.awt.datatransfer.Clipboard;
52 import java.awt.datatransfer.ClipboardOwner;
53 import java.awt.datatransfer.DataFlavor;
54 import java.awt.datatransfer.Transferable;
55 import java.awt.dnd.DnDConstants;
56 import java.awt.dnd.DropTargetDragEvent;
57 import java.awt.dnd.DropTargetDropEvent;
58 import java.awt.dnd.DropTargetEvent;
59 import java.awt.dnd.DropTargetListener;
60 import java.awt.event.ActionEvent;
61 import java.awt.event.ActionListener;
62 import java.awt.event.FocusEvent;
63 import java.awt.event.FocusListener;
64 import java.awt.event.MouseAdapter;
65 import java.awt.event.MouseEvent;
66 import java.awt.event.MouseListener;
67 import java.awt.event.WindowAdapter;
68 import java.awt.event.WindowEvent;
69 import java.beans.PropertyChangeEvent;
70 import java.beans.PropertyChangeListener;
71 import java.beans.PropertyVetoException;
72 import java.io.BufferedInputStream;
74 import java.io.FileOutputStream;
75 import java.lang.reflect.Constructor;
76 import java.lang.reflect.InvocationTargetException;
77 import java.lang.reflect.Method;
79 import java.util.ArrayList;
80 import java.util.Hashtable;
81 import java.util.List;
82 import java.util.StringTokenizer;
83 import java.util.Vector;
84 import java.util.concurrent.ExecutorService;
85 import java.util.concurrent.Executors;
86 import java.util.concurrent.Semaphore;
88 import javax.swing.DefaultDesktopManager;
89 import javax.swing.DesktopManager;
90 import javax.swing.JButton;
91 import javax.swing.JComboBox;
92 import javax.swing.JComponent;
93 import javax.swing.JDesktopPane;
94 import javax.swing.JFrame;
95 import javax.swing.JInternalFrame;
96 import javax.swing.JLabel;
97 import javax.swing.JMenuItem;
98 import javax.swing.JOptionPane;
99 import javax.swing.JPanel;
100 import javax.swing.JPopupMenu;
101 import javax.swing.JProgressBar;
102 import javax.swing.SwingUtilities;
103 import javax.swing.event.HyperlinkEvent;
104 import javax.swing.event.HyperlinkEvent.EventType;
105 import javax.swing.event.MenuEvent;
106 import javax.swing.event.MenuListener;
113 * @version $Revision: 1.155 $
115 public class Desktop extends jalview.jbgui.GDesktop implements
116 DropTargetListener, ClipboardOwner, IProgressIndicator,
117 jalview.api.StructureSelectionManagerProvider
120 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
123 * news reader - null if it was never started.
125 private BlogReader jvnews = null;
127 private File projectFile;
131 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
133 public void addJalviewPropertyChangeListener(
134 PropertyChangeListener listener)
136 changeSupport.addJalviewPropertyChangeListener(listener);
140 * @param propertyName
142 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
143 * java.beans.PropertyChangeListener)
145 public void addJalviewPropertyChangeListener(String propertyName,
146 PropertyChangeListener listener)
148 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
152 * @param propertyName
154 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
155 * java.beans.PropertyChangeListener)
157 public void removeJalviewPropertyChangeListener(String propertyName,
158 PropertyChangeListener listener)
160 changeSupport.removeJalviewPropertyChangeListener(propertyName,
164 /** Singleton Desktop instance */
165 public static Desktop instance;
167 public static MyDesktopPane desktop;
169 static int openFrameCount = 0;
171 static final int xOffset = 30;
173 static final int yOffset = 30;
175 private static AlignFrame currentAlignFrame;
177 public static jalview.ws.jws1.Discoverer discoverer;
179 public static Object[] jalviewClipboard;
181 public static boolean internalCopy = false;
183 static int fileLoadingCount = 0;
185 class MyDesktopManager implements DesktopManager
188 private DesktopManager delegate;
190 public MyDesktopManager(DesktopManager delegate)
192 this.delegate = delegate;
196 public void activateFrame(JInternalFrame f)
200 delegate.activateFrame(f);
201 } catch (NullPointerException npe)
203 Point p = getMousePosition();
204 instance.showPasteMenu(p.x, p.y);
209 public void beginDraggingFrame(JComponent f)
211 delegate.beginDraggingFrame(f);
215 public void beginResizingFrame(JComponent f, int direction)
217 delegate.beginResizingFrame(f, direction);
221 public void closeFrame(JInternalFrame f)
223 delegate.closeFrame(f);
227 public void deactivateFrame(JInternalFrame f)
229 delegate.deactivateFrame(f);
233 public void deiconifyFrame(JInternalFrame f)
235 delegate.deiconifyFrame(f);
239 public void dragFrame(JComponent f, int newX, int newY)
245 delegate.dragFrame(f, newX, newY);
249 public void endDraggingFrame(JComponent f)
251 delegate.endDraggingFrame(f);
255 public void endResizingFrame(JComponent f)
257 delegate.endResizingFrame(f);
261 public void iconifyFrame(JInternalFrame f)
263 delegate.iconifyFrame(f);
267 public void maximizeFrame(JInternalFrame f)
269 delegate.maximizeFrame(f);
273 public void minimizeFrame(JInternalFrame f)
275 delegate.minimizeFrame(f);
279 public void openFrame(JInternalFrame f)
281 delegate.openFrame(f);
285 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
292 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
296 public void setBoundsForFrame(JComponent f, int newX, int newY,
297 int newWidth, int newHeight)
299 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
302 // All other methods, simply delegate
307 * Creates a new Desktop object.
312 * A note to implementors. It is ESSENTIAL that any activities that might
313 * block are spawned off as threads rather than waited for during this
317 doVamsasClientCheck();
319 doConfigureStructurePrefs();
320 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
321 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
322 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
324 boolean showjconsole = jalview.bin.Cache.getDefault(
325 "SHOW_JAVA_CONSOLE", false);
326 desktop = new MyDesktopPane(selmemusage);
327 if (Platform.isAMac())
329 desktop.setDoubleBuffered(false);
331 showMemusage.setSelected(selmemusage);
332 desktop.setBackground(Color.white);
333 getContentPane().setLayout(new BorderLayout());
334 // alternate config - have scrollbars - see notes in JAL-153
335 // JScrollPane sp = new JScrollPane();
336 // sp.getViewport().setView(desktop);
337 // getContentPane().add(sp, BorderLayout.CENTER);
338 getContentPane().add(desktop, BorderLayout.CENTER);
339 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
341 // This line prevents Windows Look&Feel resizing all new windows to maximum
342 // if previous window was maximised
343 desktop.setDesktopManager(new MyDesktopManager(
344 new DefaultDesktopManager()));
346 Rectangle dims = getLastKnownDimensions("");
353 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
354 setBounds((screenSize.width - 900) / 2,
355 (screenSize.height - 650) / 2, 900, 650);
357 jconsole = new Console(this, showjconsole);
358 // add essential build information
359 jconsole.setHeader("Jalview Version: "
360 + jalview.bin.Cache.getProperty("VERSION") + "\n"
361 + "Jalview Installation: "
362 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
363 + "\n" + "Build Date: "
364 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
365 + "Java version: " + System.getProperty("java.version") + "\n"
366 + System.getProperty("os.arch") + " "
367 + System.getProperty("os.name") + " "
368 + System.getProperty("os.version"));
370 showConsole(showjconsole);
372 showNews.setVisible(false);
374 this.addWindowListener(new WindowAdapter()
377 public void windowClosing(WindowEvent evt)
384 this.addMouseListener(ma = new MouseAdapter()
387 public void mousePressed(MouseEvent evt)
389 if (evt.isPopupTrigger())
391 showPasteMenu(evt.getX(), evt.getY());
395 desktop.addMouseListener(ma);
397 this.addFocusListener(new FocusListener()
401 public void focusLost(FocusEvent e)
403 // TODO Auto-generated method stub
408 public void focusGained(FocusEvent e)
410 Cache.log.debug("Relaying windows after focus gain");
411 // make sure that we sort windows properly after we gain focus
412 instance.relayerWindows();
415 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
416 // Spawn a thread that shows the splashscreen
417 SwingUtilities.invokeLater(new Runnable()
427 // Thread off a new instance of the file chooser - this reduces the time it
428 // takes to open it later on.
429 new Thread(new Runnable()
434 Cache.log.debug("Filechooser init thread started.");
435 new JalviewFileChooser(
436 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
437 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
438 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
439 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
440 Cache.log.debug("Filechooser init thread finished.");
443 // Add the service change listener
444 changeSupport.addJalviewPropertyChangeListener("services",
445 new PropertyChangeListener()
449 public void propertyChange(PropertyChangeEvent evt)
451 Cache.log.debug("Firing service changed event for "
452 + evt.getNewValue());
453 JalviewServicesChanged(evt);
459 public void doConfigureStructurePrefs()
461 // configure services
462 StructureSelectionManager ssm = StructureSelectionManager
463 .getStructureSelectionManager(this);
464 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
466 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
467 Preferences.ADD_TEMPFACT_ANN, true));
468 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
469 Preferences.STRUCT_FROM_PDB, true));
470 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
471 Preferences.USE_RNAVIEW, true));
475 ssm.setAddTempFacAnnot(false);
476 ssm.setProcessSecondaryStructure(false);
477 ssm.setSecStructServices(false);
481 public void checkForNews()
483 final Desktop me = this;
484 // Thread off the news reader, in case there are connection problems.
485 addDialogThread(new Runnable()
490 Cache.log.debug("Starting news thread.");
492 jvnews = new BlogReader(me);
493 showNews.setVisible(true);
494 Cache.log.debug("Completed news thread.");
500 protected void showNews_actionPerformed(ActionEvent e)
502 showNews(showNews.isSelected());
505 void showNews(boolean visible)
508 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
509 showNews.setSelected(visible);
510 if (visible && !jvnews.isVisible())
512 new Thread(new Runnable()
517 long now = System.currentTimeMillis();
518 Desktop.instance.setProgressBar(
519 MessageManager.getString("status.refreshing_news"), now);
520 jvnews.refreshNews();
521 Desktop.instance.setProgressBar(null, now);
530 * recover the last known dimensions for a jalview window
533 * - empty string is desktop, all other windows have unique prefix
534 * @return null or last known dimensions scaled to current geometry (if last
535 * window geom was known)
537 Rectangle getLastKnownDimensions(String windowName)
539 // TODO: lock aspect ratio for scaling desktop Bug #0058199
540 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
541 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
542 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
543 String width = jalview.bin.Cache.getProperty(windowName
545 String height = jalview.bin.Cache.getProperty(windowName
547 if ((x != null) && (y != null) && (width != null) && (height != null))
549 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
550 .parseInt(width), ih = Integer.parseInt(height);
551 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
553 // attempt #1 - try to cope with change in screen geometry - this
554 // version doesn't preserve original jv aspect ratio.
555 // take ratio of current screen size vs original screen size.
556 double sw = ((1f * screenSize.width) / (1f * Integer
557 .parseInt(jalview.bin.Cache
558 .getProperty("SCREENGEOMETRY_WIDTH"))));
559 double sh = ((1f * screenSize.height) / (1f * Integer
560 .parseInt(jalview.bin.Cache
561 .getProperty("SCREENGEOMETRY_HEIGHT"))));
562 // rescale the bounds depending upon the current screen geometry.
563 ix = (int) (ix * sw);
564 iw = (int) (iw * sw);
565 iy = (int) (iy * sh);
566 ih = (int) (ih * sh);
567 while (ix >= screenSize.width)
569 jalview.bin.Cache.log
570 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
571 ix -= screenSize.width;
573 while (iy >= screenSize.height)
575 jalview.bin.Cache.log
576 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
577 iy -= screenSize.height;
579 jalview.bin.Cache.log.debug("Got last known dimensions for "
580 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
583 // return dimensions for new instance
584 return new Rectangle(ix, iy, iw, ih);
589 private void doVamsasClientCheck()
591 if (jalview.bin.Cache.vamsasJarsPresent())
593 setupVamsasDisconnectedGui();
594 VamsasMenu.setVisible(true);
595 final Desktop us = this;
596 VamsasMenu.addMenuListener(new MenuListener()
598 // this listener remembers when the menu was first selected, and
599 // doesn't rebuild the session list until it has been cleared and
601 boolean refresh = true;
604 public void menuCanceled(MenuEvent e)
610 public void menuDeselected(MenuEvent e)
616 public void menuSelected(MenuEvent e)
620 us.buildVamsasStMenu();
625 vamsasStart.setVisible(true);
629 void showPasteMenu(int x, int y)
631 JPopupMenu popup = new JPopupMenu();
632 JMenuItem item = new JMenuItem(
633 MessageManager.getString("label.paste_new_window"));
634 item.addActionListener(new ActionListener()
637 public void actionPerformed(ActionEvent evt)
644 popup.show(this, x, y);
651 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
652 Transferable contents = c.getContents(this);
654 if (contents != null)
656 String file = (String) contents
657 .getTransferData(DataFlavor.stringFlavor);
659 String format = new IdentifyFile().identify(file,
660 FormatAdapter.PASTE);
662 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
665 } catch (Exception ex)
668 .println("Unable to paste alignment from system clipboard:\n"
674 * Adds and opens the given frame to the desktop
685 public static synchronized void addInternalFrame(
686 final JInternalFrame frame, String title, int w, int h)
688 addInternalFrame(frame, title, true, w, h, true);
692 * Add an internal frame to the Jalview desktop
699 * When true, display frame immediately, otherwise, caller must call
700 * setVisible themselves.
706 public static synchronized void addInternalFrame(
707 final JInternalFrame frame, String title, boolean makeVisible,
710 addInternalFrame(frame, title, makeVisible, w, h, true);
714 * Add an internal frame to the Jalview desktop and make it visible
727 public static synchronized void addInternalFrame(
728 final JInternalFrame frame, String title, int w, int h,
731 addInternalFrame(frame, title, true, w, h, resizable);
735 * Add an internal frame to the Jalview desktop
742 * When true, display frame immediately, otherwise, caller must call
743 * setVisible themselves.
751 public static synchronized void addInternalFrame(
752 final JInternalFrame frame, String title, boolean makeVisible,
753 int w, int h, boolean resizable)
756 // TODO: allow callers to determine X and Y position of frame (eg. via
758 // TODO: consider fixing method to update entries in the window submenu with
759 // the current window title
761 frame.setTitle(title);
762 if (frame.getWidth() < 1 || frame.getHeight() < 1)
766 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
767 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
768 // IF JALVIEW IS RUNNING HEADLESS
769 // ///////////////////////////////////////////////
771 || (System.getProperty("java.awt.headless") != null && System
772 .getProperty("java.awt.headless").equals("true")))
779 frame.setVisible(makeVisible);
780 frame.setClosable(true);
781 frame.setResizable(resizable);
782 frame.setMaximizable(resizable);
783 frame.setIconifiable(resizable);
784 if (Platform.isAMac())
786 frame.setIconifiable(false);
787 frame.setFrameIcon(null);
788 // frame.setDesktopIcon(null);
789 frame.setDoubleBuffered(false);
791 if (frame.getX() < 1 && frame.getY() < 1)
793 frame.setLocation(xOffset * openFrameCount, yOffset
794 * ((openFrameCount - 1) % 10) + yOffset);
797 final JMenuItem menuItem = new JMenuItem(title);
798 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
801 public void internalFrameActivated(
802 javax.swing.event.InternalFrameEvent evt)
804 JInternalFrame itf = desktop.getSelectedFrame();
813 public void internalFrameClosed(
814 javax.swing.event.InternalFrameEvent evt)
816 PaintRefresher.RemoveComponent(frame);
818 windowMenu.remove(menuItem);
819 JInternalFrame itf = desktop.getSelectedFrame();
828 menuItem.addActionListener(new ActionListener()
831 public void actionPerformed(ActionEvent e)
835 frame.setSelected(true);
836 frame.setIcon(false);
837 } catch (java.beans.PropertyVetoException ex)
843 menuItem.addMouseListener(new MouseListener()
847 public void mouseReleased(MouseEvent e)
852 public void mousePressed(MouseEvent e)
857 public void mouseExited(MouseEvent e)
861 frame.setSelected(false);
862 } catch (PropertyVetoException e1)
868 public void mouseEntered(MouseEvent e)
872 frame.setSelected(true);
873 } catch (PropertyVetoException e1)
879 public void mouseClicked(MouseEvent e)
885 windowMenu.add(menuItem);
891 frame.setSelected(true);
892 frame.requestFocus();
893 } catch (java.beans.PropertyVetoException ve)
895 } catch (java.lang.ClassCastException cex)
898 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
904 public void lostOwnership(Clipboard clipboard, Transferable contents)
908 Desktop.jalviewClipboard = null;
911 internalCopy = false;
915 public void dragEnter(DropTargetDragEvent evt)
920 public void dragExit(DropTargetEvent evt)
925 public void dragOver(DropTargetDragEvent evt)
930 public void dropActionChanged(DropTargetDragEvent evt)
941 public void drop(DropTargetDropEvent evt)
943 boolean success = true;
944 Transferable t = evt.getTransferable();
945 java.util.List files = null;
946 java.util.List protocols = null;
950 DataFlavor uriListFlavor = new DataFlavor(
951 "text/uri-list;class=java.lang.String");
952 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
954 // Works on Windows and MacOSX
955 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
956 files = (java.util.List) t
957 .getTransferData(DataFlavor.javaFileListFlavor);
959 else if (t.isDataFlavorSupported(uriListFlavor))
961 // This is used by Unix drag system
962 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
963 String data = (String) t.getTransferData(uriListFlavor);
964 files = new java.util.ArrayList(1);
965 protocols = new java.util.ArrayList(1);
966 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
967 data, "\r\n"); st.hasMoreTokens();)
969 String s = st.nextToken();
970 if (s.startsWith("#"))
972 // the line is a comment (as per the RFC 2483)
975 java.net.URI uri = new java.net.URI(s);
976 if (uri.getScheme().toLowerCase().startsWith("http"))
978 protocols.add(FormatAdapter.URL);
979 files.add(uri.toString());
983 // otherwise preserve old behaviour: catch all for file objects
984 java.io.File file = new java.io.File(uri);
985 protocols.add(FormatAdapter.FILE);
986 files.add(file.toString());
990 } catch (Exception e)
999 for (int i = 0; i < files.size(); i++)
1001 String file = files.get(i).toString();
1002 String protocol = (protocols == null) ? FormatAdapter.FILE
1003 : (String) protocols.get(i);
1004 String format = null;
1006 if (file.endsWith(".jar"))
1013 format = new IdentifyFile().identify(file, protocol);
1016 new FileLoader().LoadFile(file, protocol, format);
1019 } catch (Exception ex)
1024 evt.dropComplete(success); // need this to ensure input focus is properly
1025 // transfered to any new windows created
1035 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1037 JalviewFileChooser chooser = new JalviewFileChooser(
1038 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1039 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1040 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1041 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1043 chooser.setFileView(new JalviewFileView());
1044 chooser.setDialogTitle(MessageManager
1045 .getString("label.open_local_file"));
1046 chooser.setToolTipText(MessageManager.getString("action.open"));
1048 int value = chooser.showOpenDialog(this);
1050 if (value == JalviewFileChooser.APPROVE_OPTION)
1052 String choice = chooser.getSelectedFile().getPath();
1053 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1054 .getSelectedFile().getParent());
1056 String format = null;
1057 if (chooser.getSelectedFormat() != null
1058 && chooser.getSelectedFormat().equals("Jalview"))
1064 format = new IdentifyFile().identify(choice, FormatAdapter.FILE);
1067 if (viewport != null)
1069 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1074 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1086 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1088 // This construct allows us to have a wider textfield
1090 JLabel label = new JLabel(
1091 MessageManager.getString("label.input_file_url"));
1092 final JComboBox history = new JComboBox();
1094 JPanel panel = new JPanel(new GridLayout(2, 1));
1097 history.setPreferredSize(new Dimension(400, 20));
1098 history.setEditable(true);
1099 history.addItem("http://www.");
1101 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1105 if (historyItems != null)
1107 st = new StringTokenizer(historyItems, "\t");
1109 while (st.hasMoreTokens())
1111 history.addItem(st.nextElement());
1115 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1116 MessageManager.getString("label.input_alignment_from_url"),
1117 JOptionPane.OK_CANCEL_OPTION);
1119 if (reply != JOptionPane.OK_OPTION)
1124 String url = history.getSelectedItem().toString();
1126 if (url.toLowerCase().endsWith(".jar"))
1128 if (viewport != null)
1130 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1135 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1140 String format = new IdentifyFile().identify(url, FormatAdapter.URL);
1142 if (format.equals("URL NOT FOUND"))
1144 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1145 MessageManager.formatMessage("label.couldnt_locate",
1146 new Object[] { url }), MessageManager
1147 .getString("label.url_not_found"),
1148 JOptionPane.WARNING_MESSAGE);
1153 if (viewport != null)
1155 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1159 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1165 * Opens the CutAndPaste window for the user to paste an alignment in to
1168 * - if not null, the pasted alignment is added to the current
1169 * alignment; if null, to a new alignment window
1172 public void inputTextboxMenuItem_actionPerformed(
1173 AlignmentViewPanel viewPanel)
1175 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1176 cap.setForInput(viewPanel);
1177 Desktop.addInternalFrame(cap,
1178 MessageManager.getString("label.cut_paste_alignmen_file"),
1188 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1190 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1191 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1193 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1194 getBounds().y, getWidth(), getHeight()));
1196 if (jconsole != null)
1198 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1199 jconsole.stopConsole();
1203 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1206 if (dialogExecutor != null)
1208 dialogExecutor.shutdownNow();
1210 closeAll_actionPerformed(null);
1214 private void storeLastKnownDimensions(String string, Rectangle jc)
1216 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1217 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1218 + " height:" + jc.height);
1220 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1221 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1222 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1223 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1233 public void aboutMenuItem_actionPerformed(ActionEvent e)
1235 // StringBuffer message = getAboutMessage(false);
1236 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1238 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1239 new Thread(new Runnable()
1244 new SplashScreen(true);
1249 public StringBuffer getAboutMessage(boolean shortv)
1251 StringBuffer message = new StringBuffer();
1252 message.append("<html>");
1255 message.append("<h1><strong>Version: "
1256 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1257 message.append("<strong>Last Updated: <em>"
1258 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1259 + "</em></strong>");
1265 message.append("<strong>Version "
1266 + jalview.bin.Cache.getProperty("VERSION")
1267 + "; last updated: "
1268 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1271 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1274 message.append("<br>...Checking latest version...</br>");
1276 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1277 .equals(jalview.bin.Cache.getProperty("VERSION")))
1279 boolean red = false;
1280 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1281 .indexOf("automated build") == -1)
1284 // Displayed when code version and jnlp version do not match and code
1285 // version is not a development build
1286 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1289 message.append("<br>!! Version "
1290 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1292 + " is available for download from "
1293 + jalview.bin.Cache.getDefault("www.jalview.org",
1294 "http://www.jalview.org") + " !!");
1297 message.append("</div>");
1300 message.append("<br>Authors: "
1302 .getDefault("AUTHORFNAMES",
1303 "The Jalview Authors (See AUTHORS file for current list)")
1304 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1305 + "<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"
1306 + "<br><br>If you use Jalview, please cite:"
1307 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1308 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1309 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1321 public void documentationMenuItem_actionPerformed(ActionEvent e)
1325 Help.showHelpWindow();
1326 } catch (Exception ex)
1332 public void closeAll_actionPerformed(ActionEvent e)
1334 JInternalFrame[] frames = desktop.getAllFrames();
1335 for (int i = 0; i < frames.length; i++)
1339 frames[i].setClosed(true);
1340 } catch (java.beans.PropertyVetoException ex)
1344 System.out.println("ALL CLOSED");
1345 if (v_client != null)
1347 // TODO clear binding to vamsas document objects on close_all
1351 * reset state of singleton objects as appropriate (clear down session state
1352 * when all windows are closed)
1354 StructureSelectionManager ssm = StructureSelectionManager
1355 .getStructureSelectionManager(this);
1363 public void raiseRelated_actionPerformed(ActionEvent e)
1365 reorderAssociatedWindows(false, false);
1369 public void minimizeAssociated_actionPerformed(ActionEvent e)
1371 reorderAssociatedWindows(true, false);
1374 void closeAssociatedWindows()
1376 reorderAssociatedWindows(false, true);
1382 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1386 protected void garbageCollect_actionPerformed(ActionEvent e)
1388 // We simply collect the garbage
1389 jalview.bin.Cache.log.debug("Collecting garbage...");
1391 jalview.bin.Cache.log.debug("Finished garbage collection.");
1398 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1402 protected void showMemusage_actionPerformed(ActionEvent e)
1404 desktop.showMemoryUsage(showMemusage.isSelected());
1411 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1415 protected void showConsole_actionPerformed(ActionEvent e)
1417 showConsole(showConsole.isSelected());
1420 Console jconsole = null;
1423 * control whether the java console is visible or not
1427 void showConsole(boolean selected)
1429 showConsole.setSelected(selected);
1430 // TODO: decide if we should update properties file
1431 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1433 jconsole.setVisible(selected);
1436 void reorderAssociatedWindows(boolean minimize, boolean close)
1438 JInternalFrame[] frames = desktop.getAllFrames();
1439 if (frames == null || frames.length < 1)
1444 AlignmentViewport source = null, target = null;
1445 if (frames[0] instanceof AlignFrame)
1447 source = ((AlignFrame) frames[0]).getCurrentView();
1449 else if (frames[0] instanceof TreePanel)
1451 source = ((TreePanel) frames[0]).getViewPort();
1453 else if (frames[0] instanceof PCAPanel)
1455 source = ((PCAPanel) frames[0]).av;
1457 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1459 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1464 for (int i = 0; i < frames.length; i++)
1467 if (frames[i] == null)
1471 if (frames[i] instanceof AlignFrame)
1473 target = ((AlignFrame) frames[i]).getCurrentView();
1475 else if (frames[i] instanceof TreePanel)
1477 target = ((TreePanel) frames[i]).getViewPort();
1479 else if (frames[i] instanceof PCAPanel)
1481 target = ((PCAPanel) frames[i]).av;
1483 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1485 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1488 if (source == target)
1494 frames[i].setClosed(true);
1498 frames[i].setIcon(minimize);
1501 frames[i].toFront();
1505 } catch (java.beans.PropertyVetoException ex)
1520 protected void preferences_actionPerformed(ActionEvent e)
1532 public void saveState_actionPerformed(ActionEvent e)
1534 JalviewFileChooser chooser = new JalviewFileChooser(
1535 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1536 new String[] { "jvp" }, new String[] { "Jalview Project" },
1539 chooser.setFileView(new JalviewFileView());
1540 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1542 int value = chooser.showSaveDialog(this);
1544 if (value == JalviewFileChooser.APPROVE_OPTION)
1546 final Desktop me = this;
1547 final java.io.File choice = chooser.getSelectedFile();
1548 setProjectFile(choice);
1550 new Thread(new Runnable()
1555 // TODO: refactor to Jalview desktop session controller action.
1556 setProgressBar(MessageManager.formatMessage(
1557 "label.saving_jalview_project",
1558 new Object[] { choice.getName() }), choice.hashCode());
1559 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1560 choice.getParent());
1561 // TODO catch and handle errors for savestate
1562 // TODO prevent user from messing with the Desktop whilst we're saving
1565 new Jalview2XML().saveState(choice);
1566 } catch (OutOfMemoryError oom)
1568 new OOMWarning("Whilst saving current state to "
1569 + choice.getName(), oom);
1570 } catch (Exception ex)
1573 "Problems whilst trying to save to " + choice.getName(),
1575 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1576 "label.error_whilst_saving_current_state_to",
1577 new Object[] { choice.getName() }), MessageManager
1578 .getString("label.couldnt_save_project"),
1579 JOptionPane.WARNING_MESSAGE);
1581 setProgressBar(null, choice.hashCode());
1587 private void setProjectFile(File choice)
1589 this.projectFile = choice;
1592 public File getProjectFile()
1594 return this.projectFile;
1604 public void loadState_actionPerformed(ActionEvent e)
1606 JalviewFileChooser chooser = new JalviewFileChooser(
1607 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1608 "jvp", "jar" }, new String[] { "Jalview Project",
1609 "Jalview Project (old)" }, "Jalview Project");
1610 chooser.setFileView(new JalviewFileView());
1611 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1613 int value = chooser.showOpenDialog(this);
1615 if (value == JalviewFileChooser.APPROVE_OPTION)
1617 final File selectedFile = chooser.getSelectedFile();
1618 setProjectFile(selectedFile);
1619 final String choice = selectedFile.getAbsolutePath();
1620 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1621 selectedFile.getParent());
1622 new Thread(new Runnable()
1628 MessageManager.formatMessage(
1629 "label.loading_jalview_project",
1630 new Object[] { choice }), choice.hashCode());
1633 new Jalview2XML().loadJalviewAlign(choice);
1634 } catch (OutOfMemoryError oom)
1636 new OOMWarning("Whilst loading project from " + choice, oom);
1637 } catch (Exception ex)
1639 Cache.log.error("Problems whilst loading project from "
1641 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1643 "label.error_whilst_loading_project_from",
1644 new Object[] { choice }), MessageManager
1645 .getString("label.couldnt_load_project"),
1646 JOptionPane.WARNING_MESSAGE);
1648 setProgressBar(null, choice.hashCode());
1655 public void inputSequence_actionPerformed(ActionEvent e)
1657 new SequenceFetcher(this);
1660 JPanel progressPanel;
1662 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1664 public void startLoading(final String fileName)
1666 if (fileLoadingCount == 0)
1668 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1669 "label.loading_file", new Object[] { fileName })));
1674 private JPanel addProgressPanel(String string)
1676 if (progressPanel == null)
1678 progressPanel = new JPanel(new GridLayout(1, 1));
1679 totalProgressCount = 0;
1680 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1682 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1683 JProgressBar progressBar = new JProgressBar();
1684 progressBar.setIndeterminate(true);
1686 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1688 thisprogress.add(progressBar, BorderLayout.CENTER);
1689 progressPanel.add(thisprogress);
1690 ((GridLayout) progressPanel.getLayout())
1691 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1692 ++totalProgressCount;
1693 instance.validate();
1694 return thisprogress;
1697 int totalProgressCount = 0;
1699 private void removeProgressPanel(JPanel progbar)
1701 if (progressPanel != null)
1703 synchronized (progressPanel)
1705 progressPanel.remove(progbar);
1706 GridLayout gl = (GridLayout) progressPanel.getLayout();
1707 gl.setRows(gl.getRows() - 1);
1708 if (--totalProgressCount < 1)
1710 this.getContentPane().remove(progressPanel);
1711 progressPanel = null;
1718 public void stopLoading()
1721 if (fileLoadingCount < 1)
1723 while (fileLoadingPanels.size() > 0)
1725 removeProgressPanel(fileLoadingPanels.remove(0));
1727 fileLoadingPanels.clear();
1728 fileLoadingCount = 0;
1733 public static int getViewCount(String alignmentId)
1735 AlignmentViewport[] aps = getViewports(alignmentId);
1736 return (aps == null) ? 0 : aps.length;
1741 * @param alignmentId
1742 * - if null, all sets are returned
1743 * @return all AlignmentPanels concerning the alignmentId sequence set
1745 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1747 if (Desktop.desktop == null)
1749 // no frames created and in headless mode
1750 // TODO: verify that frames are recoverable when in headless mode
1753 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1754 AlignFrame[] frames = getAlignFrames();
1759 for (AlignFrame af : frames)
1761 for (AlignmentPanel ap : af.alignPanels)
1763 if (alignmentId == null
1764 || alignmentId.equals(ap.av.getSequenceSetId()))
1770 if (aps.size() == 0)
1774 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1779 * get all the viewports on an alignment.
1781 * @param sequenceSetId
1782 * unique alignment id (may be null - all viewports returned in that
1784 * @return all viewports on the alignment bound to sequenceSetId
1786 public static AlignmentViewport[] getViewports(String sequenceSetId)
1788 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1789 if (desktop != null)
1791 AlignFrame[] frames = Desktop.getAlignFrames();
1793 for (AlignFrame afr : frames)
1795 if (sequenceSetId == null
1796 || afr.getViewport().getSequenceSetId()
1797 .equals(sequenceSetId))
1799 if (afr.alignPanels != null)
1801 for (AlignmentPanel ap : afr.alignPanels)
1803 if (sequenceSetId == null
1804 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1812 viewp.add(afr.getViewport());
1816 if (viewp.size() > 0)
1818 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1825 * Explode the views in the given frame into separate AlignFrame
1829 public void explodeViews(AlignFrame af)
1831 int size = af.alignPanels.size();
1837 for (int i = 0; i < size; i++)
1839 AlignmentPanel ap = af.alignPanels.get(i);
1840 AlignFrame newaf = new AlignFrame(ap);
1843 * Restore the view's last exploded frame geometry if known. Multiple
1844 * views from one exploded frame share and restore the same (frame)
1845 * position and size.
1847 Rectangle geometry = ap.av.getExplodedGeometry();
1848 if (geometry != null)
1850 newaf.setBounds(geometry);
1853 ap.av.setGatherViewsHere(false);
1855 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1856 AlignFrame.DEFAULT_HEIGHT);
1859 af.alignPanels.clear();
1860 af.closeMenuItem_actionPerformed(true);
1865 * Gather expanded views (separate AlignFrame's) with the same sequence set
1866 * identifier back in to this frame as additional views, and close the
1867 * expanded views. Note the expanded frames may themselves have multiple
1868 * views. We take the lot.
1872 public void gatherViews(AlignFrame source)
1874 source.viewport.setGatherViewsHere(true);
1875 source.viewport.setExplodedGeometry(source.getBounds());
1876 JInternalFrame[] frames = desktop.getAllFrames();
1877 String viewId = source.viewport.getSequenceSetId();
1879 for (int t = 0; t < frames.length; t++)
1881 if (frames[t] instanceof AlignFrame && frames[t] != source)
1883 AlignFrame af = (AlignFrame) frames[t];
1884 boolean gatherThis = false;
1885 for (int a = 0; a < af.alignPanels.size(); a++)
1887 AlignmentPanel ap = af.alignPanels.get(a);
1888 if (viewId.equals(ap.av.getSequenceSetId()))
1891 ap.av.setGatherViewsHere(false);
1892 ap.av.setExplodedGeometry(af.getBounds());
1893 source.addAlignmentPanel(ap, false);
1899 af.alignPanels.clear();
1900 af.closeMenuItem_actionPerformed(true);
1907 jalview.gui.VamsasApplication v_client = null;
1910 public void vamsasImport_actionPerformed(ActionEvent e)
1912 if (v_client == null)
1914 // Load and try to start a session.
1915 JalviewFileChooser chooser = new JalviewFileChooser(
1916 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1918 chooser.setFileView(new JalviewFileView());
1919 chooser.setDialogTitle(MessageManager
1920 .getString("label.open_saved_vamsas_session"));
1921 chooser.setToolTipText(MessageManager
1922 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1924 int value = chooser.showOpenDialog(this);
1926 if (value == JalviewFileChooser.APPROVE_OPTION)
1928 String fle = chooser.getSelectedFile().toString();
1929 if (!vamsasImport(chooser.getSelectedFile()))
1932 .showInternalMessageDialog(
1934 MessageManager.formatMessage(
1935 "label.couldnt_import_as_vamsas_session",
1936 new Object[] { fle }),
1938 .getString("label.vamsas_document_import_failed"),
1939 JOptionPane.ERROR_MESSAGE);
1945 jalview.bin.Cache.log
1946 .error("Implementation error - load session from a running session is not supported.");
1951 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1954 * @return true if import was a success and a session was started.
1956 public boolean vamsasImport(URL url)
1958 // TODO: create progress bar
1959 if (v_client != null)
1962 jalview.bin.Cache.log
1963 .error("Implementation error - load session from a running session is not supported.");
1969 // copy the URL content to a temporary local file
1970 // TODO: be a bit cleverer here with nio (?!)
1971 File file = File.createTempFile("vdocfromurl", ".vdj");
1972 FileOutputStream fos = new FileOutputStream(file);
1973 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1974 byte[] buffer = new byte[2048];
1976 while ((ln = bis.read(buffer)) > -1)
1978 fos.write(buffer, 0, ln);
1982 v_client = new jalview.gui.VamsasApplication(this, file,
1983 url.toExternalForm());
1984 } catch (Exception ex)
1986 jalview.bin.Cache.log.error(
1987 "Failed to create new vamsas session from contents of URL "
1991 setupVamsasConnectedGui();
1992 v_client.initial_update(); // TODO: thread ?
1993 return v_client.inSession();
1997 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2000 * @return true if import was a success and a session was started.
2002 public boolean vamsasImport(File file)
2004 if (v_client != null)
2007 jalview.bin.Cache.log
2008 .error("Implementation error - load session from a running session is not supported.");
2012 setProgressBar(MessageManager.formatMessage(
2013 "status.importing_vamsas_session_from",
2014 new Object[] { file.getName() }), file.hashCode());
2017 v_client = new jalview.gui.VamsasApplication(this, file, null);
2018 } catch (Exception ex)
2020 setProgressBar(MessageManager.formatMessage(
2021 "status.importing_vamsas_session_from",
2022 new Object[] { file.getName() }), file.hashCode());
2023 jalview.bin.Cache.log.error(
2024 "New vamsas session from existing session file failed:", ex);
2027 setupVamsasConnectedGui();
2028 v_client.initial_update(); // TODO: thread ?
2029 setProgressBar(MessageManager.formatMessage(
2030 "status.importing_vamsas_session_from",
2031 new Object[] { file.getName() }), file.hashCode());
2032 return v_client.inSession();
2035 public boolean joinVamsasSession(String mysesid)
2037 if (v_client != null)
2041 .getString("error.try_join_vamsas_session_another"));
2043 if (mysesid == null)
2046 MessageManager.getString("error.invalid_vamsas_session_id"));
2048 v_client = new VamsasApplication(this, mysesid);
2049 setupVamsasConnectedGui();
2050 v_client.initial_update();
2051 return (v_client.inSession());
2055 public void vamsasStart_actionPerformed(ActionEvent e)
2057 if (v_client == null)
2060 // we just start a default session for moment.
2062 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2063 * getProperty("LAST_DIRECTORY"));
2065 * chooser.setFileView(new JalviewFileView());
2066 * chooser.setDialogTitle("Load Vamsas file");
2067 * chooser.setToolTipText("Import");
2069 * int value = chooser.showOpenDialog(this);
2071 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2072 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2074 v_client = new VamsasApplication(this);
2075 setupVamsasConnectedGui();
2076 v_client.initial_update(); // TODO: thread ?
2080 // store current data in session.
2081 v_client.push_update(); // TODO: thread
2085 protected void setupVamsasConnectedGui()
2087 vamsasStart.setText(MessageManager.getString("label.session_update"));
2088 vamsasSave.setVisible(true);
2089 vamsasStop.setVisible(true);
2090 vamsasImport.setVisible(false); // Document import to existing session is
2091 // not possible for vamsas-client-1.0.
2094 protected void setupVamsasDisconnectedGui()
2096 vamsasSave.setVisible(false);
2097 vamsasStop.setVisible(false);
2098 vamsasImport.setVisible(true);
2099 vamsasStart.setText(MessageManager
2100 .getString("label.new_vamsas_session"));
2104 public void vamsasStop_actionPerformed(ActionEvent e)
2106 if (v_client != null)
2108 v_client.end_session();
2110 setupVamsasDisconnectedGui();
2114 protected void buildVamsasStMenu()
2116 if (v_client == null)
2118 String[] sess = null;
2121 sess = VamsasApplication.getSessionList();
2122 } catch (Exception e)
2124 jalview.bin.Cache.log.warn(
2125 "Problem getting current sessions list.", e);
2130 jalview.bin.Cache.log.debug("Got current sessions list: "
2131 + sess.length + " entries.");
2132 VamsasStMenu.removeAll();
2133 for (int i = 0; i < sess.length; i++)
2135 JMenuItem sessit = new JMenuItem();
2136 sessit.setText(sess[i]);
2137 sessit.setToolTipText(MessageManager.formatMessage(
2138 "label.connect_to_session", new Object[] { sess[i] }));
2139 final Desktop dsktp = this;
2140 final String mysesid = sess[i];
2141 sessit.addActionListener(new ActionListener()
2145 public void actionPerformed(ActionEvent e)
2147 if (dsktp.v_client == null)
2149 Thread rthr = new Thread(new Runnable()
2155 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2156 dsktp.setupVamsasConnectedGui();
2157 dsktp.v_client.initial_update();
2165 VamsasStMenu.add(sessit);
2167 // don't show an empty menu.
2168 VamsasStMenu.setVisible(sess.length > 0);
2173 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2174 VamsasStMenu.removeAll();
2175 VamsasStMenu.setVisible(false);
2180 // Not interested in the content. Just hide ourselves.
2181 VamsasStMenu.setVisible(false);
2186 public void vamsasSave_actionPerformed(ActionEvent e)
2188 if (v_client != null)
2190 JalviewFileChooser chooser = new JalviewFileChooser(
2191 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2192 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2193 new String[] { "Vamsas Document" }, "Vamsas Document");
2195 chooser.setFileView(new JalviewFileView());
2196 chooser.setDialogTitle(MessageManager
2197 .getString("label.save_vamsas_document_archive"));
2199 int value = chooser.showSaveDialog(this);
2201 if (value == JalviewFileChooser.APPROVE_OPTION)
2203 java.io.File choice = chooser.getSelectedFile();
2204 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2205 "label.saving_vamsas_doc",
2206 new Object[] { choice.getName() }));
2207 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2208 String warnmsg = null;
2209 String warnttl = null;
2212 v_client.vclient.storeDocument(choice);
2215 warnttl = "Serious Problem saving Vamsas Document";
2216 warnmsg = ex.toString();
2217 jalview.bin.Cache.log.error("Error Whilst saving document to "
2220 } catch (Exception ex)
2222 warnttl = "Problem saving Vamsas Document.";
2223 warnmsg = ex.toString();
2224 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2228 removeProgressPanel(progpanel);
2229 if (warnmsg != null)
2231 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2233 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2239 JPanel vamUpdate = null;
2242 * hide vamsas user gui bits when a vamsas document event is being handled.
2245 * true to hide gui, false to reveal gui
2247 public void setVamsasUpdate(boolean b)
2249 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2250 + (b ? "in progress" : "finished"));
2252 if (vamUpdate != null)
2254 this.removeProgressPanel(vamUpdate);
2258 vamUpdate = this.addProgressPanel(MessageManager
2259 .getString("label.updating_vamsas_session"));
2261 vamsasStart.setVisible(!b);
2262 vamsasStop.setVisible(!b);
2263 vamsasSave.setVisible(!b);
2266 public JInternalFrame[] getAllFrames()
2268 return desktop.getAllFrames();
2272 * Checks the given url to see if it gives a response indicating that the user
2273 * should be informed of a new questionnaire.
2277 public void checkForQuestionnaire(String url)
2279 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2280 // javax.swing.SwingUtilities.invokeLater(jvq);
2281 new Thread(jvq).start();
2285 * Proxy class for JDesktopPane which optionally displays the current memory
2286 * usage and highlights the desktop area with a red bar if free memory runs
2291 public class MyDesktopPane extends JDesktopPane implements Runnable
2294 private static final float ONE_MB = 1048576f;
2296 boolean showMemoryUsage = false;
2300 java.text.NumberFormat df;
2302 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2305 public MyDesktopPane(boolean showMemoryUsage)
2307 showMemoryUsage(showMemoryUsage);
2310 public void showMemoryUsage(boolean showMemory)
2312 this.showMemoryUsage = showMemory;
2315 Thread worker = new Thread(this);
2320 public boolean isShowMemoryUsage()
2322 return showMemoryUsage;
2328 df = java.text.NumberFormat.getNumberInstance();
2329 df.setMaximumFractionDigits(2);
2330 runtime = Runtime.getRuntime();
2332 while (showMemoryUsage)
2336 maxMemory = runtime.maxMemory() / ONE_MB;
2337 allocatedMemory = runtime.totalMemory() / ONE_MB;
2338 freeMemory = runtime.freeMemory() / ONE_MB;
2339 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2341 percentUsage = (totalFreeMemory / maxMemory) * 100;
2343 // if (percentUsage < 20)
2345 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2347 // instance.set.setBorder(border1);
2350 // sleep after showing usage
2352 } catch (Exception ex)
2354 ex.printStackTrace();
2360 public void paintComponent(Graphics g)
2362 if (showMemoryUsage && g != null && df != null)
2364 if (percentUsage < 20)
2366 g.setColor(Color.red);
2368 FontMetrics fm = g.getFontMetrics();
2371 g.drawString(MessageManager.formatMessage(
2372 "label.memory_stats",
2373 new Object[] { df.format(totalFreeMemory),
2374 df.format(maxMemory), df.format(percentUsage) }), 10,
2375 getHeight() - fm.getHeight());
2382 * fixes stacking order after a modal dialog to ensure windows that should be
2383 * on top actually are
2385 public void relayerWindows()
2390 protected JMenuItem groovyShell;
2392 public void doGroovyCheck()
2394 if (jalview.bin.Cache.groovyJarsPresent())
2396 groovyShell = new JMenuItem();
2397 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2398 groovyShell.addActionListener(new ActionListener()
2401 public void actionPerformed(ActionEvent e)
2403 groovyShell_actionPerformed();
2406 toolsMenu.add(groovyShell);
2407 groovyShell.setVisible(true);
2412 * Accessor method to quickly get all the AlignmentFrames loaded.
2414 * @return an array of AlignFrame, or null if none found
2416 public static AlignFrame[] getAlignFrames()
2418 if (Jalview.isHeadlessMode())
2420 // Desktop.desktop is null in headless mode
2421 return new AlignFrame[] { currentAlignFrame };
2424 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2430 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2432 for (int i = frames.length - 1; i > -1; i--)
2434 if (frames[i] instanceof AlignFrame)
2436 avp.add((AlignFrame) frames[i]);
2438 else if (frames[i] instanceof SplitFrame)
2441 * Also check for a split frame containing an AlignFrame
2443 GSplitFrame sf = (GSplitFrame) frames[i];
2444 if (sf.getTopFrame() instanceof AlignFrame)
2446 avp.add((AlignFrame) sf.getTopFrame());
2448 if (sf.getBottomFrame() instanceof AlignFrame)
2450 avp.add((AlignFrame) sf.getBottomFrame());
2454 if (avp.size() == 0)
2458 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2463 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2467 public GStructureViewer[] getJmols()
2469 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2475 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2477 for (int i = frames.length - 1; i > -1; i--)
2479 if (frames[i] instanceof AppJmol)
2481 GStructureViewer af = (GStructureViewer) frames[i];
2485 if (avp.size() == 0)
2489 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2494 * Add Groovy Support to Jalview
2496 public void groovyShell_actionPerformed()
2498 if (!jalview.bin.Cache.groovyJarsPresent())
2502 .getString("error.implementation_error_cannot_create_groovyshell"));
2506 openGroovyConsole();
2507 } catch (Exception ex)
2509 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2510 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2512 MessageManager.getString("label.couldnt_create_groovy_shell"),
2513 MessageManager.getString("label.groovy_support_failed"),
2514 JOptionPane.ERROR_MESSAGE);
2519 * Open the Groovy console, using reflection to avoid creating compile-time
2520 * dependency on Groovy libraries
2522 * @throws ClassNotFoundException
2523 * @throws NoSuchMethodException
2524 * @throws InstantiationException
2525 * @throws IllegalAccessException
2526 * @throws InvocationTargetException
2528 void openGroovyConsole() throws ClassNotFoundException,
2529 NoSuchMethodException, InstantiationException,
2530 IllegalAccessException, InvocationTargetException
2532 Class<?> gcClass = Desktop.class.getClassLoader().loadClass(
2533 "groovy.ui.Console");
2534 Constructor<?> gccons = gcClass.getConstructor();
2535 groovyConsole = gccons.newInstance();
2538 * bind groovy variable 'Jalview' to the Desktop object
2540 Method setvar = gcClass.getMethod("setVariable", new Class[] {
2541 String.class, Object.class });
2542 setvar.invoke(groovyConsole, new Object[] { "Jalview", this });
2547 Method run = gcClass.getMethod("run");
2548 run.invoke(groovyConsole);
2551 * Allow only one console at a time, so that the AlignFrame menu option
2552 * 'Calculate | Run Groovy script' is unambiguous.
2553 * Disable 'new console', and enable 'Run script', when the console is
2554 * opened, and the reverse when it is closed
2556 Method getFrame = gcClass.getMethod("getFrame");
2557 Window window = (Window) getFrame.invoke(groovyConsole);
2558 window.addWindowListener(new WindowAdapter()
2561 public void windowClosed(WindowEvent e)
2563 groovyShell.setEnabled(true);
2564 enableExecuteGroovy(false);
2569 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2570 * and disable opening a second console
2572 groovyShell.setEnabled(false);
2573 enableExecuteGroovy(true);
2577 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2581 public void enableExecuteGroovy(boolean enabled)
2583 AlignFrame[] alignFrames = getAlignFrames();
2584 if (alignFrames != null)
2586 for (AlignFrame af : alignFrames)
2588 af.setGroovyEnabled(enabled);
2594 * Progress bars managed by the IProgressIndicator method.
2596 private Hashtable<Long, JPanel> progressBars;
2598 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2603 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2606 public void setProgressBar(String message, long id)
2608 if (progressBars == null)
2610 progressBars = new Hashtable<Long, JPanel>();
2611 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2614 if (progressBars.get(new Long(id)) != null)
2616 JPanel panel = progressBars.remove(new Long(id));
2617 if (progressBarHandlers.contains(new Long(id)))
2619 progressBarHandlers.remove(new Long(id));
2621 removeProgressPanel(panel);
2625 progressBars.put(new Long(id), addProgressPanel(message));
2632 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2633 * jalview.gui.IProgressIndicatorHandler)
2636 public void registerHandler(final long id,
2637 final IProgressIndicatorHandler handler)
2639 if (progressBarHandlers == null
2640 || !progressBars.containsKey(new Long(id)))
2644 .getString("error.call_setprogressbar_before_registering_handler"));
2646 progressBarHandlers.put(new Long(id), handler);
2647 final JPanel progressPanel = progressBars.get(new Long(id));
2648 if (handler.canCancel())
2650 JButton cancel = new JButton(
2651 MessageManager.getString("action.cancel"));
2652 final IProgressIndicator us = this;
2653 cancel.addActionListener(new ActionListener()
2657 public void actionPerformed(ActionEvent e)
2659 handler.cancelActivity(id);
2660 us.setProgressBar(MessageManager.formatMessage(
2661 "label.cancelled_params",
2662 new Object[] { ((JLabel) progressPanel.getComponent(0))
2666 progressPanel.add(cancel, BorderLayout.EAST);
2672 * @return true if any progress bars are still active
2675 public boolean operationInProgress()
2677 if (progressBars != null && progressBars.size() > 0)
2685 * This will return the first AlignFrame holding the given viewport instance.
2686 * It will break if there are more than one AlignFrames viewing a particular
2690 * @return alignFrame for viewport
2692 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2694 if (desktop != null)
2696 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2697 for (int panel = 0; aps != null && panel < aps.length; panel++)
2699 if (aps[panel] != null && aps[panel].av == viewport)
2701 return aps[panel].alignFrame;
2708 public VamsasApplication getVamsasApplication()
2715 * flag set if jalview GUI is being operated programmatically
2717 private boolean inBatchMode = false;
2720 * check if jalview GUI is being operated programmatically
2722 * @return inBatchMode
2724 public boolean isInBatchMode()
2730 * set flag if jalview GUI is being operated programmatically
2732 * @param inBatchMode
2734 public void setInBatchMode(boolean inBatchMode)
2736 this.inBatchMode = inBatchMode;
2739 public void startServiceDiscovery()
2741 startServiceDiscovery(false);
2744 public void startServiceDiscovery(boolean blocking)
2746 boolean alive = true;
2747 Thread t0 = null, t1 = null, t2 = null;
2748 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2751 // todo: changesupport handlers need to be transferred
2752 if (discoverer == null)
2754 discoverer = new jalview.ws.jws1.Discoverer();
2755 // register PCS handler for desktop.
2756 discoverer.addPropertyChangeListener(changeSupport);
2758 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2759 // until we phase out completely
2760 (t0 = new Thread(discoverer)).start();
2763 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2765 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2767 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2769 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2775 // TODO: do rest service discovery
2784 } catch (Exception e)
2787 alive = (t1 != null && t1.isAlive())
2788 || (t2 != null && t2.isAlive())
2789 || (t3 != null && t3.isAlive())
2790 || (t0 != null && t0.isAlive());
2796 * called to check if the service discovery process completed successfully.
2800 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2802 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2804 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2805 .getErrorMessages();
2808 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2810 if (serviceChangedDialog == null)
2812 // only run if we aren't already displaying one of these.
2813 addDialogThread(serviceChangedDialog = new Runnable()
2820 * JalviewDialog jd =new JalviewDialog() {
2822 * @Override protected void cancelPressed() { // TODO
2823 * Auto-generated method stub
2825 * }@Override protected void okPressed() { // TODO
2826 * Auto-generated method stub
2828 * }@Override protected void raiseClosed() { // TODO
2829 * Auto-generated method stub
2831 * } }; jd.initDialogFrame(new
2832 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2833 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2834 * + " or mis-configured HTTP proxy settings.<br/>" +
2835 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2837 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2838 * ), true, true, "Web Service Configuration Problem", 450,
2841 * jd.waitForInput();
2847 "<html><table width=\"450\"><tr><td>"
2849 + "</td></tr></table>"
2850 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2851 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2852 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2853 + " Tools->Preferences dialog box to change them.</p></html>"),
2854 "Web Service Configuration Problem",
2855 JOptionPane.DEFAULT_OPTION,
2856 JOptionPane.ERROR_MESSAGE);
2857 serviceChangedDialog = null;
2866 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2873 private Runnable serviceChangedDialog = null;
2876 * start a thread to open a URL in the configured browser. Pops up a warning
2877 * dialog to the user if there is an exception when calling out to the browser
2882 public static void showUrl(final String url)
2884 showUrl(url, Desktop.instance);
2888 * Like showUrl but allows progress handler to be specified
2892 * (null) or object implementing IProgressIndicator
2894 public static void showUrl(final String url,
2895 final IProgressIndicator progress)
2897 new Thread(new Runnable()
2904 if (progress != null)
2906 progress.setProgressBar(MessageManager.formatMessage(
2907 "status.opening_params", new Object[] { url }), this
2910 jalview.util.BrowserLauncher.openURL(url);
2911 } catch (Exception ex)
2913 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2915 .getString("label.web_browser_not_found_unix"),
2916 MessageManager.getString("label.web_browser_not_found"),
2917 JOptionPane.WARNING_MESSAGE);
2919 ex.printStackTrace();
2921 if (progress != null)
2923 progress.setProgressBar(null, this.hashCode());
2929 public static WsParamSetManager wsparamManager = null;
2931 public static ParamManager getUserParameterStore()
2933 if (wsparamManager == null)
2935 wsparamManager = new WsParamSetManager();
2937 return wsparamManager;
2941 * static hyperlink handler proxy method for use by Jalview's internal windows
2945 public static void hyperlinkUpdate(HyperlinkEvent e)
2947 if (e.getEventType() == EventType.ACTIVATED)
2952 url = e.getURL().toString();
2953 Desktop.showUrl(url);
2954 } catch (Exception x)
2958 if (Cache.log != null)
2960 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2964 System.err.println("Couldn't handle string " + url
2968 // ignore any exceptions due to dud links.
2975 * single thread that handles display of dialogs to user.
2977 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2980 * flag indicating if dialogExecutor should try to acquire a permit
2982 private volatile boolean dialogPause = true;
2987 private java.util.concurrent.Semaphore block = new Semaphore(0);
2990 * groovy.ui.Console object - if Groovy jars are present and the
2991 * user has activated the Groovy console. Use via reflection to
2992 * avoid compile-time dependency on Groovy libraries.
2994 private static Object groovyConsole;
2997 * add another dialog thread to the queue
3001 public void addDialogThread(final Runnable prompter)
3003 dialogExecutor.submit(new Runnable()
3013 } catch (InterruptedException x)
3018 if (instance == null)
3024 SwingUtilities.invokeAndWait(prompter);
3025 } catch (Exception q)
3027 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3033 public void startDialogQueue()
3035 // set the flag so we don't pause waiting for another permit and semaphore
3036 // the current task to begin
3037 dialogPause = false;
3042 protected void snapShotWindow_actionPerformed(ActionEvent e)
3046 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3047 "View of Desktop", getWidth(), getHeight(), of = new File(
3048 "Jalview_snapshot" + System.currentTimeMillis()
3049 + ".eps"), "View of desktop", null, 0, false);
3052 paintAll(im.getGraphics());
3054 } catch (Exception q)
3056 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3060 Cache.log.info("Successfully written snapshot to file "
3061 + of.getAbsolutePath());
3065 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3066 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3067 * and location last time the view was expanded (if any). However it does not
3068 * remember the split pane divider location - this is set to match the
3069 * 'exploding' frame.
3073 public void explodeViews(SplitFrame sf)
3075 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3076 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3077 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3079 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3081 int viewCount = topPanels.size();
3088 * Processing in reverse order works, forwards order leaves the first panels
3089 * not visible. I don't know why!
3091 for (int i = viewCount - 1; i >= 0; i--)
3094 * Make new top and bottom frames. These take over the respective
3095 * AlignmentPanel objects, including their AlignmentViewports, so the
3096 * cdna/protein relationships between the viewports is carried over to the
3099 * explodedGeometry holds the (x, y) position of the previously exploded
3100 * SplitFrame, and the (width, height) of the AlignFrame component
3102 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3103 AlignFrame newTopFrame = new AlignFrame(topPanel);
3104 newTopFrame.setSize(oldTopFrame.getSize());
3105 newTopFrame.setVisible(true);
3106 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3107 .getExplodedGeometry();
3108 if (geometry != null)
3110 newTopFrame.setSize(geometry.getSize());
3113 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3114 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3115 newBottomFrame.setSize(oldBottomFrame.getSize());
3116 newBottomFrame.setVisible(true);
3117 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3118 .getExplodedGeometry();
3119 if (geometry != null)
3121 newBottomFrame.setSize(geometry.getSize());
3124 topPanel.av.setGatherViewsHere(false);
3125 bottomPanel.av.setGatherViewsHere(false);
3126 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3128 if (geometry != null)
3130 splitFrame.setLocation(geometry.getLocation());
3132 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3136 * Clear references to the panels (now relocated in the new SplitFrames)
3137 * before closing the old SplitFrame.
3140 bottomPanels.clear();
3145 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3146 * back into the given SplitFrame as additional views. Note that the gathered
3147 * frames may themselves have multiple views.
3151 public void gatherViews(GSplitFrame source)
3154 * special handling of explodedGeometry for a view within a SplitFrame: - it
3155 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3156 * height) of the AlignFrame component
3158 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3159 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3160 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3161 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3162 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3163 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3165 myTopFrame.viewport.setGatherViewsHere(true);
3166 myBottomFrame.viewport.setGatherViewsHere(true);
3167 String topViewId = myTopFrame.viewport.getSequenceSetId();
3168 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3170 JInternalFrame[] frames = desktop.getAllFrames();
3171 for (JInternalFrame frame : frames)
3173 if (frame instanceof SplitFrame && frame != source)
3175 SplitFrame sf = (SplitFrame) frame;
3176 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3177 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3178 boolean gatherThis = false;
3179 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3181 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3182 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3183 if (topViewId.equals(topPanel.av.getSequenceSetId())
3184 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3187 topPanel.av.setGatherViewsHere(false);
3188 bottomPanel.av.setGatherViewsHere(false);
3189 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3190 topFrame.getSize()));
3191 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3192 .getLocation(), bottomFrame.getSize()));
3193 myTopFrame.addAlignmentPanel(topPanel, false);
3194 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3200 topFrame.getAlignPanels().clear();
3201 bottomFrame.getAlignPanels().clear();
3208 * The dust settles...give focus to the tab we did this from.
3210 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3214 public static AlignFrame getCurrentAlignFrame()
3216 return currentAlignFrame;
3219 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
3221 Desktop.currentAlignFrame = currentAlignFrame;
3224 public static Object getGroovyConsole()
3226 return groovyConsole;