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.KeyEvent;
65 import java.awt.event.MouseAdapter;
66 import java.awt.event.MouseEvent;
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.io.BufferedInputStream;
73 import java.io.FileOutputStream;
75 import java.util.ArrayList;
76 import java.util.Hashtable;
77 import java.util.List;
78 import java.util.StringTokenizer;
79 import java.util.Vector;
80 import java.util.concurrent.ExecutorService;
81 import java.util.concurrent.Executors;
82 import java.util.concurrent.Semaphore;
84 import javax.swing.AbstractAction;
85 import javax.swing.Box;
86 import javax.swing.BoxLayout;
87 import javax.swing.DefaultDesktopManager;
88 import javax.swing.DesktopManager;
89 import javax.swing.JButton;
90 import javax.swing.JCheckBox;
91 import javax.swing.JComboBox;
92 import javax.swing.JComponent;
93 import javax.swing.JDesktopPane;
94 import javax.swing.JFrame;
95 import javax.swing.JInternalFrame;
96 import javax.swing.JLabel;
97 import javax.swing.JMenuItem;
98 import javax.swing.JOptionPane;
99 import javax.swing.JPanel;
100 import javax.swing.JPopupMenu;
101 import javax.swing.JProgressBar;
102 import javax.swing.KeyStroke;
103 import javax.swing.SwingUtilities;
104 import javax.swing.event.HyperlinkEvent;
105 import javax.swing.event.HyperlinkEvent.EventType;
106 import javax.swing.event.InternalFrameAdapter;
107 import javax.swing.event.InternalFrameEvent;
108 import javax.swing.event.MenuEvent;
109 import javax.swing.event.MenuListener;
116 * @version $Revision: 1.155 $
118 public class Desktop extends jalview.jbgui.GDesktop implements
119 DropTargetListener, ClipboardOwner, IProgressIndicator,
120 jalview.api.StructureSelectionManagerProvider
123 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
126 * news reader - null if it was never started.
128 private BlogReader jvnews = null;
130 private File projectFile;
134 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
136 public void addJalviewPropertyChangeListener(
137 PropertyChangeListener listener)
139 changeSupport.addJalviewPropertyChangeListener(listener);
143 * @param propertyName
145 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
146 * java.beans.PropertyChangeListener)
148 public void addJalviewPropertyChangeListener(String propertyName,
149 PropertyChangeListener listener)
151 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
155 * @param propertyName
157 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
158 * java.beans.PropertyChangeListener)
160 public void removeJalviewPropertyChangeListener(String propertyName,
161 PropertyChangeListener listener)
163 changeSupport.removeJalviewPropertyChangeListener(propertyName,
167 /** Singleton Desktop instance */
168 public static Desktop instance;
170 public static MyDesktopPane desktop;
172 static int openFrameCount = 0;
174 static final int xOffset = 30;
176 static final int yOffset = 30;
178 public static jalview.ws.jws1.Discoverer discoverer;
180 public static Object[] jalviewClipboard;
182 public static boolean internalCopy = false;
184 static int fileLoadingCount = 0;
186 class MyDesktopManager implements DesktopManager
189 private DesktopManager delegate;
191 public MyDesktopManager(DesktopManager delegate)
193 this.delegate = delegate;
197 public void activateFrame(JInternalFrame f)
201 delegate.activateFrame(f);
202 } catch (NullPointerException npe)
204 Point p = getMousePosition();
205 instance.showPasteMenu(p.x, p.y);
210 public void beginDraggingFrame(JComponent f)
212 delegate.beginDraggingFrame(f);
216 public void beginResizingFrame(JComponent f, int direction)
218 delegate.beginResizingFrame(f, direction);
222 public void closeFrame(JInternalFrame f)
224 delegate.closeFrame(f);
228 public void deactivateFrame(JInternalFrame f)
230 delegate.deactivateFrame(f);
234 public void deiconifyFrame(JInternalFrame f)
236 delegate.deiconifyFrame(f);
240 public void dragFrame(JComponent f, int newX, int newY)
246 delegate.dragFrame(f, newX, newY);
250 public void endDraggingFrame(JComponent f)
252 delegate.endDraggingFrame(f);
256 public void endResizingFrame(JComponent f)
258 delegate.endResizingFrame(f);
262 public void iconifyFrame(JInternalFrame f)
264 delegate.iconifyFrame(f);
268 public void maximizeFrame(JInternalFrame f)
270 delegate.maximizeFrame(f);
274 public void minimizeFrame(JInternalFrame f)
276 delegate.minimizeFrame(f);
280 public void openFrame(JInternalFrame f)
282 delegate.openFrame(f);
286 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
293 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
297 public void setBoundsForFrame(JComponent f, int newX, int newY,
298 int newWidth, int newHeight)
300 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
303 // All other methods, simply delegate
308 * Creates a new Desktop object.
313 * A note to implementors. It is ESSENTIAL that any activities that might
314 * block are spawned off as threads rather than waited for during this
318 doVamsasClientCheck();
320 groovyShell = new JMenuItem();
321 groovyShell.setText(MessageManager.getString("label.groovy_console"));
322 groovyShell.addActionListener(new ActionListener()
325 public void actionPerformed(ActionEvent e)
327 groovyShell_actionPerformed();
330 toolsMenu.add(groovyShell);
331 groovyShell.setVisible(true);
333 doConfigureStructurePrefs();
334 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
335 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
336 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
338 boolean showjconsole = jalview.bin.Cache.getDefault(
339 "SHOW_JAVA_CONSOLE", false);
340 desktop = new MyDesktopPane(selmemusage);
341 if (Platform.isAMac())
343 desktop.setDoubleBuffered(false);
345 showMemusage.setSelected(selmemusage);
346 desktop.setBackground(Color.white);
347 getContentPane().setLayout(new BorderLayout());
348 // alternate config - have scrollbars - see notes in JAL-153
349 // JScrollPane sp = new JScrollPane();
350 // sp.getViewport().setView(desktop);
351 // getContentPane().add(sp, BorderLayout.CENTER);
352 getContentPane().add(desktop, BorderLayout.CENTER);
353 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
355 // This line prevents Windows Look&Feel resizing all new windows to maximum
356 // if previous window was maximised
357 desktop.setDesktopManager(new MyDesktopManager(
358 new DefaultDesktopManager()));
360 Rectangle dims = getLastKnownDimensions("");
367 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
368 setBounds((screenSize.width - 900) / 2,
369 (screenSize.height - 650) / 2, 900, 650);
371 jconsole = new Console(this, showjconsole);
372 // add essential build information
373 jconsole.setHeader("Jalview Version: "
374 + jalview.bin.Cache.getProperty("VERSION") + "\n"
375 + "Jalview Installation: "
376 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
377 + "\n" + "Build Date: "
378 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
379 + "Java version: " + System.getProperty("java.version") + "\n"
380 + System.getProperty("os.arch") + " "
381 + System.getProperty("os.name") + " "
382 + System.getProperty("os.version"));
384 showConsole(showjconsole);
386 showNews.setVisible(false);
390 this.addWindowListener(new WindowAdapter()
393 public void windowClosing(WindowEvent evt)
400 this.addMouseListener(ma = new MouseAdapter()
403 public void mousePressed(MouseEvent evt)
405 if (evt.isPopupTrigger()) // Mac
407 showPasteMenu(evt.getX(), evt.getY());
412 public void mouseReleased(MouseEvent evt)
414 if (evt.isPopupTrigger()) // Windows
416 showPasteMenu(evt.getX(), evt.getY());
420 desktop.addMouseListener(ma);
422 this.addFocusListener(new FocusListener()
426 public void focusLost(FocusEvent e)
428 // TODO Auto-generated method stub
433 public void focusGained(FocusEvent e)
435 Cache.log.debug("Relaying windows after focus gain");
436 // make sure that we sort windows properly after we gain focus
437 instance.relayerWindows();
440 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
441 // Spawn a thread that shows the splashscreen
442 SwingUtilities.invokeLater(new Runnable()
452 // Thread off a new instance of the file chooser - this reduces the time it
453 // takes to open it later on.
454 new Thread(new Runnable()
459 Cache.log.debug("Filechooser init thread started.");
460 new JalviewFileChooser(
461 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
462 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
463 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
464 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
465 Cache.log.debug("Filechooser init thread finished.");
468 // Add the service change listener
469 changeSupport.addJalviewPropertyChangeListener("services",
470 new PropertyChangeListener()
474 public void propertyChange(PropertyChangeEvent evt)
476 Cache.log.debug("Firing service changed event for "
477 + evt.getNewValue());
478 JalviewServicesChanged(evt);
484 public void doConfigureStructurePrefs()
486 // configure services
487 StructureSelectionManager ssm = StructureSelectionManager
488 .getStructureSelectionManager(this);
489 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
491 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
492 Preferences.ADD_TEMPFACT_ANN, true));
493 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
494 Preferences.STRUCT_FROM_PDB, true));
495 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
496 Preferences.USE_RNAVIEW, true));
500 ssm.setAddTempFacAnnot(false);
501 ssm.setProcessSecondaryStructure(false);
502 ssm.setSecStructServices(false);
506 public void checkForNews()
508 final Desktop me = this;
509 // Thread off the news reader, in case there are connection problems.
510 addDialogThread(new Runnable()
515 Cache.log.debug("Starting news thread.");
517 jvnews = new BlogReader(me);
518 showNews.setVisible(true);
519 Cache.log.debug("Completed news thread.");
525 protected void showNews_actionPerformed(ActionEvent e)
527 showNews(showNews.isSelected());
530 void showNews(boolean visible)
533 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
534 showNews.setSelected(visible);
535 if (visible && !jvnews.isVisible())
537 new Thread(new Runnable()
542 long now = System.currentTimeMillis();
543 Desktop.instance.setProgressBar(
544 MessageManager.getString("status.refreshing_news"), now);
545 jvnews.refreshNews();
546 Desktop.instance.setProgressBar(null, now);
555 * recover the last known dimensions for a jalview window
558 * - empty string is desktop, all other windows have unique prefix
559 * @return null or last known dimensions scaled to current geometry (if last
560 * window geom was known)
562 Rectangle getLastKnownDimensions(String windowName)
564 // TODO: lock aspect ratio for scaling desktop Bug #0058199
565 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
566 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
567 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
568 String width = jalview.bin.Cache.getProperty(windowName
570 String height = jalview.bin.Cache.getProperty(windowName
572 if ((x != null) && (y != null) && (width != null) && (height != null))
574 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
575 .parseInt(width), ih = Integer.parseInt(height);
576 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
578 // attempt #1 - try to cope with change in screen geometry - this
579 // version doesn't preserve original jv aspect ratio.
580 // take ratio of current screen size vs original screen size.
581 double sw = ((1f * screenSize.width) / (1f * Integer
582 .parseInt(jalview.bin.Cache
583 .getProperty("SCREENGEOMETRY_WIDTH"))));
584 double sh = ((1f * screenSize.height) / (1f * Integer
585 .parseInt(jalview.bin.Cache
586 .getProperty("SCREENGEOMETRY_HEIGHT"))));
587 // rescale the bounds depending upon the current screen geometry.
588 ix = (int) (ix * sw);
589 iw = (int) (iw * sw);
590 iy = (int) (iy * sh);
591 ih = (int) (ih * sh);
592 while (ix >= screenSize.width)
594 jalview.bin.Cache.log
595 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
596 ix -= screenSize.width;
598 while (iy >= screenSize.height)
600 jalview.bin.Cache.log
601 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
602 iy -= screenSize.height;
604 jalview.bin.Cache.log.debug("Got last known dimensions for "
605 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
608 // return dimensions for new instance
609 return new Rectangle(ix, iy, iw, ih);
614 private void doVamsasClientCheck()
616 if (jalview.bin.Cache.vamsasJarsPresent())
618 setupVamsasDisconnectedGui();
619 VamsasMenu.setVisible(true);
620 final Desktop us = this;
621 VamsasMenu.addMenuListener(new MenuListener()
623 // this listener remembers when the menu was first selected, and
624 // doesn't rebuild the session list until it has been cleared and
626 boolean refresh = true;
629 public void menuCanceled(MenuEvent e)
635 public void menuDeselected(MenuEvent e)
641 public void menuSelected(MenuEvent e)
645 us.buildVamsasStMenu();
650 vamsasStart.setVisible(true);
654 void showPasteMenu(int x, int y)
656 JPopupMenu popup = new JPopupMenu();
657 JMenuItem item = new JMenuItem(
658 MessageManager.getString("label.paste_new_window"));
659 item.addActionListener(new ActionListener()
662 public void actionPerformed(ActionEvent evt)
669 popup.show(this, x, y);
676 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
677 Transferable contents = c.getContents(this);
679 if (contents != null)
681 String file = (String) contents
682 .getTransferData(DataFlavor.stringFlavor);
684 String format = new IdentifyFile().identify(file,
685 FormatAdapter.PASTE);
687 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
690 } catch (Exception ex)
693 .println("Unable to paste alignment from system clipboard:\n"
699 * Adds and opens the given frame to the desktop
710 public static synchronized void addInternalFrame(
711 final JInternalFrame frame, String title, int w, int h)
713 addInternalFrame(frame, title, true, w, h, true);
717 * Add an internal frame to the Jalview desktop
724 * When true, display frame immediately, otherwise, caller must call
725 * setVisible themselves.
731 public static synchronized void addInternalFrame(
732 final JInternalFrame frame, String title, boolean makeVisible,
735 addInternalFrame(frame, title, makeVisible, w, h, true);
739 * Add an internal frame to the Jalview desktop and make it visible
752 public static synchronized void addInternalFrame(
753 final JInternalFrame frame, String title, int w, int h,
756 addInternalFrame(frame, title, true, w, h, resizable);
760 * Add an internal frame to the Jalview desktop
767 * When true, display frame immediately, otherwise, caller must call
768 * setVisible themselves.
776 public static synchronized void addInternalFrame(
777 final JInternalFrame frame, String title, boolean makeVisible,
778 int w, int h, boolean resizable)
781 // TODO: allow callers to determine X and Y position of frame (eg. via
783 // TODO: consider fixing method to update entries in the window submenu with
784 // the current window title
786 frame.setTitle(title);
787 if (frame.getWidth() < 1 || frame.getHeight() < 1)
791 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
792 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
793 // IF JALVIEW IS RUNNING HEADLESS
794 // ///////////////////////////////////////////////
796 || (System.getProperty("java.awt.headless") != null && System
797 .getProperty("java.awt.headless").equals("true")))
804 frame.setVisible(makeVisible);
805 frame.setClosable(true);
806 frame.setResizable(resizable);
807 frame.setMaximizable(resizable);
808 frame.setIconifiable(resizable);
809 if (Platform.isAMac())
811 frame.setIconifiable(false);
812 frame.setFrameIcon(null);
813 // frame.setDesktopIcon(null);
814 frame.setDoubleBuffered(false);
816 if (frame.getX() < 1 && frame.getY() < 1)
818 frame.setLocation(xOffset * openFrameCount, yOffset
819 * ((openFrameCount - 1) % 10) + yOffset);
823 * add an entry for the new frame in the Window menu
824 * (and remove it when the frame is closed)
826 final JMenuItem menuItem = new JMenuItem(title);
827 frame.addInternalFrameListener(new InternalFrameAdapter()
830 public void internalFrameActivated(InternalFrameEvent evt)
832 JInternalFrame itf = desktop.getSelectedFrame();
840 public void internalFrameClosed(InternalFrameEvent evt)
842 PaintRefresher.RemoveComponent(frame);
845 * defensive check to prevent frames being
846 * added half off the window
848 if (openFrameCount > 0)
854 * ensure no reference to alignFrame retained by menu item listener
856 if (menuItem.getActionListeners().length > 0)
858 menuItem.removeActionListener(menuItem.getActionListeners()[0]);
860 windowMenu.remove(menuItem);
861 JInternalFrame itf = desktop.getSelectedFrame();
865 if (itf instanceof AlignFrame)
867 Jalview.setCurrentAlignFrame((AlignFrame) itf);
874 menuItem.addActionListener(new ActionListener()
877 public void actionPerformed(ActionEvent e)
881 frame.setSelected(true);
882 frame.setIcon(false);
883 } catch (java.beans.PropertyVetoException ex)
890 windowMenu.add(menuItem);
896 frame.setSelected(true);
897 frame.requestFocus();
898 } catch (java.beans.PropertyVetoException ve)
900 } catch (java.lang.ClassCastException cex)
903 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
909 public void lostOwnership(Clipboard clipboard, Transferable contents)
913 Desktop.jalviewClipboard = null;
916 internalCopy = false;
920 public void dragEnter(DropTargetDragEvent evt)
925 public void dragExit(DropTargetEvent evt)
930 public void dragOver(DropTargetDragEvent evt)
935 public void dropActionChanged(DropTargetDragEvent evt)
946 public void drop(DropTargetDropEvent evt)
948 boolean success = true;
949 // JAL-1552 - acceptDrop required before getTransferable call for
950 // Java's Transferable for native dnd
951 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
952 Transferable t = evt.getTransferable();
953 java.util.List<String> files = new ArrayList<String>();
954 java.util.List<String> protocols = new ArrayList<String>();
958 Desktop.transferFromDropTarget(files, protocols, evt, t);
959 } catch (Exception e)
969 for (int i = 0; i < files.size(); i++)
971 String file = files.get(i).toString();
972 String protocol = (protocols == null) ? FormatAdapter.FILE
973 : (String) protocols.get(i);
974 String format = null;
976 if (file.endsWith(".jar"))
983 format = new IdentifyFile().identify(file, protocol);
986 new FileLoader().LoadFile(file, protocol, format);
989 } catch (Exception ex)
994 evt.dropComplete(success); // need this to ensure input focus is properly
995 // transfered to any new windows created
1005 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1007 JalviewFileChooser chooser = new JalviewFileChooser(
1008 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1009 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1010 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1011 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1013 chooser.setFileView(new JalviewFileView());
1014 chooser.setDialogTitle(MessageManager
1015 .getString("label.open_local_file"));
1016 chooser.setToolTipText(MessageManager.getString("action.open"));
1018 int value = chooser.showOpenDialog(this);
1020 if (value == JalviewFileChooser.APPROVE_OPTION)
1022 String choice = chooser.getSelectedFile().getPath();
1023 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1024 .getSelectedFile().getParent());
1026 String format = null;
1027 if (chooser.getSelectedFormat() != null
1028 && chooser.getSelectedFormat().equals("Jalview"))
1034 format = new IdentifyFile().identify(choice, FormatAdapter.FILE);
1037 if (viewport != null)
1039 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1044 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1056 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1058 // This construct allows us to have a wider textfield
1060 JLabel label = new JLabel(
1061 MessageManager.getString("label.input_file_url"));
1062 final JComboBox history = new JComboBox();
1064 JPanel panel = new JPanel(new GridLayout(2, 1));
1067 history.setPreferredSize(new Dimension(400, 20));
1068 history.setEditable(true);
1069 history.addItem("http://www.");
1071 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1075 if (historyItems != null)
1077 st = new StringTokenizer(historyItems, "\t");
1079 while (st.hasMoreTokens())
1081 history.addItem(st.nextElement());
1085 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1086 MessageManager.getString("label.input_alignment_from_url"),
1087 JOptionPane.OK_CANCEL_OPTION);
1089 if (reply != JOptionPane.OK_OPTION)
1094 String url = history.getSelectedItem().toString();
1096 if (url.toLowerCase().endsWith(".jar"))
1098 if (viewport != null)
1100 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1105 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1110 String format = new IdentifyFile().identify(url, FormatAdapter.URL);
1112 if (format.equals("URL NOT FOUND"))
1114 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1115 MessageManager.formatMessage("label.couldnt_locate",
1116 new Object[] { url }), MessageManager
1117 .getString("label.url_not_found"),
1118 JOptionPane.WARNING_MESSAGE);
1123 if (viewport != null)
1125 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1129 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1135 * Opens the CutAndPaste window for the user to paste an alignment in to
1138 * - if not null, the pasted alignment is added to the current
1139 * alignment; if null, to a new alignment window
1142 public void inputTextboxMenuItem_actionPerformed(
1143 AlignmentViewPanel viewPanel)
1145 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1146 cap.setForInput(viewPanel);
1147 Desktop.addInternalFrame(cap,
1148 MessageManager.getString("label.cut_paste_alignmen_file"),
1158 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1160 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1161 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1163 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1164 getBounds().y, getWidth(), getHeight()));
1166 if (jconsole != null)
1168 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1169 jconsole.stopConsole();
1173 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1176 if (dialogExecutor != null)
1178 dialogExecutor.shutdownNow();
1180 closeAll_actionPerformed(null);
1182 if (groovyConsole != null)
1184 // suppress a possible repeat prompt to save script
1185 groovyConsole.setDirty(false);
1186 groovyConsole.exit();
1191 private void storeLastKnownDimensions(String string, Rectangle jc)
1193 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1194 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1195 + " height:" + jc.height);
1197 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1198 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1199 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1200 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1210 public void aboutMenuItem_actionPerformed(ActionEvent e)
1212 // StringBuffer message = getAboutMessage(false);
1213 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1215 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1216 new Thread(new Runnable()
1221 new SplashScreen(true);
1226 public StringBuffer getAboutMessage(boolean shortv)
1228 StringBuffer message = new StringBuffer();
1229 message.append("<html>");
1232 message.append("<h1><strong>Version: "
1233 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1234 message.append("<strong>Last Updated: <em>"
1235 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1236 + "</em></strong>");
1242 message.append("<strong>Version "
1243 + jalview.bin.Cache.getProperty("VERSION")
1244 + "; last updated: "
1245 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1248 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1251 message.append("<br>...Checking latest version...</br>");
1253 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1254 .equals(jalview.bin.Cache.getProperty("VERSION")))
1256 boolean red = false;
1257 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1258 .indexOf("automated build") == -1)
1261 // Displayed when code version and jnlp version do not match and code
1262 // version is not a development build
1263 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1266 message.append("<br>!! Version "
1267 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1269 + " is available for download from "
1270 + jalview.bin.Cache.getDefault("www.jalview.org",
1271 "http://www.jalview.org") + " !!");
1274 message.append("</div>");
1277 message.append("<br>Authors: "
1279 .getDefault("AUTHORFNAMES",
1280 "The Jalview Authors (See AUTHORS file for current list)")
1281 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1282 + "<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"
1283 + "<br><br>If you use Jalview, please cite:"
1284 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1285 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1286 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1298 public void documentationMenuItem_actionPerformed(ActionEvent e)
1302 Help.showHelpWindow();
1303 } catch (Exception ex)
1309 public void closeAll_actionPerformed(ActionEvent e)
1311 // TODO show a progress bar while closing?
1312 JInternalFrame[] frames = desktop.getAllFrames();
1313 for (int i = 0; i < frames.length; i++)
1317 frames[i].setClosed(true);
1318 } catch (java.beans.PropertyVetoException ex)
1322 Jalview.setCurrentAlignFrame(null);
1323 System.out.println("ALL CLOSED");
1324 if (v_client != null)
1326 // TODO clear binding to vamsas document objects on close_all
1330 * reset state of singleton objects as appropriate (clear down session state
1331 * when all windows are closed)
1333 StructureSelectionManager ssm = StructureSelectionManager
1334 .getStructureSelectionManager(this);
1343 public void raiseRelated_actionPerformed(ActionEvent e)
1345 reorderAssociatedWindows(false, false);
1349 public void minimizeAssociated_actionPerformed(ActionEvent e)
1351 reorderAssociatedWindows(true, false);
1354 void closeAssociatedWindows()
1356 reorderAssociatedWindows(false, true);
1362 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1366 protected void garbageCollect_actionPerformed(ActionEvent e)
1368 // We simply collect the garbage
1369 jalview.bin.Cache.log.debug("Collecting garbage...");
1371 jalview.bin.Cache.log.debug("Finished garbage collection.");
1378 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1382 protected void showMemusage_actionPerformed(ActionEvent e)
1384 desktop.showMemoryUsage(showMemusage.isSelected());
1391 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1395 protected void showConsole_actionPerformed(ActionEvent e)
1397 showConsole(showConsole.isSelected());
1400 Console jconsole = null;
1403 * control whether the java console is visible or not
1407 void showConsole(boolean selected)
1409 showConsole.setSelected(selected);
1410 // TODO: decide if we should update properties file
1411 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1413 jconsole.setVisible(selected);
1416 void reorderAssociatedWindows(boolean minimize, boolean close)
1418 JInternalFrame[] frames = desktop.getAllFrames();
1419 if (frames == null || frames.length < 1)
1424 AlignmentViewport source = null, target = null;
1425 if (frames[0] instanceof AlignFrame)
1427 source = ((AlignFrame) frames[0]).getCurrentView();
1429 else if (frames[0] instanceof TreePanel)
1431 source = ((TreePanel) frames[0]).getViewPort();
1433 else if (frames[0] instanceof PCAPanel)
1435 source = ((PCAPanel) frames[0]).av;
1437 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1439 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1444 for (int i = 0; i < frames.length; i++)
1447 if (frames[i] == null)
1451 if (frames[i] instanceof AlignFrame)
1453 target = ((AlignFrame) frames[i]).getCurrentView();
1455 else if (frames[i] instanceof TreePanel)
1457 target = ((TreePanel) frames[i]).getViewPort();
1459 else if (frames[i] instanceof PCAPanel)
1461 target = ((PCAPanel) frames[i]).av;
1463 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1465 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1468 if (source == target)
1474 frames[i].setClosed(true);
1478 frames[i].setIcon(minimize);
1481 frames[i].toFront();
1485 } catch (java.beans.PropertyVetoException ex)
1500 protected void preferences_actionPerformed(ActionEvent e)
1512 public void saveState_actionPerformed(ActionEvent e)
1514 JalviewFileChooser chooser = new JalviewFileChooser(
1515 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1516 new String[] { "jvp" }, new String[] { "Jalview Project" },
1519 chooser.setFileView(new JalviewFileView());
1520 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1522 int value = chooser.showSaveDialog(this);
1524 if (value == JalviewFileChooser.APPROVE_OPTION)
1526 final Desktop me = this;
1527 final java.io.File choice = chooser.getSelectedFile();
1528 setProjectFile(choice);
1530 new Thread(new Runnable()
1535 // TODO: refactor to Jalview desktop session controller action.
1536 setProgressBar(MessageManager.formatMessage(
1537 "label.saving_jalview_project",
1538 new Object[] { choice.getName() }), choice.hashCode());
1539 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1540 choice.getParent());
1541 // TODO catch and handle errors for savestate
1542 // TODO prevent user from messing with the Desktop whilst we're saving
1545 new Jalview2XML().saveState(choice);
1546 } catch (OutOfMemoryError oom)
1548 new OOMWarning("Whilst saving current state to "
1549 + choice.getName(), oom);
1550 } catch (Exception ex)
1553 "Problems whilst trying to save to " + choice.getName(),
1555 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1556 "label.error_whilst_saving_current_state_to",
1557 new Object[] { choice.getName() }), MessageManager
1558 .getString("label.couldnt_save_project"),
1559 JOptionPane.WARNING_MESSAGE);
1561 setProgressBar(null, choice.hashCode());
1567 private void setProjectFile(File choice)
1569 this.projectFile = choice;
1572 public File getProjectFile()
1574 return this.projectFile;
1584 public void loadState_actionPerformed(ActionEvent e)
1586 JalviewFileChooser chooser = new JalviewFileChooser(
1587 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1588 "jvp", "jar" }, new String[] { "Jalview Project",
1589 "Jalview Project (old)" }, "Jalview Project");
1590 chooser.setFileView(new JalviewFileView());
1591 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1593 int value = chooser.showOpenDialog(this);
1595 if (value == JalviewFileChooser.APPROVE_OPTION)
1597 final File selectedFile = chooser.getSelectedFile();
1598 setProjectFile(selectedFile);
1599 final String choice = selectedFile.getAbsolutePath();
1600 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1601 selectedFile.getParent());
1602 new Thread(new Runnable()
1608 MessageManager.formatMessage(
1609 "label.loading_jalview_project",
1610 new Object[] { choice }), choice.hashCode());
1613 new Jalview2XML().loadJalviewAlign(choice);
1614 } catch (OutOfMemoryError oom)
1616 new OOMWarning("Whilst loading project from " + choice, oom);
1617 } catch (Exception ex)
1619 Cache.log.error("Problems whilst loading project from "
1621 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1623 "label.error_whilst_loading_project_from",
1624 new Object[] { choice }), MessageManager
1625 .getString("label.couldnt_load_project"),
1626 JOptionPane.WARNING_MESSAGE);
1628 setProgressBar(null, choice.hashCode());
1635 public void inputSequence_actionPerformed(ActionEvent e)
1637 new SequenceFetcher(this);
1640 JPanel progressPanel;
1642 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1644 public void startLoading(final String fileName)
1646 if (fileLoadingCount == 0)
1648 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1649 "label.loading_file", new Object[] { fileName })));
1654 private JPanel addProgressPanel(String string)
1656 if (progressPanel == null)
1658 progressPanel = new JPanel(new GridLayout(1, 1));
1659 totalProgressCount = 0;
1660 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1662 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1663 JProgressBar progressBar = new JProgressBar();
1664 progressBar.setIndeterminate(true);
1666 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1668 thisprogress.add(progressBar, BorderLayout.CENTER);
1669 progressPanel.add(thisprogress);
1670 ((GridLayout) progressPanel.getLayout())
1671 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1672 ++totalProgressCount;
1673 instance.validate();
1674 return thisprogress;
1677 int totalProgressCount = 0;
1679 private void removeProgressPanel(JPanel progbar)
1681 if (progressPanel != null)
1683 synchronized (progressPanel)
1685 progressPanel.remove(progbar);
1686 GridLayout gl = (GridLayout) progressPanel.getLayout();
1687 gl.setRows(gl.getRows() - 1);
1688 if (--totalProgressCount < 1)
1690 this.getContentPane().remove(progressPanel);
1691 progressPanel = null;
1698 public void stopLoading()
1701 if (fileLoadingCount < 1)
1703 while (fileLoadingPanels.size() > 0)
1705 removeProgressPanel(fileLoadingPanels.remove(0));
1707 fileLoadingPanels.clear();
1708 fileLoadingCount = 0;
1713 public static int getViewCount(String alignmentId)
1715 AlignmentViewport[] aps = getViewports(alignmentId);
1716 return (aps == null) ? 0 : aps.length;
1721 * @param alignmentId
1722 * - if null, all sets are returned
1723 * @return all AlignmentPanels concerning the alignmentId sequence set
1725 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1727 if (Desktop.desktop == null)
1729 // no frames created and in headless mode
1730 // TODO: verify that frames are recoverable when in headless mode
1733 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1734 AlignFrame[] frames = getAlignFrames();
1739 for (AlignFrame af : frames)
1741 for (AlignmentPanel ap : af.alignPanels)
1743 if (alignmentId == null
1744 || alignmentId.equals(ap.av.getSequenceSetId()))
1750 if (aps.size() == 0)
1754 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1759 * get all the viewports on an alignment.
1761 * @param sequenceSetId
1762 * unique alignment id (may be null - all viewports returned in that
1764 * @return all viewports on the alignment bound to sequenceSetId
1766 public static AlignmentViewport[] getViewports(String sequenceSetId)
1768 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1769 if (desktop != null)
1771 AlignFrame[] frames = Desktop.getAlignFrames();
1773 for (AlignFrame afr : frames)
1775 if (sequenceSetId == null
1776 || afr.getViewport().getSequenceSetId()
1777 .equals(sequenceSetId))
1779 if (afr.alignPanels != null)
1781 for (AlignmentPanel ap : afr.alignPanels)
1783 if (sequenceSetId == null
1784 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1792 viewp.add(afr.getViewport());
1796 if (viewp.size() > 0)
1798 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1805 * Explode the views in the given frame into separate AlignFrame
1809 public static void explodeViews(AlignFrame af)
1811 int size = af.alignPanels.size();
1817 for (int i = 0; i < size; i++)
1819 AlignmentPanel ap = af.alignPanels.get(i);
1820 AlignFrame newaf = new AlignFrame(ap);
1823 * Restore the view's last exploded frame geometry if known. Multiple
1824 * views from one exploded frame share and restore the same (frame)
1825 * position and size.
1827 Rectangle geometry = ap.av.getExplodedGeometry();
1828 if (geometry != null)
1830 newaf.setBounds(geometry);
1833 ap.av.setGatherViewsHere(false);
1835 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1836 AlignFrame.DEFAULT_HEIGHT);
1839 af.alignPanels.clear();
1840 af.closeMenuItem_actionPerformed(true);
1845 * Gather expanded views (separate AlignFrame's) with the same sequence set
1846 * identifier back in to this frame as additional views, and close the
1847 * expanded views. Note the expanded frames may themselves have multiple
1848 * views. We take the lot.
1852 public void gatherViews(AlignFrame source)
1854 source.viewport.setGatherViewsHere(true);
1855 source.viewport.setExplodedGeometry(source.getBounds());
1856 JInternalFrame[] frames = desktop.getAllFrames();
1857 String viewId = source.viewport.getSequenceSetId();
1859 for (int t = 0; t < frames.length; t++)
1861 if (frames[t] instanceof AlignFrame && frames[t] != source)
1863 AlignFrame af = (AlignFrame) frames[t];
1864 boolean gatherThis = false;
1865 for (int a = 0; a < af.alignPanels.size(); a++)
1867 AlignmentPanel ap = af.alignPanels.get(a);
1868 if (viewId.equals(ap.av.getSequenceSetId()))
1871 ap.av.setGatherViewsHere(false);
1872 ap.av.setExplodedGeometry(af.getBounds());
1873 source.addAlignmentPanel(ap, false);
1879 af.alignPanels.clear();
1880 af.closeMenuItem_actionPerformed(true);
1887 jalview.gui.VamsasApplication v_client = null;
1890 public void vamsasImport_actionPerformed(ActionEvent e)
1892 if (v_client == null)
1894 // Load and try to start a session.
1895 JalviewFileChooser chooser = new JalviewFileChooser(
1896 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1898 chooser.setFileView(new JalviewFileView());
1899 chooser.setDialogTitle(MessageManager
1900 .getString("label.open_saved_vamsas_session"));
1901 chooser.setToolTipText(MessageManager
1902 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1904 int value = chooser.showOpenDialog(this);
1906 if (value == JalviewFileChooser.APPROVE_OPTION)
1908 String fle = chooser.getSelectedFile().toString();
1909 if (!vamsasImport(chooser.getSelectedFile()))
1912 .showInternalMessageDialog(
1914 MessageManager.formatMessage(
1915 "label.couldnt_import_as_vamsas_session",
1916 new Object[] { fle }),
1918 .getString("label.vamsas_document_import_failed"),
1919 JOptionPane.ERROR_MESSAGE);
1925 jalview.bin.Cache.log
1926 .error("Implementation error - load session from a running session is not supported.");
1931 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1934 * @return true if import was a success and a session was started.
1936 public boolean vamsasImport(URL url)
1938 // TODO: create progress bar
1939 if (v_client != null)
1942 jalview.bin.Cache.log
1943 .error("Implementation error - load session from a running session is not supported.");
1949 // copy the URL content to a temporary local file
1950 // TODO: be a bit cleverer here with nio (?!)
1951 File file = File.createTempFile("vdocfromurl", ".vdj");
1952 FileOutputStream fos = new FileOutputStream(file);
1953 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1954 byte[] buffer = new byte[2048];
1956 while ((ln = bis.read(buffer)) > -1)
1958 fos.write(buffer, 0, ln);
1962 v_client = new jalview.gui.VamsasApplication(this, file,
1963 url.toExternalForm());
1964 } catch (Exception ex)
1966 jalview.bin.Cache.log.error(
1967 "Failed to create new vamsas session from contents of URL "
1971 setupVamsasConnectedGui();
1972 v_client.initial_update(); // TODO: thread ?
1973 return v_client.inSession();
1977 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1980 * @return true if import was a success and a session was started.
1982 public boolean vamsasImport(File file)
1984 if (v_client != null)
1987 jalview.bin.Cache.log
1988 .error("Implementation error - load session from a running session is not supported.");
1992 setProgressBar(MessageManager.formatMessage(
1993 "status.importing_vamsas_session_from",
1994 new Object[] { file.getName() }), file.hashCode());
1997 v_client = new jalview.gui.VamsasApplication(this, file, null);
1998 } catch (Exception ex)
2000 setProgressBar(MessageManager.formatMessage(
2001 "status.importing_vamsas_session_from",
2002 new Object[] { file.getName() }), file.hashCode());
2003 jalview.bin.Cache.log.error(
2004 "New vamsas session from existing session file failed:", ex);
2007 setupVamsasConnectedGui();
2008 v_client.initial_update(); // TODO: thread ?
2009 setProgressBar(MessageManager.formatMessage(
2010 "status.importing_vamsas_session_from",
2011 new Object[] { file.getName() }), file.hashCode());
2012 return v_client.inSession();
2015 public boolean joinVamsasSession(String mysesid)
2017 if (v_client != null)
2021 .getString("error.try_join_vamsas_session_another"));
2023 if (mysesid == null)
2026 MessageManager.getString("error.invalid_vamsas_session_id"));
2028 v_client = new VamsasApplication(this, mysesid);
2029 setupVamsasConnectedGui();
2030 v_client.initial_update();
2031 return (v_client.inSession());
2035 public void vamsasStart_actionPerformed(ActionEvent e)
2037 if (v_client == null)
2040 // we just start a default session for moment.
2042 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2043 * getProperty("LAST_DIRECTORY"));
2045 * chooser.setFileView(new JalviewFileView());
2046 * chooser.setDialogTitle("Load Vamsas file");
2047 * chooser.setToolTipText("Import");
2049 * int value = chooser.showOpenDialog(this);
2051 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2052 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2054 v_client = new VamsasApplication(this);
2055 setupVamsasConnectedGui();
2056 v_client.initial_update(); // TODO: thread ?
2060 // store current data in session.
2061 v_client.push_update(); // TODO: thread
2065 protected void setupVamsasConnectedGui()
2067 vamsasStart.setText(MessageManager.getString("label.session_update"));
2068 vamsasSave.setVisible(true);
2069 vamsasStop.setVisible(true);
2070 vamsasImport.setVisible(false); // Document import to existing session is
2071 // not possible for vamsas-client-1.0.
2074 protected void setupVamsasDisconnectedGui()
2076 vamsasSave.setVisible(false);
2077 vamsasStop.setVisible(false);
2078 vamsasImport.setVisible(true);
2079 vamsasStart.setText(MessageManager
2080 .getString("label.new_vamsas_session"));
2084 public void vamsasStop_actionPerformed(ActionEvent e)
2086 if (v_client != null)
2088 v_client.end_session();
2090 setupVamsasDisconnectedGui();
2094 protected void buildVamsasStMenu()
2096 if (v_client == null)
2098 String[] sess = null;
2101 sess = VamsasApplication.getSessionList();
2102 } catch (Exception e)
2104 jalview.bin.Cache.log.warn(
2105 "Problem getting current sessions list.", e);
2110 jalview.bin.Cache.log.debug("Got current sessions list: "
2111 + sess.length + " entries.");
2112 VamsasStMenu.removeAll();
2113 for (int i = 0; i < sess.length; i++)
2115 JMenuItem sessit = new JMenuItem();
2116 sessit.setText(sess[i]);
2117 sessit.setToolTipText(MessageManager.formatMessage(
2118 "label.connect_to_session", new Object[] { sess[i] }));
2119 final Desktop dsktp = this;
2120 final String mysesid = sess[i];
2121 sessit.addActionListener(new ActionListener()
2125 public void actionPerformed(ActionEvent e)
2127 if (dsktp.v_client == null)
2129 Thread rthr = new Thread(new Runnable()
2135 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2136 dsktp.setupVamsasConnectedGui();
2137 dsktp.v_client.initial_update();
2145 VamsasStMenu.add(sessit);
2147 // don't show an empty menu.
2148 VamsasStMenu.setVisible(sess.length > 0);
2153 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2154 VamsasStMenu.removeAll();
2155 VamsasStMenu.setVisible(false);
2160 // Not interested in the content. Just hide ourselves.
2161 VamsasStMenu.setVisible(false);
2166 public void vamsasSave_actionPerformed(ActionEvent e)
2168 if (v_client != null)
2170 JalviewFileChooser chooser = new JalviewFileChooser(
2171 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2172 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2173 new String[] { "Vamsas Document" }, "Vamsas Document");
2175 chooser.setFileView(new JalviewFileView());
2176 chooser.setDialogTitle(MessageManager
2177 .getString("label.save_vamsas_document_archive"));
2179 int value = chooser.showSaveDialog(this);
2181 if (value == JalviewFileChooser.APPROVE_OPTION)
2183 java.io.File choice = chooser.getSelectedFile();
2184 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2185 "label.saving_vamsas_doc",
2186 new Object[] { choice.getName() }));
2187 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2188 String warnmsg = null;
2189 String warnttl = null;
2192 v_client.vclient.storeDocument(choice);
2195 warnttl = "Serious Problem saving Vamsas Document";
2196 warnmsg = ex.toString();
2197 jalview.bin.Cache.log.error("Error Whilst saving document to "
2200 } catch (Exception ex)
2202 warnttl = "Problem saving Vamsas Document.";
2203 warnmsg = ex.toString();
2204 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2208 removeProgressPanel(progpanel);
2209 if (warnmsg != null)
2211 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2213 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2219 JPanel vamUpdate = null;
2222 * hide vamsas user gui bits when a vamsas document event is being handled.
2225 * true to hide gui, false to reveal gui
2227 public void setVamsasUpdate(boolean b)
2229 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2230 + (b ? "in progress" : "finished"));
2232 if (vamUpdate != null)
2234 this.removeProgressPanel(vamUpdate);
2238 vamUpdate = this.addProgressPanel(MessageManager
2239 .getString("label.updating_vamsas_session"));
2241 vamsasStart.setVisible(!b);
2242 vamsasStop.setVisible(!b);
2243 vamsasSave.setVisible(!b);
2246 public JInternalFrame[] getAllFrames()
2248 return desktop.getAllFrames();
2252 * Checks the given url to see if it gives a response indicating that the user
2253 * should be informed of a new questionnaire.
2257 public void checkForQuestionnaire(String url)
2259 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2260 // javax.swing.SwingUtilities.invokeLater(jvq);
2261 new Thread(jvq).start();
2264 public void checkURLLinks()
2266 // Thread off the URL link checker
2267 addDialogThread(new Runnable()
2272 if (Cache.getDefault("CHECKURLLINKS", true))
2274 // check in case URL links use old style tokens ($SEQUENCE_ID$ for
2275 // sequence id _or_ accession id)
2276 JPanel msgPanel = new JPanel();
2277 msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
2278 msgPanel.add(Box.createVerticalGlue());
2279 JLabel msg = new JLabel(
2281 .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
2282 JLabel msg2 = new JLabel(
2284 .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
2288 final JCheckBox jcb = new JCheckBox(
2289 MessageManager.getString("label.do_not_display_again"));
2290 jcb.addActionListener(new ActionListener()
2294 public void actionPerformed(ActionEvent e)
2296 // update Cache settings if checkbox is selected
2297 if (jcb.isSelected())
2299 Cache.setProperty("CHECKURLLINKS", "false");
2305 JOptionPane.showMessageDialog(null, msgPanel, MessageManager
2306 .getString("label.SEQUENCE_ID_no_longer_used"),
2307 JOptionPane.WARNING_MESSAGE);
2314 * Proxy class for JDesktopPane which optionally displays the current memory
2315 * usage and highlights the desktop area with a red bar if free memory runs
2320 public class MyDesktopPane extends JDesktopPane implements Runnable
2323 private static final float ONE_MB = 1048576f;
2325 boolean showMemoryUsage = false;
2329 java.text.NumberFormat df;
2331 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2334 public MyDesktopPane(boolean showMemoryUsage)
2336 showMemoryUsage(showMemoryUsage);
2339 public void showMemoryUsage(boolean showMemory)
2341 this.showMemoryUsage = showMemory;
2344 Thread worker = new Thread(this);
2349 public boolean isShowMemoryUsage()
2351 return showMemoryUsage;
2357 df = java.text.NumberFormat.getNumberInstance();
2358 df.setMaximumFractionDigits(2);
2359 runtime = Runtime.getRuntime();
2361 while (showMemoryUsage)
2365 maxMemory = runtime.maxMemory() / ONE_MB;
2366 allocatedMemory = runtime.totalMemory() / ONE_MB;
2367 freeMemory = runtime.freeMemory() / ONE_MB;
2368 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2370 percentUsage = (totalFreeMemory / maxMemory) * 100;
2372 // if (percentUsage < 20)
2374 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2376 // instance.set.setBorder(border1);
2379 // sleep after showing usage
2381 } catch (Exception ex)
2383 ex.printStackTrace();
2389 public void paintComponent(Graphics g)
2391 if (showMemoryUsage && g != null && df != null)
2393 if (percentUsage < 20)
2395 g.setColor(Color.red);
2397 FontMetrics fm = g.getFontMetrics();
2400 g.drawString(MessageManager.formatMessage(
2401 "label.memory_stats",
2402 new Object[] { df.format(totalFreeMemory),
2403 df.format(maxMemory), df.format(percentUsage) }), 10,
2404 getHeight() - fm.getHeight());
2411 * fixes stacking order after a modal dialog to ensure windows that should be
2412 * on top actually are
2414 public void relayerWindows()
2419 protected JMenuItem groovyShell;
2422 * Accessor method to quickly get all the AlignmentFrames loaded.
2424 * @return an array of AlignFrame, or null if none found
2426 public static AlignFrame[] getAlignFrames()
2428 if (Jalview.isHeadlessMode())
2430 // Desktop.desktop is null in headless mode
2431 return new AlignFrame[] { Jalview.currentAlignFrame };
2434 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2440 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2442 for (int i = frames.length - 1; i > -1; i--)
2444 if (frames[i] instanceof AlignFrame)
2446 avp.add((AlignFrame) frames[i]);
2448 else if (frames[i] instanceof SplitFrame)
2451 * Also check for a split frame containing an AlignFrame
2453 GSplitFrame sf = (GSplitFrame) frames[i];
2454 if (sf.getTopFrame() instanceof AlignFrame)
2456 avp.add((AlignFrame) sf.getTopFrame());
2458 if (sf.getBottomFrame() instanceof AlignFrame)
2460 avp.add((AlignFrame) sf.getBottomFrame());
2464 if (avp.size() == 0)
2468 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2473 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2477 public GStructureViewer[] getJmols()
2479 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2485 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2487 for (int i = frames.length - 1; i > -1; i--)
2489 if (frames[i] instanceof AppJmol)
2491 GStructureViewer af = (GStructureViewer) frames[i];
2495 if (avp.size() == 0)
2499 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2504 * Add Groovy Support to Jalview
2506 public void groovyShell_actionPerformed()
2510 openGroovyConsole();
2511 } catch (Exception ex)
2513 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2514 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2516 MessageManager.getString("label.couldnt_create_groovy_shell"),
2517 MessageManager.getString("label.groovy_support_failed"),
2518 JOptionPane.ERROR_MESSAGE);
2523 * Open the Groovy console
2525 void openGroovyConsole()
2527 if (groovyConsole == null)
2529 groovyConsole = new groovy.ui.Console();
2530 groovyConsole.setVariable("Jalview", this);
2531 groovyConsole.run();
2534 * We allow only one console at a time, so that AlignFrame menu option
2535 * 'Calculate | Run Groovy script' is unambiguous.
2536 * Disable 'Groovy Console', and enable 'Run script', when the console is
2537 * opened, and the reverse when it is closed
2539 Window window = (Window) groovyConsole.getFrame();
2540 window.addWindowListener(new WindowAdapter()
2543 public void windowClosed(WindowEvent e)
2546 * rebind CMD-Q from Groovy Console to Jalview Quit
2549 enableExecuteGroovy(false);
2555 * show Groovy console window (after close and reopen)
2557 ((Window) groovyConsole.getFrame()).setVisible(true);
2560 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2561 * and disable opening a second console
2563 enableExecuteGroovy(true);
2567 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2568 * binding when opened
2570 protected void addQuitHandler()
2572 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
2573 KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
2574 .getDefaultToolkit().getMenuShortcutKeyMask()), "Quit");
2575 getRootPane().getActionMap().put("Quit", new AbstractAction()
2578 public void actionPerformed(ActionEvent e)
2586 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2589 * true if Groovy console is open
2591 public void enableExecuteGroovy(boolean enabled)
2594 * disable opening a second Groovy console
2595 * (or re-enable when the console is closed)
2597 groovyShell.setEnabled(!enabled);
2599 AlignFrame[] alignFrames = getAlignFrames();
2600 if (alignFrames != null)
2602 for (AlignFrame af : alignFrames)
2604 af.setGroovyEnabled(enabled);
2610 * Progress bars managed by the IProgressIndicator method.
2612 private Hashtable<Long, JPanel> progressBars;
2614 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2619 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2622 public void setProgressBar(String message, long id)
2624 if (progressBars == null)
2626 progressBars = new Hashtable<Long, JPanel>();
2627 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2630 if (progressBars.get(new Long(id)) != null)
2632 JPanel panel = progressBars.remove(new Long(id));
2633 if (progressBarHandlers.contains(new Long(id)))
2635 progressBarHandlers.remove(new Long(id));
2637 removeProgressPanel(panel);
2641 progressBars.put(new Long(id), addProgressPanel(message));
2648 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2649 * jalview.gui.IProgressIndicatorHandler)
2652 public void registerHandler(final long id,
2653 final IProgressIndicatorHandler handler)
2655 if (progressBarHandlers == null
2656 || !progressBars.containsKey(new Long(id)))
2660 .getString("error.call_setprogressbar_before_registering_handler"));
2662 progressBarHandlers.put(new Long(id), handler);
2663 final JPanel progressPanel = progressBars.get(new Long(id));
2664 if (handler.canCancel())
2666 JButton cancel = new JButton(
2667 MessageManager.getString("action.cancel"));
2668 final IProgressIndicator us = this;
2669 cancel.addActionListener(new ActionListener()
2673 public void actionPerformed(ActionEvent e)
2675 handler.cancelActivity(id);
2676 us.setProgressBar(MessageManager.formatMessage(
2677 "label.cancelled_params",
2678 new Object[] { ((JLabel) progressPanel.getComponent(0))
2682 progressPanel.add(cancel, BorderLayout.EAST);
2688 * @return true if any progress bars are still active
2691 public boolean operationInProgress()
2693 if (progressBars != null && progressBars.size() > 0)
2701 * This will return the first AlignFrame holding the given viewport instance.
2702 * It will break if there are more than one AlignFrames viewing a particular
2706 * @return alignFrame for viewport
2708 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2710 if (desktop != null)
2712 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2713 for (int panel = 0; aps != null && panel < aps.length; panel++)
2715 if (aps[panel] != null && aps[panel].av == viewport)
2717 return aps[panel].alignFrame;
2724 public VamsasApplication getVamsasApplication()
2731 * flag set if jalview GUI is being operated programmatically
2733 private boolean inBatchMode = false;
2736 * check if jalview GUI is being operated programmatically
2738 * @return inBatchMode
2740 public boolean isInBatchMode()
2746 * set flag if jalview GUI is being operated programmatically
2748 * @param inBatchMode
2750 public void setInBatchMode(boolean inBatchMode)
2752 this.inBatchMode = inBatchMode;
2755 public void startServiceDiscovery()
2757 startServiceDiscovery(false);
2760 public void startServiceDiscovery(boolean blocking)
2762 boolean alive = true;
2763 Thread t0 = null, t1 = null, t2 = null;
2764 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2767 // todo: changesupport handlers need to be transferred
2768 if (discoverer == null)
2770 discoverer = new jalview.ws.jws1.Discoverer();
2771 // register PCS handler for desktop.
2772 discoverer.addPropertyChangeListener(changeSupport);
2774 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2775 // until we phase out completely
2776 (t0 = new Thread(discoverer)).start();
2779 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2781 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2783 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2785 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2791 // TODO: do rest service discovery
2800 } catch (Exception e)
2803 alive = (t1 != null && t1.isAlive())
2804 || (t2 != null && t2.isAlive())
2805 || (t3 != null && t3.isAlive())
2806 || (t0 != null && t0.isAlive());
2812 * called to check if the service discovery process completed successfully.
2816 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2818 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2820 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2821 .getErrorMessages();
2824 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2826 if (serviceChangedDialog == null)
2828 // only run if we aren't already displaying one of these.
2829 addDialogThread(serviceChangedDialog = new Runnable()
2836 * JalviewDialog jd =new JalviewDialog() {
2838 * @Override protected void cancelPressed() { // TODO
2839 * Auto-generated method stub
2841 * }@Override protected void okPressed() { // TODO
2842 * Auto-generated method stub
2844 * }@Override protected void raiseClosed() { // TODO
2845 * Auto-generated method stub
2847 * } }; jd.initDialogFrame(new
2848 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2849 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2850 * + " or mis-configured HTTP proxy settings.<br/>" +
2851 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2853 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2854 * ), true, true, "Web Service Configuration Problem", 450,
2857 * jd.waitForInput();
2863 "<html><table width=\"450\"><tr><td>"
2865 + "</td></tr></table>"
2866 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2867 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2868 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2869 + " Tools->Preferences dialog box to change them.</p></html>"),
2870 "Web Service Configuration Problem",
2871 JOptionPane.DEFAULT_OPTION,
2872 JOptionPane.ERROR_MESSAGE);
2873 serviceChangedDialog = null;
2882 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2889 private Runnable serviceChangedDialog = null;
2892 * start a thread to open a URL in the configured browser. Pops up a warning
2893 * dialog to the user if there is an exception when calling out to the browser
2898 public static void showUrl(final String url)
2900 showUrl(url, Desktop.instance);
2904 * Like showUrl but allows progress handler to be specified
2908 * (null) or object implementing IProgressIndicator
2910 public static void showUrl(final String url,
2911 final IProgressIndicator progress)
2913 new Thread(new Runnable()
2920 if (progress != null)
2922 progress.setProgressBar(MessageManager.formatMessage(
2923 "status.opening_params", new Object[] { url }), this
2926 jalview.util.BrowserLauncher.openURL(url);
2927 } catch (Exception ex)
2929 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2931 .getString("label.web_browser_not_found_unix"),
2932 MessageManager.getString("label.web_browser_not_found"),
2933 JOptionPane.WARNING_MESSAGE);
2935 ex.printStackTrace();
2937 if (progress != null)
2939 progress.setProgressBar(null, this.hashCode());
2945 public static WsParamSetManager wsparamManager = null;
2947 public static ParamManager getUserParameterStore()
2949 if (wsparamManager == null)
2951 wsparamManager = new WsParamSetManager();
2953 return wsparamManager;
2957 * static hyperlink handler proxy method for use by Jalview's internal windows
2961 public static void hyperlinkUpdate(HyperlinkEvent e)
2963 if (e.getEventType() == EventType.ACTIVATED)
2968 url = e.getURL().toString();
2969 Desktop.showUrl(url);
2970 } catch (Exception x)
2974 if (Cache.log != null)
2976 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2980 System.err.println("Couldn't handle string " + url
2984 // ignore any exceptions due to dud links.
2991 * single thread that handles display of dialogs to user.
2993 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2996 * flag indicating if dialogExecutor should try to acquire a permit
2998 private volatile boolean dialogPause = true;
3003 private java.util.concurrent.Semaphore block = new Semaphore(0);
3005 private static groovy.ui.Console groovyConsole;
3008 * add another dialog thread to the queue
3012 public void addDialogThread(final Runnable prompter)
3014 dialogExecutor.submit(new Runnable()
3024 } catch (InterruptedException x)
3029 if (instance == null)
3035 SwingUtilities.invokeAndWait(prompter);
3036 } catch (Exception q)
3038 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3044 public void startDialogQueue()
3046 // set the flag so we don't pause waiting for another permit and semaphore
3047 // the current task to begin
3048 dialogPause = false;
3053 protected void snapShotWindow_actionPerformed(ActionEvent e)
3057 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3058 "View of Desktop", getWidth(), getHeight(), of = new File(
3059 "Jalview_snapshot" + System.currentTimeMillis()
3060 + ".eps"), "View of desktop", null, 0, false);
3063 paintAll(im.getGraphics());
3065 } catch (Exception q)
3067 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3071 Cache.log.info("Successfully written snapshot to file "
3072 + of.getAbsolutePath());
3076 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3077 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3078 * and location last time the view was expanded (if any). However it does not
3079 * remember the split pane divider location - this is set to match the
3080 * 'exploding' frame.
3084 public void explodeViews(SplitFrame sf)
3086 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3087 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3088 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3090 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3092 int viewCount = topPanels.size();
3099 * Processing in reverse order works, forwards order leaves the first panels
3100 * not visible. I don't know why!
3102 for (int i = viewCount - 1; i >= 0; i--)
3105 * Make new top and bottom frames. These take over the respective
3106 * AlignmentPanel objects, including their AlignmentViewports, so the
3107 * cdna/protein relationships between the viewports is carried over to the
3110 * explodedGeometry holds the (x, y) position of the previously exploded
3111 * SplitFrame, and the (width, height) of the AlignFrame component
3113 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3114 AlignFrame newTopFrame = new AlignFrame(topPanel);
3115 newTopFrame.setSize(oldTopFrame.getSize());
3116 newTopFrame.setVisible(true);
3117 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3118 .getExplodedGeometry();
3119 if (geometry != null)
3121 newTopFrame.setSize(geometry.getSize());
3124 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3125 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3126 newBottomFrame.setSize(oldBottomFrame.getSize());
3127 newBottomFrame.setVisible(true);
3128 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3129 .getExplodedGeometry();
3130 if (geometry != null)
3132 newBottomFrame.setSize(geometry.getSize());
3135 topPanel.av.setGatherViewsHere(false);
3136 bottomPanel.av.setGatherViewsHere(false);
3137 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3139 if (geometry != null)
3141 splitFrame.setLocation(geometry.getLocation());
3143 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3147 * Clear references to the panels (now relocated in the new SplitFrames)
3148 * before closing the old SplitFrame.
3151 bottomPanels.clear();
3156 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3157 * back into the given SplitFrame as additional views. Note that the gathered
3158 * frames may themselves have multiple views.
3162 public void gatherViews(GSplitFrame source)
3165 * special handling of explodedGeometry for a view within a SplitFrame: - it
3166 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3167 * height) of the AlignFrame component
3169 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3170 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3171 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3172 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3173 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3174 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3176 myTopFrame.viewport.setGatherViewsHere(true);
3177 myBottomFrame.viewport.setGatherViewsHere(true);
3178 String topViewId = myTopFrame.viewport.getSequenceSetId();
3179 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3181 JInternalFrame[] frames = desktop.getAllFrames();
3182 for (JInternalFrame frame : frames)
3184 if (frame instanceof SplitFrame && frame != source)
3186 SplitFrame sf = (SplitFrame) frame;
3187 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3188 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3189 boolean gatherThis = false;
3190 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3192 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3193 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3194 if (topViewId.equals(topPanel.av.getSequenceSetId())
3195 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3198 topPanel.av.setGatherViewsHere(false);
3199 bottomPanel.av.setGatherViewsHere(false);
3200 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3201 topFrame.getSize()));
3202 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3203 .getLocation(), bottomFrame.getSize()));
3204 myTopFrame.addAlignmentPanel(topPanel, false);
3205 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3211 topFrame.getAlignPanels().clear();
3212 bottomFrame.getAlignPanels().clear();
3219 * The dust settles...give focus to the tab we did this from.
3221 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3224 public static groovy.ui.Console getGroovyConsole()
3226 return groovyConsole;
3229 public static void transferFromDropTarget(List<String> files,
3230 List<String> protocols, DropTargetDropEvent evt, Transferable t)
3234 DataFlavor uriListFlavor = new DataFlavor(
3235 "text/uri-list;class=java.lang.String");
3236 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3238 // Works on Windows and MacOSX
3239 Cache.log.debug("Drop handled as javaFileListFlavor");
3240 for (Object file : (List) t
3241 .getTransferData(DataFlavor.javaFileListFlavor))
3243 files.add(((File) file).toString());
3244 protocols.add(FormatAdapter.FILE);
3249 // Unix like behaviour
3250 boolean added = false;
3252 if (t.isDataFlavorSupported(uriListFlavor))
3254 Cache.log.debug("Drop handled as uriListFlavor");
3255 // This is used by Unix drag system
3256 data = (String) t.getTransferData(uriListFlavor);
3260 // fallback to text: workaround - on OSX where there's a JVM bug
3261 Cache.log.debug("standard URIListFlavor failed. Trying text");
3262 // try text fallback
3263 data = (String) t.getTransferData(new DataFlavor(
3264 "text/plain;class=java.lang.String"));
3265 if (Cache.log.isDebugEnabled())
3267 Cache.log.debug("fallback returned " + data);
3270 while (protocols.size() < files.size())
3272 Cache.log.debug("Adding missing FILE protocol for "
3273 + files.get(protocols.size()));
3274 protocols.add(FormatAdapter.FILE);
3276 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3277 data, "\r\n"); st.hasMoreTokens();)
3280 String s = st.nextToken();
3281 if (s.startsWith("#"))
3283 // the line is a comment (as per the RFC 2483)
3286 java.net.URI uri = new java.net.URI(s);
3287 if (uri.getScheme().toLowerCase().startsWith("http"))
3289 protocols.add(FormatAdapter.URL);
3290 files.add(uri.toString());
3294 // otherwise preserve old behaviour: catch all for file objects
3295 java.io.File file = new java.io.File(uri);
3296 protocols.add(FormatAdapter.FILE);
3297 files.add(file.toString());
3300 if (Cache.log.isDebugEnabled())
3302 if (data == null || !added)
3305 .debug("Couldn't resolve drop data. Here are the supported flavors:");
3306 for (DataFlavor fl : t.getTransferDataFlavors())
3308 Cache.log.debug("Supported transfer dataflavor: "
3310 Object df = t.getTransferData(fl);
3313 Cache.log.debug("Retrieves: " + df);
3317 Cache.log.debug("Retrieved nothing");