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;
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 public static jalview.ws.jws1.Discoverer discoverer;
174 public static Object[] jalviewClipboard;
176 public static boolean internalCopy = false;
178 static int fileLoadingCount = 0;
180 class MyDesktopManager implements DesktopManager
183 private DesktopManager delegate;
185 public MyDesktopManager(DesktopManager delegate)
187 this.delegate = delegate;
191 public void activateFrame(JInternalFrame f)
195 delegate.activateFrame(f);
196 } catch (NullPointerException npe)
198 Point p = getMousePosition();
199 instance.showPasteMenu(p.x, p.y);
204 public void beginDraggingFrame(JComponent f)
206 delegate.beginDraggingFrame(f);
210 public void beginResizingFrame(JComponent f, int direction)
212 delegate.beginResizingFrame(f, direction);
216 public void closeFrame(JInternalFrame f)
218 delegate.closeFrame(f);
222 public void deactivateFrame(JInternalFrame f)
224 delegate.deactivateFrame(f);
228 public void deiconifyFrame(JInternalFrame f)
230 delegate.deiconifyFrame(f);
234 public void dragFrame(JComponent f, int newX, int newY)
240 delegate.dragFrame(f, newX, newY);
244 public void endDraggingFrame(JComponent f)
246 delegate.endDraggingFrame(f);
250 public void endResizingFrame(JComponent f)
252 delegate.endResizingFrame(f);
256 public void iconifyFrame(JInternalFrame f)
258 delegate.iconifyFrame(f);
262 public void maximizeFrame(JInternalFrame f)
264 delegate.maximizeFrame(f);
268 public void minimizeFrame(JInternalFrame f)
270 delegate.minimizeFrame(f);
274 public void openFrame(JInternalFrame f)
276 delegate.openFrame(f);
280 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
287 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
291 public void setBoundsForFrame(JComponent f, int newX, int newY,
292 int newWidth, int newHeight)
294 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
297 // All other methods, simply delegate
302 * Creates a new Desktop object.
307 * A note to implementors. It is ESSENTIAL that any activities that might
308 * block are spawned off as threads rather than waited for during this
312 doVamsasClientCheck();
314 groovyShell = new JMenuItem();
315 groovyShell.setText(MessageManager.getString("label.groovy_console"));
316 groovyShell.addActionListener(new ActionListener()
319 public void actionPerformed(ActionEvent e)
321 groovyShell_actionPerformed();
324 toolsMenu.add(groovyShell);
325 groovyShell.setVisible(true);
327 doConfigureStructurePrefs();
328 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
329 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
330 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
332 boolean showjconsole = jalview.bin.Cache.getDefault(
333 "SHOW_JAVA_CONSOLE", false);
334 desktop = new MyDesktopPane(selmemusage);
335 if (Platform.isAMac())
337 desktop.setDoubleBuffered(false);
339 showMemusage.setSelected(selmemusage);
340 desktop.setBackground(Color.white);
341 getContentPane().setLayout(new BorderLayout());
342 // alternate config - have scrollbars - see notes in JAL-153
343 // JScrollPane sp = new JScrollPane();
344 // sp.getViewport().setView(desktop);
345 // getContentPane().add(sp, BorderLayout.CENTER);
346 getContentPane().add(desktop, BorderLayout.CENTER);
347 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
349 // This line prevents Windows Look&Feel resizing all new windows to maximum
350 // if previous window was maximised
351 desktop.setDesktopManager(new MyDesktopManager(
352 new DefaultDesktopManager()));
354 Rectangle dims = getLastKnownDimensions("");
361 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
362 setBounds((screenSize.width - 900) / 2,
363 (screenSize.height - 650) / 2, 900, 650);
365 jconsole = new Console(this, showjconsole);
366 // add essential build information
367 jconsole.setHeader("Jalview Version: "
368 + jalview.bin.Cache.getProperty("VERSION") + "\n"
369 + "Jalview Installation: "
370 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
371 + "\n" + "Build Date: "
372 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
373 + "Java version: " + System.getProperty("java.version") + "\n"
374 + System.getProperty("os.arch") + " "
375 + System.getProperty("os.name") + " "
376 + System.getProperty("os.version"));
378 showConsole(showjconsole);
380 showNews.setVisible(false);
382 this.addWindowListener(new WindowAdapter()
385 public void windowClosing(WindowEvent evt)
392 this.addMouseListener(ma = new MouseAdapter()
395 public void mousePressed(MouseEvent evt)
397 if (evt.isPopupTrigger())
399 showPasteMenu(evt.getX(), evt.getY());
403 desktop.addMouseListener(ma);
405 this.addFocusListener(new FocusListener()
409 public void focusLost(FocusEvent e)
411 // TODO Auto-generated method stub
416 public void focusGained(FocusEvent e)
418 Cache.log.debug("Relaying windows after focus gain");
419 // make sure that we sort windows properly after we gain focus
420 instance.relayerWindows();
423 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
424 // Spawn a thread that shows the splashscreen
425 SwingUtilities.invokeLater(new Runnable()
435 // Thread off a new instance of the file chooser - this reduces the time it
436 // takes to open it later on.
437 new Thread(new Runnable()
442 Cache.log.debug("Filechooser init thread started.");
443 new JalviewFileChooser(
444 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
445 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
446 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
447 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
448 Cache.log.debug("Filechooser init thread finished.");
451 // Add the service change listener
452 changeSupport.addJalviewPropertyChangeListener("services",
453 new PropertyChangeListener()
457 public void propertyChange(PropertyChangeEvent evt)
459 Cache.log.debug("Firing service changed event for "
460 + evt.getNewValue());
461 JalviewServicesChanged(evt);
467 public void doConfigureStructurePrefs()
469 // configure services
470 StructureSelectionManager ssm = StructureSelectionManager
471 .getStructureSelectionManager(this);
472 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
474 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
475 Preferences.ADD_TEMPFACT_ANN, true));
476 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
477 Preferences.STRUCT_FROM_PDB, true));
478 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
479 Preferences.USE_RNAVIEW, true));
483 ssm.setAddTempFacAnnot(false);
484 ssm.setProcessSecondaryStructure(false);
485 ssm.setSecStructServices(false);
489 public void checkForNews()
491 final Desktop me = this;
492 // Thread off the news reader, in case there are connection problems.
493 addDialogThread(new Runnable()
498 Cache.log.debug("Starting news thread.");
500 jvnews = new BlogReader(me);
501 showNews.setVisible(true);
502 Cache.log.debug("Completed news thread.");
508 protected void showNews_actionPerformed(ActionEvent e)
510 showNews(showNews.isSelected());
513 void showNews(boolean visible)
516 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
517 showNews.setSelected(visible);
518 if (visible && !jvnews.isVisible())
520 new Thread(new Runnable()
525 long now = System.currentTimeMillis();
526 Desktop.instance.setProgressBar(
527 MessageManager.getString("status.refreshing_news"), now);
528 jvnews.refreshNews();
529 Desktop.instance.setProgressBar(null, now);
538 * recover the last known dimensions for a jalview window
541 * - empty string is desktop, all other windows have unique prefix
542 * @return null or last known dimensions scaled to current geometry (if last
543 * window geom was known)
545 Rectangle getLastKnownDimensions(String windowName)
547 // TODO: lock aspect ratio for scaling desktop Bug #0058199
548 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
549 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
550 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
551 String width = jalview.bin.Cache.getProperty(windowName
553 String height = jalview.bin.Cache.getProperty(windowName
555 if ((x != null) && (y != null) && (width != null) && (height != null))
557 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
558 .parseInt(width), ih = Integer.parseInt(height);
559 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
561 // attempt #1 - try to cope with change in screen geometry - this
562 // version doesn't preserve original jv aspect ratio.
563 // take ratio of current screen size vs original screen size.
564 double sw = ((1f * screenSize.width) / (1f * Integer
565 .parseInt(jalview.bin.Cache
566 .getProperty("SCREENGEOMETRY_WIDTH"))));
567 double sh = ((1f * screenSize.height) / (1f * Integer
568 .parseInt(jalview.bin.Cache
569 .getProperty("SCREENGEOMETRY_HEIGHT"))));
570 // rescale the bounds depending upon the current screen geometry.
571 ix = (int) (ix * sw);
572 iw = (int) (iw * sw);
573 iy = (int) (iy * sh);
574 ih = (int) (ih * sh);
575 while (ix >= screenSize.width)
577 jalview.bin.Cache.log
578 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
579 ix -= screenSize.width;
581 while (iy >= screenSize.height)
583 jalview.bin.Cache.log
584 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
585 iy -= screenSize.height;
587 jalview.bin.Cache.log.debug("Got last known dimensions for "
588 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
591 // return dimensions for new instance
592 return new Rectangle(ix, iy, iw, ih);
597 private void doVamsasClientCheck()
599 if (jalview.bin.Cache.vamsasJarsPresent())
601 setupVamsasDisconnectedGui();
602 VamsasMenu.setVisible(true);
603 final Desktop us = this;
604 VamsasMenu.addMenuListener(new MenuListener()
606 // this listener remembers when the menu was first selected, and
607 // doesn't rebuild the session list until it has been cleared and
609 boolean refresh = true;
612 public void menuCanceled(MenuEvent e)
618 public void menuDeselected(MenuEvent e)
624 public void menuSelected(MenuEvent e)
628 us.buildVamsasStMenu();
633 vamsasStart.setVisible(true);
637 void showPasteMenu(int x, int y)
639 JPopupMenu popup = new JPopupMenu();
640 JMenuItem item = new JMenuItem(
641 MessageManager.getString("label.paste_new_window"));
642 item.addActionListener(new ActionListener()
645 public void actionPerformed(ActionEvent evt)
652 popup.show(this, x, y);
659 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
660 Transferable contents = c.getContents(this);
662 if (contents != null)
664 String file = (String) contents
665 .getTransferData(DataFlavor.stringFlavor);
667 String format = new IdentifyFile().identify(file,
668 FormatAdapter.PASTE);
670 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
673 } catch (Exception ex)
676 .println("Unable to paste alignment from system clipboard:\n"
682 * Adds and opens the given frame to the desktop
693 public static synchronized void addInternalFrame(
694 final JInternalFrame frame, String title, int w, int h)
696 addInternalFrame(frame, title, true, w, h, true);
700 * Add an internal frame to the Jalview desktop
707 * When true, display frame immediately, otherwise, caller must call
708 * setVisible themselves.
714 public static synchronized void addInternalFrame(
715 final JInternalFrame frame, String title, boolean makeVisible,
718 addInternalFrame(frame, title, makeVisible, w, h, true);
722 * Add an internal frame to the Jalview desktop and make it visible
735 public static synchronized void addInternalFrame(
736 final JInternalFrame frame, String title, int w, int h,
739 addInternalFrame(frame, title, true, w, h, resizable);
743 * Add an internal frame to the Jalview desktop
750 * When true, display frame immediately, otherwise, caller must call
751 * setVisible themselves.
759 public static synchronized void addInternalFrame(
760 final JInternalFrame frame, String title, boolean makeVisible,
761 int w, int h, boolean resizable)
764 // TODO: allow callers to determine X and Y position of frame (eg. via
766 // TODO: consider fixing method to update entries in the window submenu with
767 // the current window title
769 frame.setTitle(title);
770 if (frame.getWidth() < 1 || frame.getHeight() < 1)
774 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
775 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
776 // IF JALVIEW IS RUNNING HEADLESS
777 // ///////////////////////////////////////////////
779 || (System.getProperty("java.awt.headless") != null && System
780 .getProperty("java.awt.headless").equals("true")))
787 frame.setVisible(makeVisible);
788 frame.setClosable(true);
789 frame.setResizable(resizable);
790 frame.setMaximizable(resizable);
791 frame.setIconifiable(resizable);
792 if (Platform.isAMac())
794 frame.setIconifiable(false);
795 frame.setFrameIcon(null);
796 // frame.setDesktopIcon(null);
797 frame.setDoubleBuffered(false);
799 if (frame.getX() < 1 && frame.getY() < 1)
801 frame.setLocation(xOffset * openFrameCount, yOffset
802 * ((openFrameCount - 1) % 10) + yOffset);
805 final JMenuItem menuItem = new JMenuItem(title);
806 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
809 public void internalFrameActivated(
810 javax.swing.event.InternalFrameEvent evt)
812 JInternalFrame itf = desktop.getSelectedFrame();
821 public void internalFrameClosed(
822 javax.swing.event.InternalFrameEvent evt)
824 PaintRefresher.RemoveComponent(frame);
826 windowMenu.remove(menuItem);
827 JInternalFrame itf = desktop.getSelectedFrame();
836 menuItem.addActionListener(new ActionListener()
839 public void actionPerformed(ActionEvent e)
843 frame.setSelected(true);
844 frame.setIcon(false);
845 } catch (java.beans.PropertyVetoException ex)
851 menuItem.addMouseListener(new MouseListener()
855 public void mouseReleased(MouseEvent e)
860 public void mousePressed(MouseEvent e)
865 public void mouseExited(MouseEvent e)
869 frame.setSelected(false);
870 } catch (PropertyVetoException e1)
876 public void mouseEntered(MouseEvent e)
880 frame.setSelected(true);
881 } catch (PropertyVetoException e1)
887 public void mouseClicked(MouseEvent e)
893 windowMenu.add(menuItem);
899 frame.setSelected(true);
900 frame.requestFocus();
901 } catch (java.beans.PropertyVetoException ve)
903 } catch (java.lang.ClassCastException cex)
906 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
912 public void lostOwnership(Clipboard clipboard, Transferable contents)
916 Desktop.jalviewClipboard = null;
919 internalCopy = false;
923 public void dragEnter(DropTargetDragEvent evt)
928 public void dragExit(DropTargetEvent evt)
933 public void dragOver(DropTargetDragEvent evt)
938 public void dropActionChanged(DropTargetDragEvent evt)
949 public void drop(DropTargetDropEvent evt)
951 boolean success = true;
952 Transferable t = evt.getTransferable();
953 java.util.List files = null;
954 java.util.List protocols = null;
958 DataFlavor uriListFlavor = new DataFlavor(
959 "text/uri-list;class=java.lang.String");
960 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
962 // Works on Windows and MacOSX
963 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
964 files = (java.util.List) t
965 .getTransferData(DataFlavor.javaFileListFlavor);
967 else if (t.isDataFlavorSupported(uriListFlavor))
969 // This is used by Unix drag system
970 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
971 String data = (String) t.getTransferData(uriListFlavor);
972 files = new java.util.ArrayList(1);
973 protocols = new java.util.ArrayList(1);
974 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
975 data, "\r\n"); st.hasMoreTokens();)
977 String s = st.nextToken();
978 if (s.startsWith("#"))
980 // the line is a comment (as per the RFC 2483)
983 java.net.URI uri = new java.net.URI(s);
984 if (uri.getScheme().toLowerCase().startsWith("http"))
986 protocols.add(FormatAdapter.URL);
987 files.add(uri.toString());
991 // otherwise preserve old behaviour: catch all for file objects
992 java.io.File file = new java.io.File(uri);
993 protocols.add(FormatAdapter.FILE);
994 files.add(file.toString());
998 } catch (Exception e)
1007 for (int i = 0; i < files.size(); i++)
1009 String file = files.get(i).toString();
1010 String protocol = (protocols == null) ? FormatAdapter.FILE
1011 : (String) protocols.get(i);
1012 String format = null;
1014 if (file.endsWith(".jar"))
1021 format = new IdentifyFile().identify(file, protocol);
1024 new FileLoader().LoadFile(file, protocol, format);
1027 } catch (Exception ex)
1032 evt.dropComplete(success); // need this to ensure input focus is properly
1033 // transfered to any new windows created
1043 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1045 JalviewFileChooser chooser = new JalviewFileChooser(
1046 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1047 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1048 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1049 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1051 chooser.setFileView(new JalviewFileView());
1052 chooser.setDialogTitle(MessageManager
1053 .getString("label.open_local_file"));
1054 chooser.setToolTipText(MessageManager.getString("action.open"));
1056 int value = chooser.showOpenDialog(this);
1058 if (value == JalviewFileChooser.APPROVE_OPTION)
1060 String choice = chooser.getSelectedFile().getPath();
1061 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1062 .getSelectedFile().getParent());
1064 String format = null;
1065 if (chooser.getSelectedFormat() != null
1066 && chooser.getSelectedFormat().equals("Jalview"))
1072 format = new IdentifyFile().identify(choice, FormatAdapter.FILE);
1075 if (viewport != null)
1077 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1082 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1094 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1096 // This construct allows us to have a wider textfield
1098 JLabel label = new JLabel(
1099 MessageManager.getString("label.input_file_url"));
1100 final JComboBox history = new JComboBox();
1102 JPanel panel = new JPanel(new GridLayout(2, 1));
1105 history.setPreferredSize(new Dimension(400, 20));
1106 history.setEditable(true);
1107 history.addItem("http://www.");
1109 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1113 if (historyItems != null)
1115 st = new StringTokenizer(historyItems, "\t");
1117 while (st.hasMoreTokens())
1119 history.addItem(st.nextElement());
1123 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1124 MessageManager.getString("label.input_alignment_from_url"),
1125 JOptionPane.OK_CANCEL_OPTION);
1127 if (reply != JOptionPane.OK_OPTION)
1132 String url = history.getSelectedItem().toString();
1134 if (url.toLowerCase().endsWith(".jar"))
1136 if (viewport != null)
1138 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1143 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1148 String format = new IdentifyFile().identify(url, FormatAdapter.URL);
1150 if (format.equals("URL NOT FOUND"))
1152 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1153 MessageManager.formatMessage("label.couldnt_locate",
1154 new Object[] { url }), MessageManager
1155 .getString("label.url_not_found"),
1156 JOptionPane.WARNING_MESSAGE);
1161 if (viewport != null)
1163 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1167 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1173 * Opens the CutAndPaste window for the user to paste an alignment in to
1176 * - if not null, the pasted alignment is added to the current
1177 * alignment; if null, to a new alignment window
1180 public void inputTextboxMenuItem_actionPerformed(
1181 AlignmentViewPanel viewPanel)
1183 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1184 cap.setForInput(viewPanel);
1185 Desktop.addInternalFrame(cap,
1186 MessageManager.getString("label.cut_paste_alignmen_file"),
1196 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1198 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1199 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1201 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1202 getBounds().y, getWidth(), getHeight()));
1204 if (jconsole != null)
1206 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1207 jconsole.stopConsole();
1211 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1214 if (dialogExecutor != null)
1216 dialogExecutor.shutdownNow();
1218 closeAll_actionPerformed(null);
1222 private void storeLastKnownDimensions(String string, Rectangle jc)
1224 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1225 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1226 + " height:" + jc.height);
1228 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1229 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1230 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1231 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1241 public void aboutMenuItem_actionPerformed(ActionEvent e)
1243 // StringBuffer message = getAboutMessage(false);
1244 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1246 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1247 new Thread(new Runnable()
1252 new SplashScreen(true);
1257 public StringBuffer getAboutMessage(boolean shortv)
1259 StringBuffer message = new StringBuffer();
1260 message.append("<html>");
1263 message.append("<h1><strong>Version: "
1264 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1265 message.append("<strong>Last Updated: <em>"
1266 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1267 + "</em></strong>");
1273 message.append("<strong>Version "
1274 + jalview.bin.Cache.getProperty("VERSION")
1275 + "; last updated: "
1276 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1279 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1282 message.append("<br>...Checking latest version...</br>");
1284 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1285 .equals(jalview.bin.Cache.getProperty("VERSION")))
1287 boolean red = false;
1288 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1289 .indexOf("automated build") == -1)
1292 // Displayed when code version and jnlp version do not match and code
1293 // version is not a development build
1294 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1297 message.append("<br>!! Version "
1298 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1300 + " is available for download from "
1301 + jalview.bin.Cache.getDefault("www.jalview.org",
1302 "http://www.jalview.org") + " !!");
1305 message.append("</div>");
1308 message.append("<br>Authors: "
1310 .getDefault("AUTHORFNAMES",
1311 "The Jalview Authors (See AUTHORS file for current list)")
1312 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1313 + "<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"
1314 + "<br><br>If you use Jalview, please cite:"
1315 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1316 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1317 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1329 public void documentationMenuItem_actionPerformed(ActionEvent e)
1333 Help.showHelpWindow();
1334 } catch (Exception ex)
1340 public void closeAll_actionPerformed(ActionEvent e)
1342 JInternalFrame[] frames = desktop.getAllFrames();
1343 for (int i = 0; i < frames.length; i++)
1347 frames[i].setClosed(true);
1348 } catch (java.beans.PropertyVetoException ex)
1352 System.out.println("ALL CLOSED");
1353 if (v_client != null)
1355 // TODO clear binding to vamsas document objects on close_all
1359 * reset state of singleton objects as appropriate (clear down session state
1360 * when all windows are closed)
1362 StructureSelectionManager ssm = StructureSelectionManager
1363 .getStructureSelectionManager(this);
1371 public void raiseRelated_actionPerformed(ActionEvent e)
1373 reorderAssociatedWindows(false, false);
1377 public void minimizeAssociated_actionPerformed(ActionEvent e)
1379 reorderAssociatedWindows(true, false);
1382 void closeAssociatedWindows()
1384 reorderAssociatedWindows(false, true);
1390 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1394 protected void garbageCollect_actionPerformed(ActionEvent e)
1396 // We simply collect the garbage
1397 jalview.bin.Cache.log.debug("Collecting garbage...");
1399 jalview.bin.Cache.log.debug("Finished garbage collection.");
1406 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1410 protected void showMemusage_actionPerformed(ActionEvent e)
1412 desktop.showMemoryUsage(showMemusage.isSelected());
1419 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1423 protected void showConsole_actionPerformed(ActionEvent e)
1425 showConsole(showConsole.isSelected());
1428 Console jconsole = null;
1431 * control whether the java console is visible or not
1435 void showConsole(boolean selected)
1437 showConsole.setSelected(selected);
1438 // TODO: decide if we should update properties file
1439 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1441 jconsole.setVisible(selected);
1444 void reorderAssociatedWindows(boolean minimize, boolean close)
1446 JInternalFrame[] frames = desktop.getAllFrames();
1447 if (frames == null || frames.length < 1)
1452 AlignmentViewport source = null, target = null;
1453 if (frames[0] instanceof AlignFrame)
1455 source = ((AlignFrame) frames[0]).getCurrentView();
1457 else if (frames[0] instanceof TreePanel)
1459 source = ((TreePanel) frames[0]).getViewPort();
1461 else if (frames[0] instanceof PCAPanel)
1463 source = ((PCAPanel) frames[0]).av;
1465 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1467 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1472 for (int i = 0; i < frames.length; i++)
1475 if (frames[i] == null)
1479 if (frames[i] instanceof AlignFrame)
1481 target = ((AlignFrame) frames[i]).getCurrentView();
1483 else if (frames[i] instanceof TreePanel)
1485 target = ((TreePanel) frames[i]).getViewPort();
1487 else if (frames[i] instanceof PCAPanel)
1489 target = ((PCAPanel) frames[i]).av;
1491 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1493 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1496 if (source == target)
1502 frames[i].setClosed(true);
1506 frames[i].setIcon(minimize);
1509 frames[i].toFront();
1513 } catch (java.beans.PropertyVetoException ex)
1528 protected void preferences_actionPerformed(ActionEvent e)
1540 public void saveState_actionPerformed(ActionEvent e)
1542 JalviewFileChooser chooser = new JalviewFileChooser(
1543 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1544 new String[] { "jvp" }, new String[] { "Jalview Project" },
1547 chooser.setFileView(new JalviewFileView());
1548 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1550 int value = chooser.showSaveDialog(this);
1552 if (value == JalviewFileChooser.APPROVE_OPTION)
1554 final Desktop me = this;
1555 final java.io.File choice = chooser.getSelectedFile();
1556 setProjectFile(choice);
1558 new Thread(new Runnable()
1563 // TODO: refactor to Jalview desktop session controller action.
1564 setProgressBar(MessageManager.formatMessage(
1565 "label.saving_jalview_project",
1566 new Object[] { choice.getName() }), choice.hashCode());
1567 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1568 choice.getParent());
1569 // TODO catch and handle errors for savestate
1570 // TODO prevent user from messing with the Desktop whilst we're saving
1573 new Jalview2XML().saveState(choice);
1574 } catch (OutOfMemoryError oom)
1576 new OOMWarning("Whilst saving current state to "
1577 + choice.getName(), oom);
1578 } catch (Exception ex)
1581 "Problems whilst trying to save to " + choice.getName(),
1583 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1584 "label.error_whilst_saving_current_state_to",
1585 new Object[] { choice.getName() }), MessageManager
1586 .getString("label.couldnt_save_project"),
1587 JOptionPane.WARNING_MESSAGE);
1589 setProgressBar(null, choice.hashCode());
1595 private void setProjectFile(File choice)
1597 this.projectFile = choice;
1600 public File getProjectFile()
1602 return this.projectFile;
1612 public void loadState_actionPerformed(ActionEvent e)
1614 JalviewFileChooser chooser = new JalviewFileChooser(
1615 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1616 "jvp", "jar" }, new String[] { "Jalview Project",
1617 "Jalview Project (old)" }, "Jalview Project");
1618 chooser.setFileView(new JalviewFileView());
1619 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1621 int value = chooser.showOpenDialog(this);
1623 if (value == JalviewFileChooser.APPROVE_OPTION)
1625 final File selectedFile = chooser.getSelectedFile();
1626 setProjectFile(selectedFile);
1627 final String choice = selectedFile.getAbsolutePath();
1628 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1629 selectedFile.getParent());
1630 new Thread(new Runnable()
1636 MessageManager.formatMessage(
1637 "label.loading_jalview_project",
1638 new Object[] { choice }), choice.hashCode());
1641 new Jalview2XML().loadJalviewAlign(choice);
1642 } catch (OutOfMemoryError oom)
1644 new OOMWarning("Whilst loading project from " + choice, oom);
1645 } catch (Exception ex)
1647 Cache.log.error("Problems whilst loading project from "
1649 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1651 "label.error_whilst_loading_project_from",
1652 new Object[] { choice }), MessageManager
1653 .getString("label.couldnt_load_project"),
1654 JOptionPane.WARNING_MESSAGE);
1656 setProgressBar(null, choice.hashCode());
1663 public void inputSequence_actionPerformed(ActionEvent e)
1665 new SequenceFetcher(this);
1668 JPanel progressPanel;
1670 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1672 public void startLoading(final String fileName)
1674 if (fileLoadingCount == 0)
1676 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1677 "label.loading_file", new Object[] { fileName })));
1682 private JPanel addProgressPanel(String string)
1684 if (progressPanel == null)
1686 progressPanel = new JPanel(new GridLayout(1, 1));
1687 totalProgressCount = 0;
1688 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1690 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1691 JProgressBar progressBar = new JProgressBar();
1692 progressBar.setIndeterminate(true);
1694 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1696 thisprogress.add(progressBar, BorderLayout.CENTER);
1697 progressPanel.add(thisprogress);
1698 ((GridLayout) progressPanel.getLayout())
1699 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1700 ++totalProgressCount;
1701 instance.validate();
1702 return thisprogress;
1705 int totalProgressCount = 0;
1707 private void removeProgressPanel(JPanel progbar)
1709 if (progressPanel != null)
1711 synchronized (progressPanel)
1713 progressPanel.remove(progbar);
1714 GridLayout gl = (GridLayout) progressPanel.getLayout();
1715 gl.setRows(gl.getRows() - 1);
1716 if (--totalProgressCount < 1)
1718 this.getContentPane().remove(progressPanel);
1719 progressPanel = null;
1726 public void stopLoading()
1729 if (fileLoadingCount < 1)
1731 while (fileLoadingPanels.size() > 0)
1733 removeProgressPanel(fileLoadingPanels.remove(0));
1735 fileLoadingPanels.clear();
1736 fileLoadingCount = 0;
1741 public static int getViewCount(String alignmentId)
1743 AlignmentViewport[] aps = getViewports(alignmentId);
1744 return (aps == null) ? 0 : aps.length;
1749 * @param alignmentId
1750 * - if null, all sets are returned
1751 * @return all AlignmentPanels concerning the alignmentId sequence set
1753 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1755 if (Desktop.desktop == null)
1757 // no frames created and in headless mode
1758 // TODO: verify that frames are recoverable when in headless mode
1761 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1762 AlignFrame[] frames = getAlignFrames();
1767 for (AlignFrame af : frames)
1769 for (AlignmentPanel ap : af.alignPanels)
1771 if (alignmentId == null
1772 || alignmentId.equals(ap.av.getSequenceSetId()))
1778 if (aps.size() == 0)
1782 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1787 * get all the viewports on an alignment.
1789 * @param sequenceSetId
1790 * unique alignment id (may be null - all viewports returned in that
1792 * @return all viewports on the alignment bound to sequenceSetId
1794 public static AlignmentViewport[] getViewports(String sequenceSetId)
1796 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1797 if (desktop != null)
1799 AlignFrame[] frames = Desktop.getAlignFrames();
1801 for (AlignFrame afr : frames)
1803 if (sequenceSetId == null
1804 || afr.getViewport().getSequenceSetId()
1805 .equals(sequenceSetId))
1807 if (afr.alignPanels != null)
1809 for (AlignmentPanel ap : afr.alignPanels)
1811 if (sequenceSetId == null
1812 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1820 viewp.add(afr.getViewport());
1824 if (viewp.size() > 0)
1826 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1833 * Explode the views in the given frame into separate AlignFrame
1837 public void explodeViews(AlignFrame af)
1839 int size = af.alignPanels.size();
1845 for (int i = 0; i < size; i++)
1847 AlignmentPanel ap = af.alignPanels.get(i);
1848 AlignFrame newaf = new AlignFrame(ap);
1851 * Restore the view's last exploded frame geometry if known. Multiple
1852 * views from one exploded frame share and restore the same (frame)
1853 * position and size.
1855 Rectangle geometry = ap.av.getExplodedGeometry();
1856 if (geometry != null)
1858 newaf.setBounds(geometry);
1861 ap.av.setGatherViewsHere(false);
1863 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1864 AlignFrame.DEFAULT_HEIGHT);
1867 af.alignPanels.clear();
1868 af.closeMenuItem_actionPerformed(true);
1873 * Gather expanded views (separate AlignFrame's) with the same sequence set
1874 * identifier back in to this frame as additional views, and close the
1875 * expanded views. Note the expanded frames may themselves have multiple
1876 * views. We take the lot.
1880 public void gatherViews(AlignFrame source)
1882 source.viewport.setGatherViewsHere(true);
1883 source.viewport.setExplodedGeometry(source.getBounds());
1884 JInternalFrame[] frames = desktop.getAllFrames();
1885 String viewId = source.viewport.getSequenceSetId();
1887 for (int t = 0; t < frames.length; t++)
1889 if (frames[t] instanceof AlignFrame && frames[t] != source)
1891 AlignFrame af = (AlignFrame) frames[t];
1892 boolean gatherThis = false;
1893 for (int a = 0; a < af.alignPanels.size(); a++)
1895 AlignmentPanel ap = af.alignPanels.get(a);
1896 if (viewId.equals(ap.av.getSequenceSetId()))
1899 ap.av.setGatherViewsHere(false);
1900 ap.av.setExplodedGeometry(af.getBounds());
1901 source.addAlignmentPanel(ap, false);
1907 af.alignPanels.clear();
1908 af.closeMenuItem_actionPerformed(true);
1915 jalview.gui.VamsasApplication v_client = null;
1918 public void vamsasImport_actionPerformed(ActionEvent e)
1920 if (v_client == null)
1922 // Load and try to start a session.
1923 JalviewFileChooser chooser = new JalviewFileChooser(
1924 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1926 chooser.setFileView(new JalviewFileView());
1927 chooser.setDialogTitle(MessageManager
1928 .getString("label.open_saved_vamsas_session"));
1929 chooser.setToolTipText(MessageManager
1930 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1932 int value = chooser.showOpenDialog(this);
1934 if (value == JalviewFileChooser.APPROVE_OPTION)
1936 String fle = chooser.getSelectedFile().toString();
1937 if (!vamsasImport(chooser.getSelectedFile()))
1940 .showInternalMessageDialog(
1942 MessageManager.formatMessage(
1943 "label.couldnt_import_as_vamsas_session",
1944 new Object[] { fle }),
1946 .getString("label.vamsas_document_import_failed"),
1947 JOptionPane.ERROR_MESSAGE);
1953 jalview.bin.Cache.log
1954 .error("Implementation error - load session from a running session is not supported.");
1959 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1962 * @return true if import was a success and a session was started.
1964 public boolean vamsasImport(URL url)
1966 // TODO: create progress bar
1967 if (v_client != null)
1970 jalview.bin.Cache.log
1971 .error("Implementation error - load session from a running session is not supported.");
1977 // copy the URL content to a temporary local file
1978 // TODO: be a bit cleverer here with nio (?!)
1979 File file = File.createTempFile("vdocfromurl", ".vdj");
1980 FileOutputStream fos = new FileOutputStream(file);
1981 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1982 byte[] buffer = new byte[2048];
1984 while ((ln = bis.read(buffer)) > -1)
1986 fos.write(buffer, 0, ln);
1990 v_client = new jalview.gui.VamsasApplication(this, file,
1991 url.toExternalForm());
1992 } catch (Exception ex)
1994 jalview.bin.Cache.log.error(
1995 "Failed to create new vamsas session from contents of URL "
1999 setupVamsasConnectedGui();
2000 v_client.initial_update(); // TODO: thread ?
2001 return v_client.inSession();
2005 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2008 * @return true if import was a success and a session was started.
2010 public boolean vamsasImport(File file)
2012 if (v_client != null)
2015 jalview.bin.Cache.log
2016 .error("Implementation error - load session from a running session is not supported.");
2020 setProgressBar(MessageManager.formatMessage(
2021 "status.importing_vamsas_session_from",
2022 new Object[] { file.getName() }), file.hashCode());
2025 v_client = new jalview.gui.VamsasApplication(this, file, null);
2026 } catch (Exception ex)
2028 setProgressBar(MessageManager.formatMessage(
2029 "status.importing_vamsas_session_from",
2030 new Object[] { file.getName() }), file.hashCode());
2031 jalview.bin.Cache.log.error(
2032 "New vamsas session from existing session file failed:", ex);
2035 setupVamsasConnectedGui();
2036 v_client.initial_update(); // TODO: thread ?
2037 setProgressBar(MessageManager.formatMessage(
2038 "status.importing_vamsas_session_from",
2039 new Object[] { file.getName() }), file.hashCode());
2040 return v_client.inSession();
2043 public boolean joinVamsasSession(String mysesid)
2045 if (v_client != null)
2049 .getString("error.try_join_vamsas_session_another"));
2051 if (mysesid == null)
2054 MessageManager.getString("error.invalid_vamsas_session_id"));
2056 v_client = new VamsasApplication(this, mysesid);
2057 setupVamsasConnectedGui();
2058 v_client.initial_update();
2059 return (v_client.inSession());
2063 public void vamsasStart_actionPerformed(ActionEvent e)
2065 if (v_client == null)
2068 // we just start a default session for moment.
2070 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2071 * getProperty("LAST_DIRECTORY"));
2073 * chooser.setFileView(new JalviewFileView());
2074 * chooser.setDialogTitle("Load Vamsas file");
2075 * chooser.setToolTipText("Import");
2077 * int value = chooser.showOpenDialog(this);
2079 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2080 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2082 v_client = new VamsasApplication(this);
2083 setupVamsasConnectedGui();
2084 v_client.initial_update(); // TODO: thread ?
2088 // store current data in session.
2089 v_client.push_update(); // TODO: thread
2093 protected void setupVamsasConnectedGui()
2095 vamsasStart.setText(MessageManager.getString("label.session_update"));
2096 vamsasSave.setVisible(true);
2097 vamsasStop.setVisible(true);
2098 vamsasImport.setVisible(false); // Document import to existing session is
2099 // not possible for vamsas-client-1.0.
2102 protected void setupVamsasDisconnectedGui()
2104 vamsasSave.setVisible(false);
2105 vamsasStop.setVisible(false);
2106 vamsasImport.setVisible(true);
2107 vamsasStart.setText(MessageManager
2108 .getString("label.new_vamsas_session"));
2112 public void vamsasStop_actionPerformed(ActionEvent e)
2114 if (v_client != null)
2116 v_client.end_session();
2118 setupVamsasDisconnectedGui();
2122 protected void buildVamsasStMenu()
2124 if (v_client == null)
2126 String[] sess = null;
2129 sess = VamsasApplication.getSessionList();
2130 } catch (Exception e)
2132 jalview.bin.Cache.log.warn(
2133 "Problem getting current sessions list.", e);
2138 jalview.bin.Cache.log.debug("Got current sessions list: "
2139 + sess.length + " entries.");
2140 VamsasStMenu.removeAll();
2141 for (int i = 0; i < sess.length; i++)
2143 JMenuItem sessit = new JMenuItem();
2144 sessit.setText(sess[i]);
2145 sessit.setToolTipText(MessageManager.formatMessage(
2146 "label.connect_to_session", new Object[] { sess[i] }));
2147 final Desktop dsktp = this;
2148 final String mysesid = sess[i];
2149 sessit.addActionListener(new ActionListener()
2153 public void actionPerformed(ActionEvent e)
2155 if (dsktp.v_client == null)
2157 Thread rthr = new Thread(new Runnable()
2163 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2164 dsktp.setupVamsasConnectedGui();
2165 dsktp.v_client.initial_update();
2173 VamsasStMenu.add(sessit);
2175 // don't show an empty menu.
2176 VamsasStMenu.setVisible(sess.length > 0);
2181 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2182 VamsasStMenu.removeAll();
2183 VamsasStMenu.setVisible(false);
2188 // Not interested in the content. Just hide ourselves.
2189 VamsasStMenu.setVisible(false);
2194 public void vamsasSave_actionPerformed(ActionEvent e)
2196 if (v_client != null)
2198 JalviewFileChooser chooser = new JalviewFileChooser(
2199 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2200 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2201 new String[] { "Vamsas Document" }, "Vamsas Document");
2203 chooser.setFileView(new JalviewFileView());
2204 chooser.setDialogTitle(MessageManager
2205 .getString("label.save_vamsas_document_archive"));
2207 int value = chooser.showSaveDialog(this);
2209 if (value == JalviewFileChooser.APPROVE_OPTION)
2211 java.io.File choice = chooser.getSelectedFile();
2212 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2213 "label.saving_vamsas_doc",
2214 new Object[] { choice.getName() }));
2215 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2216 String warnmsg = null;
2217 String warnttl = null;
2220 v_client.vclient.storeDocument(choice);
2223 warnttl = "Serious Problem saving Vamsas Document";
2224 warnmsg = ex.toString();
2225 jalview.bin.Cache.log.error("Error Whilst saving document to "
2228 } catch (Exception ex)
2230 warnttl = "Problem saving Vamsas Document.";
2231 warnmsg = ex.toString();
2232 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2236 removeProgressPanel(progpanel);
2237 if (warnmsg != null)
2239 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2241 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2247 JPanel vamUpdate = null;
2250 * hide vamsas user gui bits when a vamsas document event is being handled.
2253 * true to hide gui, false to reveal gui
2255 public void setVamsasUpdate(boolean b)
2257 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2258 + (b ? "in progress" : "finished"));
2260 if (vamUpdate != null)
2262 this.removeProgressPanel(vamUpdate);
2266 vamUpdate = this.addProgressPanel(MessageManager
2267 .getString("label.updating_vamsas_session"));
2269 vamsasStart.setVisible(!b);
2270 vamsasStop.setVisible(!b);
2271 vamsasSave.setVisible(!b);
2274 public JInternalFrame[] getAllFrames()
2276 return desktop.getAllFrames();
2280 * Checks the given url to see if it gives a response indicating that the user
2281 * should be informed of a new questionnaire.
2285 public void checkForQuestionnaire(String url)
2287 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2288 // javax.swing.SwingUtilities.invokeLater(jvq);
2289 new Thread(jvq).start();
2293 * Proxy class for JDesktopPane which optionally displays the current memory
2294 * usage and highlights the desktop area with a red bar if free memory runs
2299 public class MyDesktopPane extends JDesktopPane implements Runnable
2302 private static final float ONE_MB = 1048576f;
2304 boolean showMemoryUsage = false;
2308 java.text.NumberFormat df;
2310 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2313 public MyDesktopPane(boolean showMemoryUsage)
2315 showMemoryUsage(showMemoryUsage);
2318 public void showMemoryUsage(boolean showMemory)
2320 this.showMemoryUsage = showMemory;
2323 Thread worker = new Thread(this);
2328 public boolean isShowMemoryUsage()
2330 return showMemoryUsage;
2336 df = java.text.NumberFormat.getNumberInstance();
2337 df.setMaximumFractionDigits(2);
2338 runtime = Runtime.getRuntime();
2340 while (showMemoryUsage)
2344 maxMemory = runtime.maxMemory() / ONE_MB;
2345 allocatedMemory = runtime.totalMemory() / ONE_MB;
2346 freeMemory = runtime.freeMemory() / ONE_MB;
2347 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2349 percentUsage = (totalFreeMemory / maxMemory) * 100;
2351 // if (percentUsage < 20)
2353 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2355 // instance.set.setBorder(border1);
2358 // sleep after showing usage
2360 } catch (Exception ex)
2362 ex.printStackTrace();
2368 public void paintComponent(Graphics g)
2370 if (showMemoryUsage && g != null && df != null)
2372 if (percentUsage < 20)
2374 g.setColor(Color.red);
2376 FontMetrics fm = g.getFontMetrics();
2379 g.drawString(MessageManager.formatMessage(
2380 "label.memory_stats",
2381 new Object[] { df.format(totalFreeMemory),
2382 df.format(maxMemory), df.format(percentUsage) }), 10,
2383 getHeight() - fm.getHeight());
2390 * fixes stacking order after a modal dialog to ensure windows that should be
2391 * on top actually are
2393 public void relayerWindows()
2398 protected JMenuItem groovyShell;
2401 * Accessor method to quickly get all the AlignmentFrames loaded.
2403 * @return an array of AlignFrame, or null if none found
2405 public static AlignFrame[] getAlignFrames()
2407 if (Jalview.isHeadlessMode())
2409 // Desktop.desktop is null in headless mode
2410 return new AlignFrame[] { Jalview.currentAlignFrame };
2413 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2419 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2421 for (int i = frames.length - 1; i > -1; i--)
2423 if (frames[i] instanceof AlignFrame)
2425 avp.add((AlignFrame) frames[i]);
2427 else if (frames[i] instanceof SplitFrame)
2430 * Also check for a split frame containing an AlignFrame
2432 GSplitFrame sf = (GSplitFrame) frames[i];
2433 if (sf.getTopFrame() instanceof AlignFrame)
2435 avp.add((AlignFrame) sf.getTopFrame());
2437 if (sf.getBottomFrame() instanceof AlignFrame)
2439 avp.add((AlignFrame) sf.getBottomFrame());
2443 if (avp.size() == 0)
2447 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2452 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2456 public GStructureViewer[] getJmols()
2458 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2464 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2466 for (int i = frames.length - 1; i > -1; i--)
2468 if (frames[i] instanceof AppJmol)
2470 GStructureViewer af = (GStructureViewer) frames[i];
2474 if (avp.size() == 0)
2478 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2483 * Add Groovy Support to Jalview
2485 public void groovyShell_actionPerformed()
2489 openGroovyConsole();
2490 } catch (Exception ex)
2492 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2493 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2495 MessageManager.getString("label.couldnt_create_groovy_shell"),
2496 MessageManager.getString("label.groovy_support_failed"),
2497 JOptionPane.ERROR_MESSAGE);
2502 * Open the Groovy console
2504 void openGroovyConsole()
2506 groovyConsole = new groovy.ui.Console();
2509 * bind groovy variable 'Jalview' to the Desktop object
2511 groovyConsole.setVariable("Jalview", this);
2516 groovyConsole.run();
2519 * Allow only one console at a time, so that the AlignFrame menu option
2520 * 'Calculate | Run Groovy script' is unambiguous.
2521 * Disable 'new console', and enable 'Run script', when the console is
2522 * opened, and the reverse when it is closed
2524 Window window = (Window) groovyConsole.getFrame();
2525 window.addWindowListener(new WindowAdapter()
2528 public void windowClosed(WindowEvent e)
2530 enableExecuteGroovy(false);
2535 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2536 * and disable opening a second console
2538 enableExecuteGroovy(true);
2542 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2545 * true if Groovy console is open
2547 public void enableExecuteGroovy(boolean enabled)
2550 * disable opening a second Groovy console
2551 * (or re-enable when the console is closed)
2553 groovyShell.setEnabled(!enabled);
2555 AlignFrame[] alignFrames = getAlignFrames();
2556 if (alignFrames != null)
2558 for (AlignFrame af : alignFrames)
2560 af.setGroovyEnabled(enabled);
2566 * Progress bars managed by the IProgressIndicator method.
2568 private Hashtable<Long, JPanel> progressBars;
2570 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2575 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2578 public void setProgressBar(String message, long id)
2580 if (progressBars == null)
2582 progressBars = new Hashtable<Long, JPanel>();
2583 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2586 if (progressBars.get(new Long(id)) != null)
2588 JPanel panel = progressBars.remove(new Long(id));
2589 if (progressBarHandlers.contains(new Long(id)))
2591 progressBarHandlers.remove(new Long(id));
2593 removeProgressPanel(panel);
2597 progressBars.put(new Long(id), addProgressPanel(message));
2604 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2605 * jalview.gui.IProgressIndicatorHandler)
2608 public void registerHandler(final long id,
2609 final IProgressIndicatorHandler handler)
2611 if (progressBarHandlers == null
2612 || !progressBars.containsKey(new Long(id)))
2616 .getString("error.call_setprogressbar_before_registering_handler"));
2618 progressBarHandlers.put(new Long(id), handler);
2619 final JPanel progressPanel = progressBars.get(new Long(id));
2620 if (handler.canCancel())
2622 JButton cancel = new JButton(
2623 MessageManager.getString("action.cancel"));
2624 final IProgressIndicator us = this;
2625 cancel.addActionListener(new ActionListener()
2629 public void actionPerformed(ActionEvent e)
2631 handler.cancelActivity(id);
2632 us.setProgressBar(MessageManager.formatMessage(
2633 "label.cancelled_params",
2634 new Object[] { ((JLabel) progressPanel.getComponent(0))
2638 progressPanel.add(cancel, BorderLayout.EAST);
2644 * @return true if any progress bars are still active
2647 public boolean operationInProgress()
2649 if (progressBars != null && progressBars.size() > 0)
2657 * This will return the first AlignFrame holding the given viewport instance.
2658 * It will break if there are more than one AlignFrames viewing a particular
2662 * @return alignFrame for viewport
2664 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2666 if (desktop != null)
2668 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2669 for (int panel = 0; aps != null && panel < aps.length; panel++)
2671 if (aps[panel] != null && aps[panel].av == viewport)
2673 return aps[panel].alignFrame;
2680 public VamsasApplication getVamsasApplication()
2687 * flag set if jalview GUI is being operated programmatically
2689 private boolean inBatchMode = false;
2692 * check if jalview GUI is being operated programmatically
2694 * @return inBatchMode
2696 public boolean isInBatchMode()
2702 * set flag if jalview GUI is being operated programmatically
2704 * @param inBatchMode
2706 public void setInBatchMode(boolean inBatchMode)
2708 this.inBatchMode = inBatchMode;
2711 public void startServiceDiscovery()
2713 startServiceDiscovery(false);
2716 public void startServiceDiscovery(boolean blocking)
2718 boolean alive = true;
2719 Thread t0 = null, t1 = null, t2 = null;
2720 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2723 // todo: changesupport handlers need to be transferred
2724 if (discoverer == null)
2726 discoverer = new jalview.ws.jws1.Discoverer();
2727 // register PCS handler for desktop.
2728 discoverer.addPropertyChangeListener(changeSupport);
2730 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2731 // until we phase out completely
2732 (t0 = new Thread(discoverer)).start();
2735 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2737 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2739 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2741 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2747 // TODO: do rest service discovery
2756 } catch (Exception e)
2759 alive = (t1 != null && t1.isAlive())
2760 || (t2 != null && t2.isAlive())
2761 || (t3 != null && t3.isAlive())
2762 || (t0 != null && t0.isAlive());
2768 * called to check if the service discovery process completed successfully.
2772 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2774 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2776 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2777 .getErrorMessages();
2780 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2782 if (serviceChangedDialog == null)
2784 // only run if we aren't already displaying one of these.
2785 addDialogThread(serviceChangedDialog = new Runnable()
2792 * JalviewDialog jd =new JalviewDialog() {
2794 * @Override protected void cancelPressed() { // TODO
2795 * Auto-generated method stub
2797 * }@Override protected void okPressed() { // TODO
2798 * Auto-generated method stub
2800 * }@Override protected void raiseClosed() { // TODO
2801 * Auto-generated method stub
2803 * } }; jd.initDialogFrame(new
2804 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2805 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2806 * + " or mis-configured HTTP proxy settings.<br/>" +
2807 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2809 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2810 * ), true, true, "Web Service Configuration Problem", 450,
2813 * jd.waitForInput();
2819 "<html><table width=\"450\"><tr><td>"
2821 + "</td></tr></table>"
2822 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2823 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2824 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2825 + " Tools->Preferences dialog box to change them.</p></html>"),
2826 "Web Service Configuration Problem",
2827 JOptionPane.DEFAULT_OPTION,
2828 JOptionPane.ERROR_MESSAGE);
2829 serviceChangedDialog = null;
2838 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2845 private Runnable serviceChangedDialog = null;
2848 * start a thread to open a URL in the configured browser. Pops up a warning
2849 * dialog to the user if there is an exception when calling out to the browser
2854 public static void showUrl(final String url)
2856 showUrl(url, Desktop.instance);
2860 * Like showUrl but allows progress handler to be specified
2864 * (null) or object implementing IProgressIndicator
2866 public static void showUrl(final String url,
2867 final IProgressIndicator progress)
2869 new Thread(new Runnable()
2876 if (progress != null)
2878 progress.setProgressBar(MessageManager.formatMessage(
2879 "status.opening_params", new Object[] { url }), this
2882 jalview.util.BrowserLauncher.openURL(url);
2883 } catch (Exception ex)
2885 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2887 .getString("label.web_browser_not_found_unix"),
2888 MessageManager.getString("label.web_browser_not_found"),
2889 JOptionPane.WARNING_MESSAGE);
2891 ex.printStackTrace();
2893 if (progress != null)
2895 progress.setProgressBar(null, this.hashCode());
2901 public static WsParamSetManager wsparamManager = null;
2903 public static ParamManager getUserParameterStore()
2905 if (wsparamManager == null)
2907 wsparamManager = new WsParamSetManager();
2909 return wsparamManager;
2913 * static hyperlink handler proxy method for use by Jalview's internal windows
2917 public static void hyperlinkUpdate(HyperlinkEvent e)
2919 if (e.getEventType() == EventType.ACTIVATED)
2924 url = e.getURL().toString();
2925 Desktop.showUrl(url);
2926 } catch (Exception x)
2930 if (Cache.log != null)
2932 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2936 System.err.println("Couldn't handle string " + url
2940 // ignore any exceptions due to dud links.
2947 * single thread that handles display of dialogs to user.
2949 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2952 * flag indicating if dialogExecutor should try to acquire a permit
2954 private volatile boolean dialogPause = true;
2959 private java.util.concurrent.Semaphore block = new Semaphore(0);
2961 private static groovy.ui.Console groovyConsole;
2964 * add another dialog thread to the queue
2968 public void addDialogThread(final Runnable prompter)
2970 dialogExecutor.submit(new Runnable()
2980 } catch (InterruptedException x)
2985 if (instance == null)
2991 SwingUtilities.invokeAndWait(prompter);
2992 } catch (Exception q)
2994 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3000 public void startDialogQueue()
3002 // set the flag so we don't pause waiting for another permit and semaphore
3003 // the current task to begin
3004 dialogPause = false;
3009 protected void snapShotWindow_actionPerformed(ActionEvent e)
3013 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3014 "View of Desktop", getWidth(), getHeight(), of = new File(
3015 "Jalview_snapshot" + System.currentTimeMillis()
3016 + ".eps"), "View of desktop", null, 0, false);
3019 paintAll(im.getGraphics());
3021 } catch (Exception q)
3023 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3027 Cache.log.info("Successfully written snapshot to file "
3028 + of.getAbsolutePath());
3032 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3033 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3034 * and location last time the view was expanded (if any). However it does not
3035 * remember the split pane divider location - this is set to match the
3036 * 'exploding' frame.
3040 public void explodeViews(SplitFrame sf)
3042 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3043 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3044 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3046 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3048 int viewCount = topPanels.size();
3055 * Processing in reverse order works, forwards order leaves the first panels
3056 * not visible. I don't know why!
3058 for (int i = viewCount - 1; i >= 0; i--)
3061 * Make new top and bottom frames. These take over the respective
3062 * AlignmentPanel objects, including their AlignmentViewports, so the
3063 * cdna/protein relationships between the viewports is carried over to the
3066 * explodedGeometry holds the (x, y) position of the previously exploded
3067 * SplitFrame, and the (width, height) of the AlignFrame component
3069 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3070 AlignFrame newTopFrame = new AlignFrame(topPanel);
3071 newTopFrame.setSize(oldTopFrame.getSize());
3072 newTopFrame.setVisible(true);
3073 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3074 .getExplodedGeometry();
3075 if (geometry != null)
3077 newTopFrame.setSize(geometry.getSize());
3080 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3081 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3082 newBottomFrame.setSize(oldBottomFrame.getSize());
3083 newBottomFrame.setVisible(true);
3084 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3085 .getExplodedGeometry();
3086 if (geometry != null)
3088 newBottomFrame.setSize(geometry.getSize());
3091 topPanel.av.setGatherViewsHere(false);
3092 bottomPanel.av.setGatherViewsHere(false);
3093 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3095 if (geometry != null)
3097 splitFrame.setLocation(geometry.getLocation());
3099 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3103 * Clear references to the panels (now relocated in the new SplitFrames)
3104 * before closing the old SplitFrame.
3107 bottomPanels.clear();
3112 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3113 * back into the given SplitFrame as additional views. Note that the gathered
3114 * frames may themselves have multiple views.
3118 public void gatherViews(GSplitFrame source)
3121 * special handling of explodedGeometry for a view within a SplitFrame: - it
3122 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3123 * height) of the AlignFrame component
3125 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3126 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3127 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3128 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3129 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3130 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3132 myTopFrame.viewport.setGatherViewsHere(true);
3133 myBottomFrame.viewport.setGatherViewsHere(true);
3134 String topViewId = myTopFrame.viewport.getSequenceSetId();
3135 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3137 JInternalFrame[] frames = desktop.getAllFrames();
3138 for (JInternalFrame frame : frames)
3140 if (frame instanceof SplitFrame && frame != source)
3142 SplitFrame sf = (SplitFrame) frame;
3143 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3144 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3145 boolean gatherThis = false;
3146 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3148 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3149 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3150 if (topViewId.equals(topPanel.av.getSequenceSetId())
3151 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3154 topPanel.av.setGatherViewsHere(false);
3155 bottomPanel.av.setGatherViewsHere(false);
3156 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3157 topFrame.getSize()));
3158 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3159 .getLocation(), bottomFrame.getSize()));
3160 myTopFrame.addAlignmentPanel(topPanel, false);
3161 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3167 topFrame.getAlignPanels().clear();
3168 bottomFrame.getAlignPanels().clear();
3175 * The dust settles...give focus to the tab we did this from.
3177 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3180 public static groovy.ui.Console getGroovyConsole()
3182 return groovyConsole;