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 private static AlignFrame currentAlignFrame;
174 public static jalview.ws.jws1.Discoverer discoverer;
176 public static Object[] jalviewClipboard;
178 public static boolean internalCopy = false;
180 static int fileLoadingCount = 0;
182 class MyDesktopManager implements DesktopManager
185 private DesktopManager delegate;
187 public MyDesktopManager(DesktopManager delegate)
189 this.delegate = delegate;
193 public void activateFrame(JInternalFrame f)
197 delegate.activateFrame(f);
198 } catch (NullPointerException npe)
200 Point p = getMousePosition();
201 instance.showPasteMenu(p.x, p.y);
206 public void beginDraggingFrame(JComponent f)
208 delegate.beginDraggingFrame(f);
212 public void beginResizingFrame(JComponent f, int direction)
214 delegate.beginResizingFrame(f, direction);
218 public void closeFrame(JInternalFrame f)
220 delegate.closeFrame(f);
224 public void deactivateFrame(JInternalFrame f)
226 delegate.deactivateFrame(f);
230 public void deiconifyFrame(JInternalFrame f)
232 delegate.deiconifyFrame(f);
236 public void dragFrame(JComponent f, int newX, int newY)
242 delegate.dragFrame(f, newX, newY);
246 public void endDraggingFrame(JComponent f)
248 delegate.endDraggingFrame(f);
252 public void endResizingFrame(JComponent f)
254 delegate.endResizingFrame(f);
258 public void iconifyFrame(JInternalFrame f)
260 delegate.iconifyFrame(f);
264 public void maximizeFrame(JInternalFrame f)
266 delegate.maximizeFrame(f);
270 public void minimizeFrame(JInternalFrame f)
272 delegate.minimizeFrame(f);
276 public void openFrame(JInternalFrame f)
278 delegate.openFrame(f);
282 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
289 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
293 public void setBoundsForFrame(JComponent f, int newX, int newY,
294 int newWidth, int newHeight)
296 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
299 // All other methods, simply delegate
304 * Creates a new Desktop object.
309 * A note to implementors. It is ESSENTIAL that any activities that might
310 * block are spawned off as threads rather than waited for during this
314 doVamsasClientCheck();
316 groovyShell = new JMenuItem();
317 groovyShell.setText(MessageManager.getString("label.groovy_console"));
318 groovyShell.addActionListener(new ActionListener()
321 public void actionPerformed(ActionEvent e)
323 groovyShell_actionPerformed();
326 toolsMenu.add(groovyShell);
327 groovyShell.setVisible(true);
329 doConfigureStructurePrefs();
330 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
331 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
332 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
334 boolean showjconsole = jalview.bin.Cache.getDefault(
335 "SHOW_JAVA_CONSOLE", false);
336 desktop = new MyDesktopPane(selmemusage);
337 if (Platform.isAMac())
339 desktop.setDoubleBuffered(false);
341 showMemusage.setSelected(selmemusage);
342 desktop.setBackground(Color.white);
343 getContentPane().setLayout(new BorderLayout());
344 // alternate config - have scrollbars - see notes in JAL-153
345 // JScrollPane sp = new JScrollPane();
346 // sp.getViewport().setView(desktop);
347 // getContentPane().add(sp, BorderLayout.CENTER);
348 getContentPane().add(desktop, BorderLayout.CENTER);
349 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
351 // This line prevents Windows Look&Feel resizing all new windows to maximum
352 // if previous window was maximised
353 desktop.setDesktopManager(new MyDesktopManager(
354 new DefaultDesktopManager()));
356 Rectangle dims = getLastKnownDimensions("");
363 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
364 setBounds((screenSize.width - 900) / 2,
365 (screenSize.height - 650) / 2, 900, 650);
367 jconsole = new Console(this, showjconsole);
368 // add essential build information
369 jconsole.setHeader("Jalview Version: "
370 + jalview.bin.Cache.getProperty("VERSION") + "\n"
371 + "Jalview Installation: "
372 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
373 + "\n" + "Build Date: "
374 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
375 + "Java version: " + System.getProperty("java.version") + "\n"
376 + System.getProperty("os.arch") + " "
377 + System.getProperty("os.name") + " "
378 + System.getProperty("os.version"));
380 showConsole(showjconsole);
382 showNews.setVisible(false);
384 this.addWindowListener(new WindowAdapter()
387 public void windowClosing(WindowEvent evt)
394 this.addMouseListener(ma = new MouseAdapter()
397 public void mousePressed(MouseEvent evt)
399 if (evt.isPopupTrigger())
401 showPasteMenu(evt.getX(), evt.getY());
405 desktop.addMouseListener(ma);
407 this.addFocusListener(new FocusListener()
411 public void focusLost(FocusEvent e)
413 // TODO Auto-generated method stub
418 public void focusGained(FocusEvent e)
420 Cache.log.debug("Relaying windows after focus gain");
421 // make sure that we sort windows properly after we gain focus
422 instance.relayerWindows();
425 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
426 // Spawn a thread that shows the splashscreen
427 SwingUtilities.invokeLater(new Runnable()
437 // Thread off a new instance of the file chooser - this reduces the time it
438 // takes to open it later on.
439 new Thread(new Runnable()
444 Cache.log.debug("Filechooser init thread started.");
445 new JalviewFileChooser(
446 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
447 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
448 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
449 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
450 Cache.log.debug("Filechooser init thread finished.");
453 // Add the service change listener
454 changeSupport.addJalviewPropertyChangeListener("services",
455 new PropertyChangeListener()
459 public void propertyChange(PropertyChangeEvent evt)
461 Cache.log.debug("Firing service changed event for "
462 + evt.getNewValue());
463 JalviewServicesChanged(evt);
469 public void doConfigureStructurePrefs()
471 // configure services
472 StructureSelectionManager ssm = StructureSelectionManager
473 .getStructureSelectionManager(this);
474 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
476 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
477 Preferences.ADD_TEMPFACT_ANN, true));
478 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
479 Preferences.STRUCT_FROM_PDB, true));
480 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
481 Preferences.USE_RNAVIEW, true));
485 ssm.setAddTempFacAnnot(false);
486 ssm.setProcessSecondaryStructure(false);
487 ssm.setSecStructServices(false);
491 public void checkForNews()
493 final Desktop me = this;
494 // Thread off the news reader, in case there are connection problems.
495 addDialogThread(new Runnable()
500 Cache.log.debug("Starting news thread.");
502 jvnews = new BlogReader(me);
503 showNews.setVisible(true);
504 Cache.log.debug("Completed news thread.");
510 protected void showNews_actionPerformed(ActionEvent e)
512 showNews(showNews.isSelected());
515 void showNews(boolean visible)
518 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
519 showNews.setSelected(visible);
520 if (visible && !jvnews.isVisible())
522 new Thread(new Runnable()
527 long now = System.currentTimeMillis();
528 Desktop.instance.setProgressBar(
529 MessageManager.getString("status.refreshing_news"), now);
530 jvnews.refreshNews();
531 Desktop.instance.setProgressBar(null, now);
540 * recover the last known dimensions for a jalview window
543 * - empty string is desktop, all other windows have unique prefix
544 * @return null or last known dimensions scaled to current geometry (if last
545 * window geom was known)
547 Rectangle getLastKnownDimensions(String windowName)
549 // TODO: lock aspect ratio for scaling desktop Bug #0058199
550 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
551 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
552 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
553 String width = jalview.bin.Cache.getProperty(windowName
555 String height = jalview.bin.Cache.getProperty(windowName
557 if ((x != null) && (y != null) && (width != null) && (height != null))
559 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
560 .parseInt(width), ih = Integer.parseInt(height);
561 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
563 // attempt #1 - try to cope with change in screen geometry - this
564 // version doesn't preserve original jv aspect ratio.
565 // take ratio of current screen size vs original screen size.
566 double sw = ((1f * screenSize.width) / (1f * Integer
567 .parseInt(jalview.bin.Cache
568 .getProperty("SCREENGEOMETRY_WIDTH"))));
569 double sh = ((1f * screenSize.height) / (1f * Integer
570 .parseInt(jalview.bin.Cache
571 .getProperty("SCREENGEOMETRY_HEIGHT"))));
572 // rescale the bounds depending upon the current screen geometry.
573 ix = (int) (ix * sw);
574 iw = (int) (iw * sw);
575 iy = (int) (iy * sh);
576 ih = (int) (ih * sh);
577 while (ix >= screenSize.width)
579 jalview.bin.Cache.log
580 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
581 ix -= screenSize.width;
583 while (iy >= screenSize.height)
585 jalview.bin.Cache.log
586 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
587 iy -= screenSize.height;
589 jalview.bin.Cache.log.debug("Got last known dimensions for "
590 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
593 // return dimensions for new instance
594 return new Rectangle(ix, iy, iw, ih);
599 private void doVamsasClientCheck()
601 if (jalview.bin.Cache.vamsasJarsPresent())
603 setupVamsasDisconnectedGui();
604 VamsasMenu.setVisible(true);
605 final Desktop us = this;
606 VamsasMenu.addMenuListener(new MenuListener()
608 // this listener remembers when the menu was first selected, and
609 // doesn't rebuild the session list until it has been cleared and
611 boolean refresh = true;
614 public void menuCanceled(MenuEvent e)
620 public void menuDeselected(MenuEvent e)
626 public void menuSelected(MenuEvent e)
630 us.buildVamsasStMenu();
635 vamsasStart.setVisible(true);
639 void showPasteMenu(int x, int y)
641 JPopupMenu popup = new JPopupMenu();
642 JMenuItem item = new JMenuItem(
643 MessageManager.getString("label.paste_new_window"));
644 item.addActionListener(new ActionListener()
647 public void actionPerformed(ActionEvent evt)
654 popup.show(this, x, y);
661 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
662 Transferable contents = c.getContents(this);
664 if (contents != null)
666 String file = (String) contents
667 .getTransferData(DataFlavor.stringFlavor);
669 String format = new IdentifyFile().identify(file,
670 FormatAdapter.PASTE);
672 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
675 } catch (Exception ex)
678 .println("Unable to paste alignment from system clipboard:\n"
684 * Adds and opens the given frame to the desktop
695 public static synchronized void addInternalFrame(
696 final JInternalFrame frame, String title, int w, int h)
698 addInternalFrame(frame, title, true, w, h, true);
702 * Add an internal frame to the Jalview desktop
709 * When true, display frame immediately, otherwise, caller must call
710 * setVisible themselves.
716 public static synchronized void addInternalFrame(
717 final JInternalFrame frame, String title, boolean makeVisible,
720 addInternalFrame(frame, title, makeVisible, w, h, true);
724 * Add an internal frame to the Jalview desktop and make it visible
737 public static synchronized void addInternalFrame(
738 final JInternalFrame frame, String title, int w, int h,
741 addInternalFrame(frame, title, true, w, h, resizable);
745 * Add an internal frame to the Jalview desktop
752 * When true, display frame immediately, otherwise, caller must call
753 * setVisible themselves.
761 public static synchronized void addInternalFrame(
762 final JInternalFrame frame, String title, boolean makeVisible,
763 int w, int h, boolean resizable)
766 // TODO: allow callers to determine X and Y position of frame (eg. via
768 // TODO: consider fixing method to update entries in the window submenu with
769 // the current window title
771 frame.setTitle(title);
772 if (frame.getWidth() < 1 || frame.getHeight() < 1)
776 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
777 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
778 // IF JALVIEW IS RUNNING HEADLESS
779 // ///////////////////////////////////////////////
781 || (System.getProperty("java.awt.headless") != null && System
782 .getProperty("java.awt.headless").equals("true")))
789 frame.setVisible(makeVisible);
790 frame.setClosable(true);
791 frame.setResizable(resizable);
792 frame.setMaximizable(resizable);
793 frame.setIconifiable(resizable);
794 if (Platform.isAMac())
796 frame.setIconifiable(false);
797 frame.setFrameIcon(null);
798 // frame.setDesktopIcon(null);
799 frame.setDoubleBuffered(false);
801 if (frame.getX() < 1 && frame.getY() < 1)
803 frame.setLocation(xOffset * openFrameCount, yOffset
804 * ((openFrameCount - 1) % 10) + yOffset);
807 final JMenuItem menuItem = new JMenuItem(title);
808 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
811 public void internalFrameActivated(
812 javax.swing.event.InternalFrameEvent evt)
814 JInternalFrame itf = desktop.getSelectedFrame();
823 public void internalFrameClosed(
824 javax.swing.event.InternalFrameEvent evt)
826 PaintRefresher.RemoveComponent(frame);
828 windowMenu.remove(menuItem);
829 JInternalFrame itf = desktop.getSelectedFrame();
838 menuItem.addActionListener(new ActionListener()
841 public void actionPerformed(ActionEvent e)
845 frame.setSelected(true);
846 frame.setIcon(false);
847 } catch (java.beans.PropertyVetoException ex)
853 menuItem.addMouseListener(new MouseListener()
857 public void mouseReleased(MouseEvent e)
862 public void mousePressed(MouseEvent e)
867 public void mouseExited(MouseEvent e)
871 frame.setSelected(false);
872 } catch (PropertyVetoException e1)
878 public void mouseEntered(MouseEvent e)
882 frame.setSelected(true);
883 } catch (PropertyVetoException e1)
889 public void mouseClicked(MouseEvent e)
895 windowMenu.add(menuItem);
901 frame.setSelected(true);
902 frame.requestFocus();
903 } catch (java.beans.PropertyVetoException ve)
905 } catch (java.lang.ClassCastException cex)
908 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
914 public void lostOwnership(Clipboard clipboard, Transferable contents)
918 Desktop.jalviewClipboard = null;
921 internalCopy = false;
925 public void dragEnter(DropTargetDragEvent evt)
930 public void dragExit(DropTargetEvent evt)
935 public void dragOver(DropTargetDragEvent evt)
940 public void dropActionChanged(DropTargetDragEvent evt)
951 public void drop(DropTargetDropEvent evt)
953 boolean success = true;
954 Transferable t = evt.getTransferable();
955 java.util.List files = null;
956 java.util.List protocols = null;
960 DataFlavor uriListFlavor = new DataFlavor(
961 "text/uri-list;class=java.lang.String");
962 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
964 // Works on Windows and MacOSX
965 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
966 files = (java.util.List) t
967 .getTransferData(DataFlavor.javaFileListFlavor);
969 else if (t.isDataFlavorSupported(uriListFlavor))
971 // This is used by Unix drag system
972 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
973 String data = (String) t.getTransferData(uriListFlavor);
974 files = new java.util.ArrayList(1);
975 protocols = new java.util.ArrayList(1);
976 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
977 data, "\r\n"); st.hasMoreTokens();)
979 String s = st.nextToken();
980 if (s.startsWith("#"))
982 // the line is a comment (as per the RFC 2483)
985 java.net.URI uri = new java.net.URI(s);
986 if (uri.getScheme().toLowerCase().startsWith("http"))
988 protocols.add(FormatAdapter.URL);
989 files.add(uri.toString());
993 // otherwise preserve old behaviour: catch all for file objects
994 java.io.File file = new java.io.File(uri);
995 protocols.add(FormatAdapter.FILE);
996 files.add(file.toString());
1000 } catch (Exception e)
1009 for (int i = 0; i < files.size(); i++)
1011 String file = files.get(i).toString();
1012 String protocol = (protocols == null) ? FormatAdapter.FILE
1013 : (String) protocols.get(i);
1014 String format = null;
1016 if (file.endsWith(".jar"))
1023 format = new IdentifyFile().identify(file, protocol);
1026 new FileLoader().LoadFile(file, protocol, format);
1029 } catch (Exception ex)
1034 evt.dropComplete(success); // need this to ensure input focus is properly
1035 // transfered to any new windows created
1045 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1047 JalviewFileChooser chooser = new JalviewFileChooser(
1048 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1049 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1050 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1051 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1053 chooser.setFileView(new JalviewFileView());
1054 chooser.setDialogTitle(MessageManager
1055 .getString("label.open_local_file"));
1056 chooser.setToolTipText(MessageManager.getString("action.open"));
1058 int value = chooser.showOpenDialog(this);
1060 if (value == JalviewFileChooser.APPROVE_OPTION)
1062 String choice = chooser.getSelectedFile().getPath();
1063 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1064 .getSelectedFile().getParent());
1066 String format = null;
1067 if (chooser.getSelectedFormat() != null
1068 && chooser.getSelectedFormat().equals("Jalview"))
1074 format = new IdentifyFile().identify(choice, FormatAdapter.FILE);
1077 if (viewport != null)
1079 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1084 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1096 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1098 // This construct allows us to have a wider textfield
1100 JLabel label = new JLabel(
1101 MessageManager.getString("label.input_file_url"));
1102 final JComboBox history = new JComboBox();
1104 JPanel panel = new JPanel(new GridLayout(2, 1));
1107 history.setPreferredSize(new Dimension(400, 20));
1108 history.setEditable(true);
1109 history.addItem("http://www.");
1111 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1115 if (historyItems != null)
1117 st = new StringTokenizer(historyItems, "\t");
1119 while (st.hasMoreTokens())
1121 history.addItem(st.nextElement());
1125 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1126 MessageManager.getString("label.input_alignment_from_url"),
1127 JOptionPane.OK_CANCEL_OPTION);
1129 if (reply != JOptionPane.OK_OPTION)
1134 String url = history.getSelectedItem().toString();
1136 if (url.toLowerCase().endsWith(".jar"))
1138 if (viewport != null)
1140 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1145 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1150 String format = new IdentifyFile().identify(url, FormatAdapter.URL);
1152 if (format.equals("URL NOT FOUND"))
1154 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1155 MessageManager.formatMessage("label.couldnt_locate",
1156 new Object[] { url }), MessageManager
1157 .getString("label.url_not_found"),
1158 JOptionPane.WARNING_MESSAGE);
1163 if (viewport != null)
1165 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1169 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1175 * Opens the CutAndPaste window for the user to paste an alignment in to
1178 * - if not null, the pasted alignment is added to the current
1179 * alignment; if null, to a new alignment window
1182 public void inputTextboxMenuItem_actionPerformed(
1183 AlignmentViewPanel viewPanel)
1185 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1186 cap.setForInput(viewPanel);
1187 Desktop.addInternalFrame(cap,
1188 MessageManager.getString("label.cut_paste_alignmen_file"),
1198 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1200 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1201 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1203 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1204 getBounds().y, getWidth(), getHeight()));
1206 if (jconsole != null)
1208 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1209 jconsole.stopConsole();
1213 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1216 if (dialogExecutor != null)
1218 dialogExecutor.shutdownNow();
1220 closeAll_actionPerformed(null);
1224 private void storeLastKnownDimensions(String string, Rectangle jc)
1226 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1227 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1228 + " height:" + jc.height);
1230 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1231 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1232 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1233 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1243 public void aboutMenuItem_actionPerformed(ActionEvent e)
1245 // StringBuffer message = getAboutMessage(false);
1246 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1248 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1249 new Thread(new Runnable()
1254 new SplashScreen(true);
1259 public StringBuffer getAboutMessage(boolean shortv)
1261 StringBuffer message = new StringBuffer();
1262 message.append("<html>");
1265 message.append("<h1><strong>Version: "
1266 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1267 message.append("<strong>Last Updated: <em>"
1268 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1269 + "</em></strong>");
1275 message.append("<strong>Version "
1276 + jalview.bin.Cache.getProperty("VERSION")
1277 + "; last updated: "
1278 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1281 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1284 message.append("<br>...Checking latest version...</br>");
1286 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1287 .equals(jalview.bin.Cache.getProperty("VERSION")))
1289 boolean red = false;
1290 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1291 .indexOf("automated build") == -1)
1294 // Displayed when code version and jnlp version do not match and code
1295 // version is not a development build
1296 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1299 message.append("<br>!! Version "
1300 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1302 + " is available for download from "
1303 + jalview.bin.Cache.getDefault("www.jalview.org",
1304 "http://www.jalview.org") + " !!");
1307 message.append("</div>");
1310 message.append("<br>Authors: "
1312 .getDefault("AUTHORFNAMES",
1313 "The Jalview Authors (See AUTHORS file for current list)")
1314 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1315 + "<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"
1316 + "<br><br>If you use Jalview, please cite:"
1317 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1318 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1319 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1331 public void documentationMenuItem_actionPerformed(ActionEvent e)
1335 Help.showHelpWindow();
1336 } catch (Exception ex)
1342 public void closeAll_actionPerformed(ActionEvent e)
1344 JInternalFrame[] frames = desktop.getAllFrames();
1345 for (int i = 0; i < frames.length; i++)
1349 frames[i].setClosed(true);
1350 } catch (java.beans.PropertyVetoException ex)
1354 System.out.println("ALL CLOSED");
1355 if (v_client != null)
1357 // TODO clear binding to vamsas document objects on close_all
1361 * reset state of singleton objects as appropriate (clear down session state
1362 * when all windows are closed)
1364 StructureSelectionManager ssm = StructureSelectionManager
1365 .getStructureSelectionManager(this);
1373 public void raiseRelated_actionPerformed(ActionEvent e)
1375 reorderAssociatedWindows(false, false);
1379 public void minimizeAssociated_actionPerformed(ActionEvent e)
1381 reorderAssociatedWindows(true, false);
1384 void closeAssociatedWindows()
1386 reorderAssociatedWindows(false, true);
1392 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1396 protected void garbageCollect_actionPerformed(ActionEvent e)
1398 // We simply collect the garbage
1399 jalview.bin.Cache.log.debug("Collecting garbage...");
1401 jalview.bin.Cache.log.debug("Finished garbage collection.");
1408 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1412 protected void showMemusage_actionPerformed(ActionEvent e)
1414 desktop.showMemoryUsage(showMemusage.isSelected());
1421 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1425 protected void showConsole_actionPerformed(ActionEvent e)
1427 showConsole(showConsole.isSelected());
1430 Console jconsole = null;
1433 * control whether the java console is visible or not
1437 void showConsole(boolean selected)
1439 showConsole.setSelected(selected);
1440 // TODO: decide if we should update properties file
1441 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1443 jconsole.setVisible(selected);
1446 void reorderAssociatedWindows(boolean minimize, boolean close)
1448 JInternalFrame[] frames = desktop.getAllFrames();
1449 if (frames == null || frames.length < 1)
1454 AlignmentViewport source = null, target = null;
1455 if (frames[0] instanceof AlignFrame)
1457 source = ((AlignFrame) frames[0]).getCurrentView();
1459 else if (frames[0] instanceof TreePanel)
1461 source = ((TreePanel) frames[0]).getViewPort();
1463 else if (frames[0] instanceof PCAPanel)
1465 source = ((PCAPanel) frames[0]).av;
1467 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1469 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1474 for (int i = 0; i < frames.length; i++)
1477 if (frames[i] == null)
1481 if (frames[i] instanceof AlignFrame)
1483 target = ((AlignFrame) frames[i]).getCurrentView();
1485 else if (frames[i] instanceof TreePanel)
1487 target = ((TreePanel) frames[i]).getViewPort();
1489 else if (frames[i] instanceof PCAPanel)
1491 target = ((PCAPanel) frames[i]).av;
1493 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1495 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1498 if (source == target)
1504 frames[i].setClosed(true);
1508 frames[i].setIcon(minimize);
1511 frames[i].toFront();
1515 } catch (java.beans.PropertyVetoException ex)
1530 protected void preferences_actionPerformed(ActionEvent e)
1542 public void saveState_actionPerformed(ActionEvent e)
1544 JalviewFileChooser chooser = new JalviewFileChooser(
1545 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1546 new String[] { "jvp" }, new String[] { "Jalview Project" },
1549 chooser.setFileView(new JalviewFileView());
1550 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1552 int value = chooser.showSaveDialog(this);
1554 if (value == JalviewFileChooser.APPROVE_OPTION)
1556 final Desktop me = this;
1557 final java.io.File choice = chooser.getSelectedFile();
1558 setProjectFile(choice);
1560 new Thread(new Runnable()
1565 // TODO: refactor to Jalview desktop session controller action.
1566 setProgressBar(MessageManager.formatMessage(
1567 "label.saving_jalview_project",
1568 new Object[] { choice.getName() }), choice.hashCode());
1569 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1570 choice.getParent());
1571 // TODO catch and handle errors for savestate
1572 // TODO prevent user from messing with the Desktop whilst we're saving
1575 new Jalview2XML().saveState(choice);
1576 } catch (OutOfMemoryError oom)
1578 new OOMWarning("Whilst saving current state to "
1579 + choice.getName(), oom);
1580 } catch (Exception ex)
1583 "Problems whilst trying to save to " + choice.getName(),
1585 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1586 "label.error_whilst_saving_current_state_to",
1587 new Object[] { choice.getName() }), MessageManager
1588 .getString("label.couldnt_save_project"),
1589 JOptionPane.WARNING_MESSAGE);
1591 setProgressBar(null, choice.hashCode());
1597 private void setProjectFile(File choice)
1599 this.projectFile = choice;
1602 public File getProjectFile()
1604 return this.projectFile;
1614 public void loadState_actionPerformed(ActionEvent e)
1616 JalviewFileChooser chooser = new JalviewFileChooser(
1617 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1618 "jvp", "jar" }, new String[] { "Jalview Project",
1619 "Jalview Project (old)" }, "Jalview Project");
1620 chooser.setFileView(new JalviewFileView());
1621 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1623 int value = chooser.showOpenDialog(this);
1625 if (value == JalviewFileChooser.APPROVE_OPTION)
1627 final File selectedFile = chooser.getSelectedFile();
1628 setProjectFile(selectedFile);
1629 final String choice = selectedFile.getAbsolutePath();
1630 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1631 selectedFile.getParent());
1632 new Thread(new Runnable()
1638 MessageManager.formatMessage(
1639 "label.loading_jalview_project",
1640 new Object[] { choice }), choice.hashCode());
1643 new Jalview2XML().loadJalviewAlign(choice);
1644 } catch (OutOfMemoryError oom)
1646 new OOMWarning("Whilst loading project from " + choice, oom);
1647 } catch (Exception ex)
1649 Cache.log.error("Problems whilst loading project from "
1651 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1653 "label.error_whilst_loading_project_from",
1654 new Object[] { choice }), MessageManager
1655 .getString("label.couldnt_load_project"),
1656 JOptionPane.WARNING_MESSAGE);
1658 setProgressBar(null, choice.hashCode());
1665 public void inputSequence_actionPerformed(ActionEvent e)
1667 new SequenceFetcher(this);
1670 JPanel progressPanel;
1672 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1674 public void startLoading(final String fileName)
1676 if (fileLoadingCount == 0)
1678 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1679 "label.loading_file", new Object[] { fileName })));
1684 private JPanel addProgressPanel(String string)
1686 if (progressPanel == null)
1688 progressPanel = new JPanel(new GridLayout(1, 1));
1689 totalProgressCount = 0;
1690 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1692 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1693 JProgressBar progressBar = new JProgressBar();
1694 progressBar.setIndeterminate(true);
1696 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1698 thisprogress.add(progressBar, BorderLayout.CENTER);
1699 progressPanel.add(thisprogress);
1700 ((GridLayout) progressPanel.getLayout())
1701 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1702 ++totalProgressCount;
1703 instance.validate();
1704 return thisprogress;
1707 int totalProgressCount = 0;
1709 private void removeProgressPanel(JPanel progbar)
1711 if (progressPanel != null)
1713 synchronized (progressPanel)
1715 progressPanel.remove(progbar);
1716 GridLayout gl = (GridLayout) progressPanel.getLayout();
1717 gl.setRows(gl.getRows() - 1);
1718 if (--totalProgressCount < 1)
1720 this.getContentPane().remove(progressPanel);
1721 progressPanel = null;
1728 public void stopLoading()
1731 if (fileLoadingCount < 1)
1733 while (fileLoadingPanels.size() > 0)
1735 removeProgressPanel(fileLoadingPanels.remove(0));
1737 fileLoadingPanels.clear();
1738 fileLoadingCount = 0;
1743 public static int getViewCount(String alignmentId)
1745 AlignmentViewport[] aps = getViewports(alignmentId);
1746 return (aps == null) ? 0 : aps.length;
1751 * @param alignmentId
1752 * - if null, all sets are returned
1753 * @return all AlignmentPanels concerning the alignmentId sequence set
1755 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1757 if (Desktop.desktop == null)
1759 // no frames created and in headless mode
1760 // TODO: verify that frames are recoverable when in headless mode
1763 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1764 AlignFrame[] frames = getAlignFrames();
1769 for (AlignFrame af : frames)
1771 for (AlignmentPanel ap : af.alignPanels)
1773 if (alignmentId == null
1774 || alignmentId.equals(ap.av.getSequenceSetId()))
1780 if (aps.size() == 0)
1784 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1789 * get all the viewports on an alignment.
1791 * @param sequenceSetId
1792 * unique alignment id (may be null - all viewports returned in that
1794 * @return all viewports on the alignment bound to sequenceSetId
1796 public static AlignmentViewport[] getViewports(String sequenceSetId)
1798 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1799 if (desktop != null)
1801 AlignFrame[] frames = Desktop.getAlignFrames();
1803 for (AlignFrame afr : frames)
1805 if (sequenceSetId == null
1806 || afr.getViewport().getSequenceSetId()
1807 .equals(sequenceSetId))
1809 if (afr.alignPanels != null)
1811 for (AlignmentPanel ap : afr.alignPanels)
1813 if (sequenceSetId == null
1814 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1822 viewp.add(afr.getViewport());
1826 if (viewp.size() > 0)
1828 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1835 * Explode the views in the given frame into separate AlignFrame
1839 public void explodeViews(AlignFrame af)
1841 int size = af.alignPanels.size();
1847 for (int i = 0; i < size; i++)
1849 AlignmentPanel ap = af.alignPanels.get(i);
1850 AlignFrame newaf = new AlignFrame(ap);
1853 * Restore the view's last exploded frame geometry if known. Multiple
1854 * views from one exploded frame share and restore the same (frame)
1855 * position and size.
1857 Rectangle geometry = ap.av.getExplodedGeometry();
1858 if (geometry != null)
1860 newaf.setBounds(geometry);
1863 ap.av.setGatherViewsHere(false);
1865 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1866 AlignFrame.DEFAULT_HEIGHT);
1869 af.alignPanels.clear();
1870 af.closeMenuItem_actionPerformed(true);
1875 * Gather expanded views (separate AlignFrame's) with the same sequence set
1876 * identifier back in to this frame as additional views, and close the
1877 * expanded views. Note the expanded frames may themselves have multiple
1878 * views. We take the lot.
1882 public void gatherViews(AlignFrame source)
1884 source.viewport.setGatherViewsHere(true);
1885 source.viewport.setExplodedGeometry(source.getBounds());
1886 JInternalFrame[] frames = desktop.getAllFrames();
1887 String viewId = source.viewport.getSequenceSetId();
1889 for (int t = 0; t < frames.length; t++)
1891 if (frames[t] instanceof AlignFrame && frames[t] != source)
1893 AlignFrame af = (AlignFrame) frames[t];
1894 boolean gatherThis = false;
1895 for (int a = 0; a < af.alignPanels.size(); a++)
1897 AlignmentPanel ap = af.alignPanels.get(a);
1898 if (viewId.equals(ap.av.getSequenceSetId()))
1901 ap.av.setGatherViewsHere(false);
1902 ap.av.setExplodedGeometry(af.getBounds());
1903 source.addAlignmentPanel(ap, false);
1909 af.alignPanels.clear();
1910 af.closeMenuItem_actionPerformed(true);
1917 jalview.gui.VamsasApplication v_client = null;
1920 public void vamsasImport_actionPerformed(ActionEvent e)
1922 if (v_client == null)
1924 // Load and try to start a session.
1925 JalviewFileChooser chooser = new JalviewFileChooser(
1926 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1928 chooser.setFileView(new JalviewFileView());
1929 chooser.setDialogTitle(MessageManager
1930 .getString("label.open_saved_vamsas_session"));
1931 chooser.setToolTipText(MessageManager
1932 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1934 int value = chooser.showOpenDialog(this);
1936 if (value == JalviewFileChooser.APPROVE_OPTION)
1938 String fle = chooser.getSelectedFile().toString();
1939 if (!vamsasImport(chooser.getSelectedFile()))
1942 .showInternalMessageDialog(
1944 MessageManager.formatMessage(
1945 "label.couldnt_import_as_vamsas_session",
1946 new Object[] { fle }),
1948 .getString("label.vamsas_document_import_failed"),
1949 JOptionPane.ERROR_MESSAGE);
1955 jalview.bin.Cache.log
1956 .error("Implementation error - load session from a running session is not supported.");
1961 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1964 * @return true if import was a success and a session was started.
1966 public boolean vamsasImport(URL url)
1968 // TODO: create progress bar
1969 if (v_client != null)
1972 jalview.bin.Cache.log
1973 .error("Implementation error - load session from a running session is not supported.");
1979 // copy the URL content to a temporary local file
1980 // TODO: be a bit cleverer here with nio (?!)
1981 File file = File.createTempFile("vdocfromurl", ".vdj");
1982 FileOutputStream fos = new FileOutputStream(file);
1983 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1984 byte[] buffer = new byte[2048];
1986 while ((ln = bis.read(buffer)) > -1)
1988 fos.write(buffer, 0, ln);
1992 v_client = new jalview.gui.VamsasApplication(this, file,
1993 url.toExternalForm());
1994 } catch (Exception ex)
1996 jalview.bin.Cache.log.error(
1997 "Failed to create new vamsas session from contents of URL "
2001 setupVamsasConnectedGui();
2002 v_client.initial_update(); // TODO: thread ?
2003 return v_client.inSession();
2007 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2010 * @return true if import was a success and a session was started.
2012 public boolean vamsasImport(File file)
2014 if (v_client != null)
2017 jalview.bin.Cache.log
2018 .error("Implementation error - load session from a running session is not supported.");
2022 setProgressBar(MessageManager.formatMessage(
2023 "status.importing_vamsas_session_from",
2024 new Object[] { file.getName() }), file.hashCode());
2027 v_client = new jalview.gui.VamsasApplication(this, file, null);
2028 } catch (Exception ex)
2030 setProgressBar(MessageManager.formatMessage(
2031 "status.importing_vamsas_session_from",
2032 new Object[] { file.getName() }), file.hashCode());
2033 jalview.bin.Cache.log.error(
2034 "New vamsas session from existing session file failed:", ex);
2037 setupVamsasConnectedGui();
2038 v_client.initial_update(); // TODO: thread ?
2039 setProgressBar(MessageManager.formatMessage(
2040 "status.importing_vamsas_session_from",
2041 new Object[] { file.getName() }), file.hashCode());
2042 return v_client.inSession();
2045 public boolean joinVamsasSession(String mysesid)
2047 if (v_client != null)
2051 .getString("error.try_join_vamsas_session_another"));
2053 if (mysesid == null)
2056 MessageManager.getString("error.invalid_vamsas_session_id"));
2058 v_client = new VamsasApplication(this, mysesid);
2059 setupVamsasConnectedGui();
2060 v_client.initial_update();
2061 return (v_client.inSession());
2065 public void vamsasStart_actionPerformed(ActionEvent e)
2067 if (v_client == null)
2070 // we just start a default session for moment.
2072 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2073 * getProperty("LAST_DIRECTORY"));
2075 * chooser.setFileView(new JalviewFileView());
2076 * chooser.setDialogTitle("Load Vamsas file");
2077 * chooser.setToolTipText("Import");
2079 * int value = chooser.showOpenDialog(this);
2081 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2082 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2084 v_client = new VamsasApplication(this);
2085 setupVamsasConnectedGui();
2086 v_client.initial_update(); // TODO: thread ?
2090 // store current data in session.
2091 v_client.push_update(); // TODO: thread
2095 protected void setupVamsasConnectedGui()
2097 vamsasStart.setText(MessageManager.getString("label.session_update"));
2098 vamsasSave.setVisible(true);
2099 vamsasStop.setVisible(true);
2100 vamsasImport.setVisible(false); // Document import to existing session is
2101 // not possible for vamsas-client-1.0.
2104 protected void setupVamsasDisconnectedGui()
2106 vamsasSave.setVisible(false);
2107 vamsasStop.setVisible(false);
2108 vamsasImport.setVisible(true);
2109 vamsasStart.setText(MessageManager
2110 .getString("label.new_vamsas_session"));
2114 public void vamsasStop_actionPerformed(ActionEvent e)
2116 if (v_client != null)
2118 v_client.end_session();
2120 setupVamsasDisconnectedGui();
2124 protected void buildVamsasStMenu()
2126 if (v_client == null)
2128 String[] sess = null;
2131 sess = VamsasApplication.getSessionList();
2132 } catch (Exception e)
2134 jalview.bin.Cache.log.warn(
2135 "Problem getting current sessions list.", e);
2140 jalview.bin.Cache.log.debug("Got current sessions list: "
2141 + sess.length + " entries.");
2142 VamsasStMenu.removeAll();
2143 for (int i = 0; i < sess.length; i++)
2145 JMenuItem sessit = new JMenuItem();
2146 sessit.setText(sess[i]);
2147 sessit.setToolTipText(MessageManager.formatMessage(
2148 "label.connect_to_session", new Object[] { sess[i] }));
2149 final Desktop dsktp = this;
2150 final String mysesid = sess[i];
2151 sessit.addActionListener(new ActionListener()
2155 public void actionPerformed(ActionEvent e)
2157 if (dsktp.v_client == null)
2159 Thread rthr = new Thread(new Runnable()
2165 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2166 dsktp.setupVamsasConnectedGui();
2167 dsktp.v_client.initial_update();
2175 VamsasStMenu.add(sessit);
2177 // don't show an empty menu.
2178 VamsasStMenu.setVisible(sess.length > 0);
2183 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2184 VamsasStMenu.removeAll();
2185 VamsasStMenu.setVisible(false);
2190 // Not interested in the content. Just hide ourselves.
2191 VamsasStMenu.setVisible(false);
2196 public void vamsasSave_actionPerformed(ActionEvent e)
2198 if (v_client != null)
2200 JalviewFileChooser chooser = new JalviewFileChooser(
2201 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2202 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2203 new String[] { "Vamsas Document" }, "Vamsas Document");
2205 chooser.setFileView(new JalviewFileView());
2206 chooser.setDialogTitle(MessageManager
2207 .getString("label.save_vamsas_document_archive"));
2209 int value = chooser.showSaveDialog(this);
2211 if (value == JalviewFileChooser.APPROVE_OPTION)
2213 java.io.File choice = chooser.getSelectedFile();
2214 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2215 "label.saving_vamsas_doc",
2216 new Object[] { choice.getName() }));
2217 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2218 String warnmsg = null;
2219 String warnttl = null;
2222 v_client.vclient.storeDocument(choice);
2225 warnttl = "Serious Problem saving Vamsas Document";
2226 warnmsg = ex.toString();
2227 jalview.bin.Cache.log.error("Error Whilst saving document to "
2230 } catch (Exception ex)
2232 warnttl = "Problem saving Vamsas Document.";
2233 warnmsg = ex.toString();
2234 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2238 removeProgressPanel(progpanel);
2239 if (warnmsg != null)
2241 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2243 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2249 JPanel vamUpdate = null;
2252 * hide vamsas user gui bits when a vamsas document event is being handled.
2255 * true to hide gui, false to reveal gui
2257 public void setVamsasUpdate(boolean b)
2259 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2260 + (b ? "in progress" : "finished"));
2262 if (vamUpdate != null)
2264 this.removeProgressPanel(vamUpdate);
2268 vamUpdate = this.addProgressPanel(MessageManager
2269 .getString("label.updating_vamsas_session"));
2271 vamsasStart.setVisible(!b);
2272 vamsasStop.setVisible(!b);
2273 vamsasSave.setVisible(!b);
2276 public JInternalFrame[] getAllFrames()
2278 return desktop.getAllFrames();
2282 * Checks the given url to see if it gives a response indicating that the user
2283 * should be informed of a new questionnaire.
2287 public void checkForQuestionnaire(String url)
2289 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2290 // javax.swing.SwingUtilities.invokeLater(jvq);
2291 new Thread(jvq).start();
2295 * Proxy class for JDesktopPane which optionally displays the current memory
2296 * usage and highlights the desktop area with a red bar if free memory runs
2301 public class MyDesktopPane extends JDesktopPane implements Runnable
2304 private static final float ONE_MB = 1048576f;
2306 boolean showMemoryUsage = false;
2310 java.text.NumberFormat df;
2312 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2315 public MyDesktopPane(boolean showMemoryUsage)
2317 showMemoryUsage(showMemoryUsage);
2320 public void showMemoryUsage(boolean showMemory)
2322 this.showMemoryUsage = showMemory;
2325 Thread worker = new Thread(this);
2330 public boolean isShowMemoryUsage()
2332 return showMemoryUsage;
2338 df = java.text.NumberFormat.getNumberInstance();
2339 df.setMaximumFractionDigits(2);
2340 runtime = Runtime.getRuntime();
2342 while (showMemoryUsage)
2346 maxMemory = runtime.maxMemory() / ONE_MB;
2347 allocatedMemory = runtime.totalMemory() / ONE_MB;
2348 freeMemory = runtime.freeMemory() / ONE_MB;
2349 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2351 percentUsage = (totalFreeMemory / maxMemory) * 100;
2353 // if (percentUsage < 20)
2355 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2357 // instance.set.setBorder(border1);
2360 // sleep after showing usage
2362 } catch (Exception ex)
2364 ex.printStackTrace();
2370 public void paintComponent(Graphics g)
2372 if (showMemoryUsage && g != null && df != null)
2374 if (percentUsage < 20)
2376 g.setColor(Color.red);
2378 FontMetrics fm = g.getFontMetrics();
2381 g.drawString(MessageManager.formatMessage(
2382 "label.memory_stats",
2383 new Object[] { df.format(totalFreeMemory),
2384 df.format(maxMemory), df.format(percentUsage) }), 10,
2385 getHeight() - fm.getHeight());
2392 * fixes stacking order after a modal dialog to ensure windows that should be
2393 * on top actually are
2395 public void relayerWindows()
2400 protected JMenuItem groovyShell;
2403 * Accessor method to quickly get all the AlignmentFrames loaded.
2405 * @return an array of AlignFrame, or null if none found
2407 public static AlignFrame[] getAlignFrames()
2409 if (Jalview.isHeadlessMode())
2411 // Desktop.desktop is null in headless mode
2412 return new AlignFrame[] { currentAlignFrame };
2415 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2421 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2423 for (int i = frames.length - 1; i > -1; i--)
2425 if (frames[i] instanceof AlignFrame)
2427 avp.add((AlignFrame) frames[i]);
2429 else if (frames[i] instanceof SplitFrame)
2432 * Also check for a split frame containing an AlignFrame
2434 GSplitFrame sf = (GSplitFrame) frames[i];
2435 if (sf.getTopFrame() instanceof AlignFrame)
2437 avp.add((AlignFrame) sf.getTopFrame());
2439 if (sf.getBottomFrame() instanceof AlignFrame)
2441 avp.add((AlignFrame) sf.getBottomFrame());
2445 if (avp.size() == 0)
2449 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2454 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2458 public GStructureViewer[] getJmols()
2460 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2466 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2468 for (int i = frames.length - 1; i > -1; i--)
2470 if (frames[i] instanceof AppJmol)
2472 GStructureViewer af = (GStructureViewer) frames[i];
2476 if (avp.size() == 0)
2480 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2485 * Add Groovy Support to Jalview
2487 public void groovyShell_actionPerformed()
2491 openGroovyConsole();
2492 } catch (Exception ex)
2494 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2495 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2497 MessageManager.getString("label.couldnt_create_groovy_shell"),
2498 MessageManager.getString("label.groovy_support_failed"),
2499 JOptionPane.ERROR_MESSAGE);
2504 * Open the Groovy console
2506 void openGroovyConsole()
2508 groovyConsole = new groovy.ui.Console();
2511 * bind groovy variable 'Jalview' to the Desktop object
2513 groovyConsole.setVariable("Jalview", this);
2518 groovyConsole.run();
2521 * Allow only one console at a time, so that the AlignFrame menu option
2522 * 'Calculate | Run Groovy script' is unambiguous.
2523 * Disable 'new console', and enable 'Run script', when the console is
2524 * opened, and the reverse when it is closed
2526 Window window = (Window) groovyConsole.getFrame();
2527 window.addWindowListener(new WindowAdapter()
2530 public void windowClosed(WindowEvent e)
2532 groovyShell.setEnabled(true);
2533 enableExecuteGroovy(false);
2538 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2539 * and disable opening a second console
2541 groovyShell.setEnabled(false);
2542 enableExecuteGroovy(true);
2546 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2550 public void enableExecuteGroovy(boolean enabled)
2552 AlignFrame[] alignFrames = getAlignFrames();
2553 if (alignFrames != null)
2555 for (AlignFrame af : alignFrames)
2557 af.setGroovyEnabled(enabled);
2563 * Progress bars managed by the IProgressIndicator method.
2565 private Hashtable<Long, JPanel> progressBars;
2567 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2572 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2575 public void setProgressBar(String message, long id)
2577 if (progressBars == null)
2579 progressBars = new Hashtable<Long, JPanel>();
2580 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2583 if (progressBars.get(new Long(id)) != null)
2585 JPanel panel = progressBars.remove(new Long(id));
2586 if (progressBarHandlers.contains(new Long(id)))
2588 progressBarHandlers.remove(new Long(id));
2590 removeProgressPanel(panel);
2594 progressBars.put(new Long(id), addProgressPanel(message));
2601 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2602 * jalview.gui.IProgressIndicatorHandler)
2605 public void registerHandler(final long id,
2606 final IProgressIndicatorHandler handler)
2608 if (progressBarHandlers == null
2609 || !progressBars.containsKey(new Long(id)))
2613 .getString("error.call_setprogressbar_before_registering_handler"));
2615 progressBarHandlers.put(new Long(id), handler);
2616 final JPanel progressPanel = progressBars.get(new Long(id));
2617 if (handler.canCancel())
2619 JButton cancel = new JButton(
2620 MessageManager.getString("action.cancel"));
2621 final IProgressIndicator us = this;
2622 cancel.addActionListener(new ActionListener()
2626 public void actionPerformed(ActionEvent e)
2628 handler.cancelActivity(id);
2629 us.setProgressBar(MessageManager.formatMessage(
2630 "label.cancelled_params",
2631 new Object[] { ((JLabel) progressPanel.getComponent(0))
2635 progressPanel.add(cancel, BorderLayout.EAST);
2641 * @return true if any progress bars are still active
2644 public boolean operationInProgress()
2646 if (progressBars != null && progressBars.size() > 0)
2654 * This will return the first AlignFrame holding the given viewport instance.
2655 * It will break if there are more than one AlignFrames viewing a particular
2659 * @return alignFrame for viewport
2661 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2663 if (desktop != null)
2665 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2666 for (int panel = 0; aps != null && panel < aps.length; panel++)
2668 if (aps[panel] != null && aps[panel].av == viewport)
2670 return aps[panel].alignFrame;
2677 public VamsasApplication getVamsasApplication()
2684 * flag set if jalview GUI is being operated programmatically
2686 private boolean inBatchMode = false;
2689 * check if jalview GUI is being operated programmatically
2691 * @return inBatchMode
2693 public boolean isInBatchMode()
2699 * set flag if jalview GUI is being operated programmatically
2701 * @param inBatchMode
2703 public void setInBatchMode(boolean inBatchMode)
2705 this.inBatchMode = inBatchMode;
2708 public void startServiceDiscovery()
2710 startServiceDiscovery(false);
2713 public void startServiceDiscovery(boolean blocking)
2715 boolean alive = true;
2716 Thread t0 = null, t1 = null, t2 = null;
2717 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2720 // todo: changesupport handlers need to be transferred
2721 if (discoverer == null)
2723 discoverer = new jalview.ws.jws1.Discoverer();
2724 // register PCS handler for desktop.
2725 discoverer.addPropertyChangeListener(changeSupport);
2727 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2728 // until we phase out completely
2729 (t0 = new Thread(discoverer)).start();
2732 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2734 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2736 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2738 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2744 // TODO: do rest service discovery
2753 } catch (Exception e)
2756 alive = (t1 != null && t1.isAlive())
2757 || (t2 != null && t2.isAlive())
2758 || (t3 != null && t3.isAlive())
2759 || (t0 != null && t0.isAlive());
2765 * called to check if the service discovery process completed successfully.
2769 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2771 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2773 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2774 .getErrorMessages();
2777 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2779 if (serviceChangedDialog == null)
2781 // only run if we aren't already displaying one of these.
2782 addDialogThread(serviceChangedDialog = new Runnable()
2789 * JalviewDialog jd =new JalviewDialog() {
2791 * @Override protected void cancelPressed() { // TODO
2792 * Auto-generated method stub
2794 * }@Override protected void okPressed() { // TODO
2795 * Auto-generated method stub
2797 * }@Override protected void raiseClosed() { // TODO
2798 * Auto-generated method stub
2800 * } }; jd.initDialogFrame(new
2801 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2802 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2803 * + " or mis-configured HTTP proxy settings.<br/>" +
2804 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2806 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2807 * ), true, true, "Web Service Configuration Problem", 450,
2810 * jd.waitForInput();
2816 "<html><table width=\"450\"><tr><td>"
2818 + "</td></tr></table>"
2819 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2820 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2821 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2822 + " Tools->Preferences dialog box to change them.</p></html>"),
2823 "Web Service Configuration Problem",
2824 JOptionPane.DEFAULT_OPTION,
2825 JOptionPane.ERROR_MESSAGE);
2826 serviceChangedDialog = null;
2835 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2842 private Runnable serviceChangedDialog = null;
2845 * start a thread to open a URL in the configured browser. Pops up a warning
2846 * dialog to the user if there is an exception when calling out to the browser
2851 public static void showUrl(final String url)
2853 showUrl(url, Desktop.instance);
2857 * Like showUrl but allows progress handler to be specified
2861 * (null) or object implementing IProgressIndicator
2863 public static void showUrl(final String url,
2864 final IProgressIndicator progress)
2866 new Thread(new Runnable()
2873 if (progress != null)
2875 progress.setProgressBar(MessageManager.formatMessage(
2876 "status.opening_params", new Object[] { url }), this
2879 jalview.util.BrowserLauncher.openURL(url);
2880 } catch (Exception ex)
2882 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2884 .getString("label.web_browser_not_found_unix"),
2885 MessageManager.getString("label.web_browser_not_found"),
2886 JOptionPane.WARNING_MESSAGE);
2888 ex.printStackTrace();
2890 if (progress != null)
2892 progress.setProgressBar(null, this.hashCode());
2898 public static WsParamSetManager wsparamManager = null;
2900 public static ParamManager getUserParameterStore()
2902 if (wsparamManager == null)
2904 wsparamManager = new WsParamSetManager();
2906 return wsparamManager;
2910 * static hyperlink handler proxy method for use by Jalview's internal windows
2914 public static void hyperlinkUpdate(HyperlinkEvent e)
2916 if (e.getEventType() == EventType.ACTIVATED)
2921 url = e.getURL().toString();
2922 Desktop.showUrl(url);
2923 } catch (Exception x)
2927 if (Cache.log != null)
2929 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2933 System.err.println("Couldn't handle string " + url
2937 // ignore any exceptions due to dud links.
2944 * single thread that handles display of dialogs to user.
2946 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2949 * flag indicating if dialogExecutor should try to acquire a permit
2951 private volatile boolean dialogPause = true;
2956 private java.util.concurrent.Semaphore block = new Semaphore(0);
2958 private static groovy.ui.Console groovyConsole;
2961 * add another dialog thread to the queue
2965 public void addDialogThread(final Runnable prompter)
2967 dialogExecutor.submit(new Runnable()
2977 } catch (InterruptedException x)
2982 if (instance == null)
2988 SwingUtilities.invokeAndWait(prompter);
2989 } catch (Exception q)
2991 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2997 public void startDialogQueue()
2999 // set the flag so we don't pause waiting for another permit and semaphore
3000 // the current task to begin
3001 dialogPause = false;
3006 protected void snapShotWindow_actionPerformed(ActionEvent e)
3010 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3011 "View of Desktop", getWidth(), getHeight(), of = new File(
3012 "Jalview_snapshot" + System.currentTimeMillis()
3013 + ".eps"), "View of desktop", null, 0, false);
3016 paintAll(im.getGraphics());
3018 } catch (Exception q)
3020 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3024 Cache.log.info("Successfully written snapshot to file "
3025 + of.getAbsolutePath());
3029 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3030 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3031 * and location last time the view was expanded (if any). However it does not
3032 * remember the split pane divider location - this is set to match the
3033 * 'exploding' frame.
3037 public void explodeViews(SplitFrame sf)
3039 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3040 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3041 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3043 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3045 int viewCount = topPanels.size();
3052 * Processing in reverse order works, forwards order leaves the first panels
3053 * not visible. I don't know why!
3055 for (int i = viewCount - 1; i >= 0; i--)
3058 * Make new top and bottom frames. These take over the respective
3059 * AlignmentPanel objects, including their AlignmentViewports, so the
3060 * cdna/protein relationships between the viewports is carried over to the
3063 * explodedGeometry holds the (x, y) position of the previously exploded
3064 * SplitFrame, and the (width, height) of the AlignFrame component
3066 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3067 AlignFrame newTopFrame = new AlignFrame(topPanel);
3068 newTopFrame.setSize(oldTopFrame.getSize());
3069 newTopFrame.setVisible(true);
3070 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3071 .getExplodedGeometry();
3072 if (geometry != null)
3074 newTopFrame.setSize(geometry.getSize());
3077 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3078 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3079 newBottomFrame.setSize(oldBottomFrame.getSize());
3080 newBottomFrame.setVisible(true);
3081 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3082 .getExplodedGeometry();
3083 if (geometry != null)
3085 newBottomFrame.setSize(geometry.getSize());
3088 topPanel.av.setGatherViewsHere(false);
3089 bottomPanel.av.setGatherViewsHere(false);
3090 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3092 if (geometry != null)
3094 splitFrame.setLocation(geometry.getLocation());
3096 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3100 * Clear references to the panels (now relocated in the new SplitFrames)
3101 * before closing the old SplitFrame.
3104 bottomPanels.clear();
3109 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3110 * back into the given SplitFrame as additional views. Note that the gathered
3111 * frames may themselves have multiple views.
3115 public void gatherViews(GSplitFrame source)
3118 * special handling of explodedGeometry for a view within a SplitFrame: - it
3119 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3120 * height) of the AlignFrame component
3122 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3123 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3124 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3125 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3126 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3127 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3129 myTopFrame.viewport.setGatherViewsHere(true);
3130 myBottomFrame.viewport.setGatherViewsHere(true);
3131 String topViewId = myTopFrame.viewport.getSequenceSetId();
3132 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3134 JInternalFrame[] frames = desktop.getAllFrames();
3135 for (JInternalFrame frame : frames)
3137 if (frame instanceof SplitFrame && frame != source)
3139 SplitFrame sf = (SplitFrame) frame;
3140 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3141 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3142 boolean gatherThis = false;
3143 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3145 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3146 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3147 if (topViewId.equals(topPanel.av.getSequenceSetId())
3148 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3151 topPanel.av.setGatherViewsHere(false);
3152 bottomPanel.av.setGatherViewsHere(false);
3153 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3154 topFrame.getSize()));
3155 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3156 .getLocation(), bottomFrame.getSize()));
3157 myTopFrame.addAlignmentPanel(topPanel, false);
3158 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3164 topFrame.getAlignPanels().clear();
3165 bottomFrame.getAlignPanels().clear();
3172 * The dust settles...give focus to the tab we did this from.
3174 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3178 public static AlignFrame getCurrentAlignFrame()
3180 return currentAlignFrame;
3183 public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
3185 Desktop.currentAlignFrame = currentAlignFrame;
3188 public static groovy.ui.Console getGroovyConsole()
3190 return groovyConsole;