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.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.KeyStroke;
100 import javax.swing.SwingUtilities;
101 import javax.swing.event.HyperlinkEvent;
102 import javax.swing.event.HyperlinkEvent.EventType;
103 import javax.swing.event.InternalFrameAdapter;
104 import javax.swing.event.InternalFrameEvent;
105 import javax.swing.event.MenuEvent;
106 import javax.swing.event.MenuListener;
113 * @version $Revision: 1.155 $
115 public class Desktop extends jalview.jbgui.GDesktop implements
116 DropTargetListener, ClipboardOwner, IProgressIndicator,
117 jalview.api.StructureSelectionManagerProvider
120 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
123 * news reader - null if it was never started.
125 private BlogReader jvnews = null;
127 private File projectFile;
131 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
133 public void addJalviewPropertyChangeListener(
134 PropertyChangeListener listener)
136 changeSupport.addJalviewPropertyChangeListener(listener);
140 * @param propertyName
142 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
143 * java.beans.PropertyChangeListener)
145 public void addJalviewPropertyChangeListener(String propertyName,
146 PropertyChangeListener listener)
148 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
152 * @param propertyName
154 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
155 * java.beans.PropertyChangeListener)
157 public void removeJalviewPropertyChangeListener(String propertyName,
158 PropertyChangeListener listener)
160 changeSupport.removeJalviewPropertyChangeListener(propertyName,
164 /** Singleton Desktop instance */
165 public static Desktop instance;
167 public static MyDesktopPane desktop;
169 static int openFrameCount = 0;
171 static final int xOffset = 30;
173 static final int yOffset = 30;
175 public static jalview.ws.jws1.Discoverer discoverer;
177 public static Object[] jalviewClipboard;
179 public static boolean internalCopy = false;
181 static int fileLoadingCount = 0;
183 class MyDesktopManager implements DesktopManager
186 private DesktopManager delegate;
188 public MyDesktopManager(DesktopManager delegate)
190 this.delegate = delegate;
194 public void activateFrame(JInternalFrame f)
198 delegate.activateFrame(f);
199 } catch (NullPointerException npe)
201 Point p = getMousePosition();
202 instance.showPasteMenu(p.x, p.y);
207 public void beginDraggingFrame(JComponent f)
209 delegate.beginDraggingFrame(f);
213 public void beginResizingFrame(JComponent f, int direction)
215 delegate.beginResizingFrame(f, direction);
219 public void closeFrame(JInternalFrame f)
221 delegate.closeFrame(f);
225 public void deactivateFrame(JInternalFrame f)
227 delegate.deactivateFrame(f);
231 public void deiconifyFrame(JInternalFrame f)
233 delegate.deiconifyFrame(f);
237 public void dragFrame(JComponent f, int newX, int newY)
243 delegate.dragFrame(f, newX, newY);
247 public void endDraggingFrame(JComponent f)
249 delegate.endDraggingFrame(f);
253 public void endResizingFrame(JComponent f)
255 delegate.endResizingFrame(f);
259 public void iconifyFrame(JInternalFrame f)
261 delegate.iconifyFrame(f);
265 public void maximizeFrame(JInternalFrame f)
267 delegate.maximizeFrame(f);
271 public void minimizeFrame(JInternalFrame f)
273 delegate.minimizeFrame(f);
277 public void openFrame(JInternalFrame f)
279 delegate.openFrame(f);
283 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
290 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
294 public void setBoundsForFrame(JComponent f, int newX, int newY,
295 int newWidth, int newHeight)
297 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
300 // All other methods, simply delegate
305 * Creates a new Desktop object.
310 * A note to implementors. It is ESSENTIAL that any activities that might
311 * block are spawned off as threads rather than waited for during this
315 doVamsasClientCheck();
317 groovyShell = new JMenuItem();
318 groovyShell.setText(MessageManager.getString("label.groovy_console"));
319 groovyShell.addActionListener(new ActionListener()
322 public void actionPerformed(ActionEvent e)
324 groovyShell_actionPerformed();
327 toolsMenu.add(groovyShell);
328 groovyShell.setVisible(true);
330 doConfigureStructurePrefs();
331 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
332 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
333 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
335 boolean showjconsole = jalview.bin.Cache.getDefault(
336 "SHOW_JAVA_CONSOLE", false);
337 desktop = new MyDesktopPane(selmemusage);
338 if (Platform.isAMac())
340 desktop.setDoubleBuffered(false);
342 showMemusage.setSelected(selmemusage);
343 desktop.setBackground(Color.white);
344 getContentPane().setLayout(new BorderLayout());
345 // alternate config - have scrollbars - see notes in JAL-153
346 // JScrollPane sp = new JScrollPane();
347 // sp.getViewport().setView(desktop);
348 // getContentPane().add(sp, BorderLayout.CENTER);
349 getContentPane().add(desktop, BorderLayout.CENTER);
350 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
352 // This line prevents Windows Look&Feel resizing all new windows to maximum
353 // if previous window was maximised
354 desktop.setDesktopManager(new MyDesktopManager(
355 new DefaultDesktopManager()));
357 Rectangle dims = getLastKnownDimensions("");
364 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
365 setBounds((screenSize.width - 900) / 2,
366 (screenSize.height - 650) / 2, 900, 650);
368 jconsole = new Console(this, showjconsole);
369 // add essential build information
370 jconsole.setHeader("Jalview Version: "
371 + jalview.bin.Cache.getProperty("VERSION") + "\n"
372 + "Jalview Installation: "
373 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
374 + "\n" + "Build Date: "
375 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
376 + "Java version: " + System.getProperty("java.version") + "\n"
377 + System.getProperty("os.arch") + " "
378 + System.getProperty("os.name") + " "
379 + System.getProperty("os.version"));
381 showConsole(showjconsole);
383 showNews.setVisible(false);
385 this.addWindowListener(new WindowAdapter()
388 public void windowClosing(WindowEvent evt)
395 this.addMouseListener(ma = new MouseAdapter()
398 public void mousePressed(MouseEvent evt)
400 if (evt.isPopupTrigger()) // Mac
402 showPasteMenu(evt.getX(), evt.getY());
407 public void mouseReleased(MouseEvent evt)
409 if (evt.isPopupTrigger()) // Windows
411 showPasteMenu(evt.getX(), evt.getY());
415 desktop.addMouseListener(ma);
417 this.addFocusListener(new FocusListener()
421 public void focusLost(FocusEvent e)
423 // TODO Auto-generated method stub
428 public void focusGained(FocusEvent e)
430 Cache.log.debug("Relaying windows after focus gain");
431 // make sure that we sort windows properly after we gain focus
432 instance.relayerWindows();
435 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
436 // Spawn a thread that shows the splashscreen
437 SwingUtilities.invokeLater(new Runnable()
447 // Thread off a new instance of the file chooser - this reduces the time it
448 // takes to open it later on.
449 new Thread(new Runnable()
454 Cache.log.debug("Filechooser init thread started.");
455 new JalviewFileChooser(
456 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
457 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
458 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
459 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
460 Cache.log.debug("Filechooser init thread finished.");
463 // Add the service change listener
464 changeSupport.addJalviewPropertyChangeListener("services",
465 new PropertyChangeListener()
469 public void propertyChange(PropertyChangeEvent evt)
471 Cache.log.debug("Firing service changed event for "
472 + evt.getNewValue());
473 JalviewServicesChanged(evt);
479 public void doConfigureStructurePrefs()
481 // configure services
482 StructureSelectionManager ssm = StructureSelectionManager
483 .getStructureSelectionManager(this);
484 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
486 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
487 Preferences.ADD_TEMPFACT_ANN, true));
488 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
489 Preferences.STRUCT_FROM_PDB, true));
490 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
491 Preferences.USE_RNAVIEW, true));
495 ssm.setAddTempFacAnnot(false);
496 ssm.setProcessSecondaryStructure(false);
497 ssm.setSecStructServices(false);
501 public void checkForNews()
503 final Desktop me = this;
504 // Thread off the news reader, in case there are connection problems.
505 addDialogThread(new Runnable()
510 Cache.log.debug("Starting news thread.");
512 jvnews = new BlogReader(me);
513 showNews.setVisible(true);
514 Cache.log.debug("Completed news thread.");
520 protected void showNews_actionPerformed(ActionEvent e)
522 showNews(showNews.isSelected());
525 void showNews(boolean visible)
528 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
529 showNews.setSelected(visible);
530 if (visible && !jvnews.isVisible())
532 new Thread(new Runnable()
537 long now = System.currentTimeMillis();
538 Desktop.instance.setProgressBar(
539 MessageManager.getString("status.refreshing_news"), now);
540 jvnews.refreshNews();
541 Desktop.instance.setProgressBar(null, now);
550 * recover the last known dimensions for a jalview window
553 * - empty string is desktop, all other windows have unique prefix
554 * @return null or last known dimensions scaled to current geometry (if last
555 * window geom was known)
557 Rectangle getLastKnownDimensions(String windowName)
559 // TODO: lock aspect ratio for scaling desktop Bug #0058199
560 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
561 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
562 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
563 String width = jalview.bin.Cache.getProperty(windowName
565 String height = jalview.bin.Cache.getProperty(windowName
567 if ((x != null) && (y != null) && (width != null) && (height != null))
569 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
570 .parseInt(width), ih = Integer.parseInt(height);
571 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
573 // attempt #1 - try to cope with change in screen geometry - this
574 // version doesn't preserve original jv aspect ratio.
575 // take ratio of current screen size vs original screen size.
576 double sw = ((1f * screenSize.width) / (1f * Integer
577 .parseInt(jalview.bin.Cache
578 .getProperty("SCREENGEOMETRY_WIDTH"))));
579 double sh = ((1f * screenSize.height) / (1f * Integer
580 .parseInt(jalview.bin.Cache
581 .getProperty("SCREENGEOMETRY_HEIGHT"))));
582 // rescale the bounds depending upon the current screen geometry.
583 ix = (int) (ix * sw);
584 iw = (int) (iw * sw);
585 iy = (int) (iy * sh);
586 ih = (int) (ih * sh);
587 while (ix >= screenSize.width)
589 jalview.bin.Cache.log
590 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
591 ix -= screenSize.width;
593 while (iy >= screenSize.height)
595 jalview.bin.Cache.log
596 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
597 iy -= screenSize.height;
599 jalview.bin.Cache.log.debug("Got last known dimensions for "
600 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
603 // return dimensions for new instance
604 return new Rectangle(ix, iy, iw, ih);
609 private void doVamsasClientCheck()
611 if (jalview.bin.Cache.vamsasJarsPresent())
613 setupVamsasDisconnectedGui();
614 VamsasMenu.setVisible(true);
615 final Desktop us = this;
616 VamsasMenu.addMenuListener(new MenuListener()
618 // this listener remembers when the menu was first selected, and
619 // doesn't rebuild the session list until it has been cleared and
621 boolean refresh = true;
624 public void menuCanceled(MenuEvent e)
630 public void menuDeselected(MenuEvent e)
636 public void menuSelected(MenuEvent e)
640 us.buildVamsasStMenu();
645 vamsasStart.setVisible(true);
649 void showPasteMenu(int x, int y)
651 JPopupMenu popup = new JPopupMenu();
652 JMenuItem item = new JMenuItem(
653 MessageManager.getString("label.paste_new_window"));
654 item.addActionListener(new ActionListener()
657 public void actionPerformed(ActionEvent evt)
664 popup.show(this, x, y);
671 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
672 Transferable contents = c.getContents(this);
674 if (contents != null)
676 String file = (String) contents
677 .getTransferData(DataFlavor.stringFlavor);
679 String format = new IdentifyFile().identify(file,
680 FormatAdapter.PASTE);
682 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
685 } catch (Exception ex)
688 .println("Unable to paste alignment from system clipboard:\n"
694 * Adds and opens the given frame to the desktop
705 public static synchronized void addInternalFrame(
706 final JInternalFrame frame, String title, int w, int h)
708 addInternalFrame(frame, title, true, w, h, true);
712 * Add an internal frame to the Jalview desktop
719 * When true, display frame immediately, otherwise, caller must call
720 * setVisible themselves.
726 public static synchronized void addInternalFrame(
727 final JInternalFrame frame, String title, boolean makeVisible,
730 addInternalFrame(frame, title, makeVisible, w, h, true);
734 * Add an internal frame to the Jalview desktop and make it visible
747 public static synchronized void addInternalFrame(
748 final JInternalFrame frame, String title, int w, int h,
751 addInternalFrame(frame, title, true, w, h, resizable);
755 * Add an internal frame to the Jalview desktop
762 * When true, display frame immediately, otherwise, caller must call
763 * setVisible themselves.
771 public static synchronized void addInternalFrame(
772 final JInternalFrame frame, String title, boolean makeVisible,
773 int w, int h, boolean resizable)
776 // TODO: allow callers to determine X and Y position of frame (eg. via
778 // TODO: consider fixing method to update entries in the window submenu with
779 // the current window title
781 frame.setTitle(title);
782 if (frame.getWidth() < 1 || frame.getHeight() < 1)
786 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
787 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
788 // IF JALVIEW IS RUNNING HEADLESS
789 // ///////////////////////////////////////////////
791 || (System.getProperty("java.awt.headless") != null && System
792 .getProperty("java.awt.headless").equals("true")))
799 frame.setVisible(makeVisible);
800 frame.setClosable(true);
801 frame.setResizable(resizable);
802 frame.setMaximizable(resizable);
803 frame.setIconifiable(resizable);
804 if (Platform.isAMac())
806 frame.setIconifiable(false);
807 frame.setFrameIcon(null);
808 // frame.setDesktopIcon(null);
809 frame.setDoubleBuffered(false);
811 if (frame.getX() < 1 && frame.getY() < 1)
813 frame.setLocation(xOffset * openFrameCount, yOffset
814 * ((openFrameCount - 1) % 10) + yOffset);
818 * add an entry for the new frame in the Window menu
819 * (and remove it when the frame is closed)
821 final JMenuItem menuItem = new JMenuItem(title);
822 frame.addInternalFrameListener(new InternalFrameAdapter()
825 public void internalFrameActivated(InternalFrameEvent evt)
827 JInternalFrame itf = desktop.getSelectedFrame();
835 public void internalFrameClosed(InternalFrameEvent evt)
837 PaintRefresher.RemoveComponent(frame);
840 * defensive check to prevent frames being
841 * added half off the window
843 if (openFrameCount > 0)
849 * ensure no reference to alignFrame retained by menu item listener
851 if (menuItem.getActionListeners().length > 0)
853 menuItem.removeActionListener(menuItem.getActionListeners()[0]);
855 windowMenu.remove(menuItem);
856 JInternalFrame itf = desktop.getSelectedFrame();
860 if (itf instanceof AlignFrame)
862 Jalview.setCurrentAlignFrame((AlignFrame) itf);
869 menuItem.addActionListener(new ActionListener()
872 public void actionPerformed(ActionEvent e)
876 frame.setSelected(true);
877 frame.setIcon(false);
878 } catch (java.beans.PropertyVetoException ex)
885 windowMenu.add(menuItem);
891 frame.setSelected(true);
892 frame.requestFocus();
893 } catch (java.beans.PropertyVetoException ve)
895 } catch (java.lang.ClassCastException cex)
898 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
904 public void lostOwnership(Clipboard clipboard, Transferable contents)
908 Desktop.jalviewClipboard = null;
911 internalCopy = false;
915 public void dragEnter(DropTargetDragEvent evt)
920 public void dragExit(DropTargetEvent evt)
925 public void dragOver(DropTargetDragEvent evt)
930 public void dropActionChanged(DropTargetDragEvent evt)
941 public void drop(DropTargetDropEvent evt)
943 boolean success = true;
944 // JAL-1552 - acceptDrop required before getTransferable call for
945 // Java's Transferable for native dnd
946 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
947 Transferable t = evt.getTransferable();
948 java.util.List<String> files = new ArrayList<String>();
949 java.util.List<String> protocols = new ArrayList<String>();
953 Desktop.transferFromDropTarget(files, protocols, evt, t);
954 } catch (Exception e)
964 for (int i = 0; i < files.size(); i++)
966 String file = files.get(i).toString();
967 String protocol = (protocols == null) ? FormatAdapter.FILE
968 : (String) protocols.get(i);
969 String format = null;
971 if (file.endsWith(".jar"))
978 format = new IdentifyFile().identify(file, protocol);
981 new FileLoader().LoadFile(file, protocol, format);
984 } catch (Exception ex)
989 evt.dropComplete(success); // need this to ensure input focus is properly
990 // transfered to any new windows created
1000 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1002 JalviewFileChooser chooser = new JalviewFileChooser(
1003 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1004 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1005 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1006 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1008 chooser.setFileView(new JalviewFileView());
1009 chooser.setDialogTitle(MessageManager
1010 .getString("label.open_local_file"));
1011 chooser.setToolTipText(MessageManager.getString("action.open"));
1013 int value = chooser.showOpenDialog(this);
1015 if (value == JalviewFileChooser.APPROVE_OPTION)
1017 String choice = chooser.getSelectedFile().getPath();
1018 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1019 .getSelectedFile().getParent());
1021 String format = null;
1022 if (chooser.getSelectedFormat() != null
1023 && chooser.getSelectedFormat().equals("Jalview"))
1029 format = new IdentifyFile().identify(choice, FormatAdapter.FILE);
1032 if (viewport != null)
1034 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1039 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1051 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1053 // This construct allows us to have a wider textfield
1055 JLabel label = new JLabel(
1056 MessageManager.getString("label.input_file_url"));
1057 final JComboBox history = new JComboBox();
1059 JPanel panel = new JPanel(new GridLayout(2, 1));
1062 history.setPreferredSize(new Dimension(400, 20));
1063 history.setEditable(true);
1064 history.addItem("http://www.");
1066 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1070 if (historyItems != null)
1072 st = new StringTokenizer(historyItems, "\t");
1074 while (st.hasMoreTokens())
1076 history.addItem(st.nextElement());
1080 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1081 MessageManager.getString("label.input_alignment_from_url"),
1082 JOptionPane.OK_CANCEL_OPTION);
1084 if (reply != JOptionPane.OK_OPTION)
1089 String url = history.getSelectedItem().toString();
1091 if (url.toLowerCase().endsWith(".jar"))
1093 if (viewport != null)
1095 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1100 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1105 String format = new IdentifyFile().identify(url, FormatAdapter.URL);
1107 if (format.equals("URL NOT FOUND"))
1109 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1110 MessageManager.formatMessage("label.couldnt_locate",
1111 new Object[] { url }), MessageManager
1112 .getString("label.url_not_found"),
1113 JOptionPane.WARNING_MESSAGE);
1118 if (viewport != null)
1120 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1124 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1130 * Opens the CutAndPaste window for the user to paste an alignment in to
1133 * - if not null, the pasted alignment is added to the current
1134 * alignment; if null, to a new alignment window
1137 public void inputTextboxMenuItem_actionPerformed(
1138 AlignmentViewPanel viewPanel)
1140 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1141 cap.setForInput(viewPanel);
1142 Desktop.addInternalFrame(cap,
1143 MessageManager.getString("label.cut_paste_alignmen_file"),
1153 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1155 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1156 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1158 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1159 getBounds().y, getWidth(), getHeight()));
1161 if (jconsole != null)
1163 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1164 jconsole.stopConsole();
1168 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1171 if (dialogExecutor != null)
1173 dialogExecutor.shutdownNow();
1175 closeAll_actionPerformed(null);
1177 if (groovyConsole != null)
1179 // suppress a possible repeat prompt to save script
1180 groovyConsole.setDirty(false);
1181 groovyConsole.exit();
1186 private void storeLastKnownDimensions(String string, Rectangle jc)
1188 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1189 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1190 + " height:" + jc.height);
1192 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1193 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1194 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1195 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1205 public void aboutMenuItem_actionPerformed(ActionEvent e)
1207 // StringBuffer message = getAboutMessage(false);
1208 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1210 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1211 new Thread(new Runnable()
1216 new SplashScreen(true);
1221 public StringBuffer getAboutMessage(boolean shortv)
1223 StringBuffer message = new StringBuffer();
1224 message.append("<html>");
1227 message.append("<h1><strong>Version: "
1228 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1229 message.append("<strong>Last Updated: <em>"
1230 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1231 + "</em></strong>");
1237 message.append("<strong>Version "
1238 + jalview.bin.Cache.getProperty("VERSION")
1239 + "; last updated: "
1240 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1243 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1246 message.append("<br>...Checking latest version...</br>");
1248 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1249 .equals(jalview.bin.Cache.getProperty("VERSION")))
1251 boolean red = false;
1252 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1253 .indexOf("automated build") == -1)
1256 // Displayed when code version and jnlp version do not match and code
1257 // version is not a development build
1258 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1261 message.append("<br>!! Version "
1262 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1264 + " is available for download from "
1265 + jalview.bin.Cache.getDefault("www.jalview.org",
1266 "http://www.jalview.org") + " !!");
1269 message.append("</div>");
1272 message.append("<br>Authors: "
1274 .getDefault("AUTHORFNAMES",
1275 "The Jalview Authors (See AUTHORS file for current list)")
1276 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1277 + "<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"
1278 + "<br><br>If you use Jalview, please cite:"
1279 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1280 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1281 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1293 public void documentationMenuItem_actionPerformed(ActionEvent e)
1297 Help.showHelpWindow();
1298 } catch (Exception ex)
1304 public void closeAll_actionPerformed(ActionEvent e)
1306 // TODO show a progress bar while closing?
1307 JInternalFrame[] frames = desktop.getAllFrames();
1308 for (int i = 0; i < frames.length; i++)
1312 frames[i].setClosed(true);
1313 } catch (java.beans.PropertyVetoException ex)
1317 Jalview.setCurrentAlignFrame(null);
1318 System.out.println("ALL CLOSED");
1319 if (v_client != null)
1321 // TODO clear binding to vamsas document objects on close_all
1325 * reset state of singleton objects as appropriate (clear down session state
1326 * when all windows are closed)
1328 StructureSelectionManager ssm = StructureSelectionManager
1329 .getStructureSelectionManager(this);
1338 public void raiseRelated_actionPerformed(ActionEvent e)
1340 reorderAssociatedWindows(false, false);
1344 public void minimizeAssociated_actionPerformed(ActionEvent e)
1346 reorderAssociatedWindows(true, false);
1349 void closeAssociatedWindows()
1351 reorderAssociatedWindows(false, true);
1357 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1361 protected void garbageCollect_actionPerformed(ActionEvent e)
1363 // We simply collect the garbage
1364 jalview.bin.Cache.log.debug("Collecting garbage...");
1366 jalview.bin.Cache.log.debug("Finished garbage collection.");
1373 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1377 protected void showMemusage_actionPerformed(ActionEvent e)
1379 desktop.showMemoryUsage(showMemusage.isSelected());
1386 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1390 protected void showConsole_actionPerformed(ActionEvent e)
1392 showConsole(showConsole.isSelected());
1395 Console jconsole = null;
1398 * control whether the java console is visible or not
1402 void showConsole(boolean selected)
1404 showConsole.setSelected(selected);
1405 // TODO: decide if we should update properties file
1406 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1408 jconsole.setVisible(selected);
1411 void reorderAssociatedWindows(boolean minimize, boolean close)
1413 JInternalFrame[] frames = desktop.getAllFrames();
1414 if (frames == null || frames.length < 1)
1419 AlignmentViewport source = null, target = null;
1420 if (frames[0] instanceof AlignFrame)
1422 source = ((AlignFrame) frames[0]).getCurrentView();
1424 else if (frames[0] instanceof TreePanel)
1426 source = ((TreePanel) frames[0]).getViewPort();
1428 else if (frames[0] instanceof PCAPanel)
1430 source = ((PCAPanel) frames[0]).av;
1432 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1434 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1439 for (int i = 0; i < frames.length; i++)
1442 if (frames[i] == null)
1446 if (frames[i] instanceof AlignFrame)
1448 target = ((AlignFrame) frames[i]).getCurrentView();
1450 else if (frames[i] instanceof TreePanel)
1452 target = ((TreePanel) frames[i]).getViewPort();
1454 else if (frames[i] instanceof PCAPanel)
1456 target = ((PCAPanel) frames[i]).av;
1458 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1460 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1463 if (source == target)
1469 frames[i].setClosed(true);
1473 frames[i].setIcon(minimize);
1476 frames[i].toFront();
1480 } catch (java.beans.PropertyVetoException ex)
1495 protected void preferences_actionPerformed(ActionEvent e)
1507 public void saveState_actionPerformed(ActionEvent e)
1509 JalviewFileChooser chooser = new JalviewFileChooser(
1510 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1511 new String[] { "jvp" }, new String[] { "Jalview Project" },
1514 chooser.setFileView(new JalviewFileView());
1515 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1517 int value = chooser.showSaveDialog(this);
1519 if (value == JalviewFileChooser.APPROVE_OPTION)
1521 final Desktop me = this;
1522 final java.io.File choice = chooser.getSelectedFile();
1523 setProjectFile(choice);
1525 new Thread(new Runnable()
1530 // TODO: refactor to Jalview desktop session controller action.
1531 setProgressBar(MessageManager.formatMessage(
1532 "label.saving_jalview_project",
1533 new Object[] { choice.getName() }), choice.hashCode());
1534 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1535 choice.getParent());
1536 // TODO catch and handle errors for savestate
1537 // TODO prevent user from messing with the Desktop whilst we're saving
1540 new Jalview2XML().saveState(choice);
1541 } catch (OutOfMemoryError oom)
1543 new OOMWarning("Whilst saving current state to "
1544 + choice.getName(), oom);
1545 } catch (Exception ex)
1548 "Problems whilst trying to save to " + choice.getName(),
1550 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1551 "label.error_whilst_saving_current_state_to",
1552 new Object[] { choice.getName() }), MessageManager
1553 .getString("label.couldnt_save_project"),
1554 JOptionPane.WARNING_MESSAGE);
1556 setProgressBar(null, choice.hashCode());
1562 private void setProjectFile(File choice)
1564 this.projectFile = choice;
1567 public File getProjectFile()
1569 return this.projectFile;
1579 public void loadState_actionPerformed(ActionEvent e)
1581 JalviewFileChooser chooser = new JalviewFileChooser(
1582 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1583 "jvp", "jar" }, new String[] { "Jalview Project",
1584 "Jalview Project (old)" }, "Jalview Project");
1585 chooser.setFileView(new JalviewFileView());
1586 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1588 int value = chooser.showOpenDialog(this);
1590 if (value == JalviewFileChooser.APPROVE_OPTION)
1592 final File selectedFile = chooser.getSelectedFile();
1593 setProjectFile(selectedFile);
1594 final String choice = selectedFile.getAbsolutePath();
1595 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1596 selectedFile.getParent());
1597 new Thread(new Runnable()
1603 MessageManager.formatMessage(
1604 "label.loading_jalview_project",
1605 new Object[] { choice }), choice.hashCode());
1608 new Jalview2XML().loadJalviewAlign(choice);
1609 } catch (OutOfMemoryError oom)
1611 new OOMWarning("Whilst loading project from " + choice, oom);
1612 } catch (Exception ex)
1614 Cache.log.error("Problems whilst loading project from "
1616 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1618 "label.error_whilst_loading_project_from",
1619 new Object[] { choice }), MessageManager
1620 .getString("label.couldnt_load_project"),
1621 JOptionPane.WARNING_MESSAGE);
1623 setProgressBar(null, choice.hashCode());
1630 public void inputSequence_actionPerformed(ActionEvent e)
1632 new SequenceFetcher(this);
1635 JPanel progressPanel;
1637 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1639 public void startLoading(final String fileName)
1641 if (fileLoadingCount == 0)
1643 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1644 "label.loading_file", new Object[] { fileName })));
1649 private JPanel addProgressPanel(String string)
1651 if (progressPanel == null)
1653 progressPanel = new JPanel(new GridLayout(1, 1));
1654 totalProgressCount = 0;
1655 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1657 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1658 JProgressBar progressBar = new JProgressBar();
1659 progressBar.setIndeterminate(true);
1661 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1663 thisprogress.add(progressBar, BorderLayout.CENTER);
1664 progressPanel.add(thisprogress);
1665 ((GridLayout) progressPanel.getLayout())
1666 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1667 ++totalProgressCount;
1668 instance.validate();
1669 return thisprogress;
1672 int totalProgressCount = 0;
1674 private void removeProgressPanel(JPanel progbar)
1676 if (progressPanel != null)
1678 synchronized (progressPanel)
1680 progressPanel.remove(progbar);
1681 GridLayout gl = (GridLayout) progressPanel.getLayout();
1682 gl.setRows(gl.getRows() - 1);
1683 if (--totalProgressCount < 1)
1685 this.getContentPane().remove(progressPanel);
1686 progressPanel = null;
1693 public void stopLoading()
1696 if (fileLoadingCount < 1)
1698 while (fileLoadingPanels.size() > 0)
1700 removeProgressPanel(fileLoadingPanels.remove(0));
1702 fileLoadingPanels.clear();
1703 fileLoadingCount = 0;
1708 public static int getViewCount(String alignmentId)
1710 AlignmentViewport[] aps = getViewports(alignmentId);
1711 return (aps == null) ? 0 : aps.length;
1716 * @param alignmentId
1717 * - if null, all sets are returned
1718 * @return all AlignmentPanels concerning the alignmentId sequence set
1720 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1722 if (Desktop.desktop == null)
1724 // no frames created and in headless mode
1725 // TODO: verify that frames are recoverable when in headless mode
1728 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1729 AlignFrame[] frames = getAlignFrames();
1734 for (AlignFrame af : frames)
1736 for (AlignmentPanel ap : af.alignPanels)
1738 if (alignmentId == null
1739 || alignmentId.equals(ap.av.getSequenceSetId()))
1745 if (aps.size() == 0)
1749 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1754 * get all the viewports on an alignment.
1756 * @param sequenceSetId
1757 * unique alignment id (may be null - all viewports returned in that
1759 * @return all viewports on the alignment bound to sequenceSetId
1761 public static AlignmentViewport[] getViewports(String sequenceSetId)
1763 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1764 if (desktop != null)
1766 AlignFrame[] frames = Desktop.getAlignFrames();
1768 for (AlignFrame afr : frames)
1770 if (sequenceSetId == null
1771 || afr.getViewport().getSequenceSetId()
1772 .equals(sequenceSetId))
1774 if (afr.alignPanels != null)
1776 for (AlignmentPanel ap : afr.alignPanels)
1778 if (sequenceSetId == null
1779 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1787 viewp.add(afr.getViewport());
1791 if (viewp.size() > 0)
1793 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1800 * Explode the views in the given frame into separate AlignFrame
1804 public static void explodeViews(AlignFrame af)
1806 int size = af.alignPanels.size();
1812 for (int i = 0; i < size; i++)
1814 AlignmentPanel ap = af.alignPanels.get(i);
1815 AlignFrame newaf = new AlignFrame(ap);
1818 * Restore the view's last exploded frame geometry if known. Multiple
1819 * views from one exploded frame share and restore the same (frame)
1820 * position and size.
1822 Rectangle geometry = ap.av.getExplodedGeometry();
1823 if (geometry != null)
1825 newaf.setBounds(geometry);
1828 ap.av.setGatherViewsHere(false);
1830 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1831 AlignFrame.DEFAULT_HEIGHT);
1834 af.alignPanels.clear();
1835 af.closeMenuItem_actionPerformed(true);
1840 * Gather expanded views (separate AlignFrame's) with the same sequence set
1841 * identifier back in to this frame as additional views, and close the
1842 * expanded views. Note the expanded frames may themselves have multiple
1843 * views. We take the lot.
1847 public void gatherViews(AlignFrame source)
1849 source.viewport.setGatherViewsHere(true);
1850 source.viewport.setExplodedGeometry(source.getBounds());
1851 JInternalFrame[] frames = desktop.getAllFrames();
1852 String viewId = source.viewport.getSequenceSetId();
1854 for (int t = 0; t < frames.length; t++)
1856 if (frames[t] instanceof AlignFrame && frames[t] != source)
1858 AlignFrame af = (AlignFrame) frames[t];
1859 boolean gatherThis = false;
1860 for (int a = 0; a < af.alignPanels.size(); a++)
1862 AlignmentPanel ap = af.alignPanels.get(a);
1863 if (viewId.equals(ap.av.getSequenceSetId()))
1866 ap.av.setGatherViewsHere(false);
1867 ap.av.setExplodedGeometry(af.getBounds());
1868 source.addAlignmentPanel(ap, false);
1874 af.alignPanels.clear();
1875 af.closeMenuItem_actionPerformed(true);
1882 jalview.gui.VamsasApplication v_client = null;
1885 public void vamsasImport_actionPerformed(ActionEvent e)
1887 if (v_client == null)
1889 // Load and try to start a session.
1890 JalviewFileChooser chooser = new JalviewFileChooser(
1891 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1893 chooser.setFileView(new JalviewFileView());
1894 chooser.setDialogTitle(MessageManager
1895 .getString("label.open_saved_vamsas_session"));
1896 chooser.setToolTipText(MessageManager
1897 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1899 int value = chooser.showOpenDialog(this);
1901 if (value == JalviewFileChooser.APPROVE_OPTION)
1903 String fle = chooser.getSelectedFile().toString();
1904 if (!vamsasImport(chooser.getSelectedFile()))
1907 .showInternalMessageDialog(
1909 MessageManager.formatMessage(
1910 "label.couldnt_import_as_vamsas_session",
1911 new Object[] { fle }),
1913 .getString("label.vamsas_document_import_failed"),
1914 JOptionPane.ERROR_MESSAGE);
1920 jalview.bin.Cache.log
1921 .error("Implementation error - load session from a running session is not supported.");
1926 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1929 * @return true if import was a success and a session was started.
1931 public boolean vamsasImport(URL url)
1933 // TODO: create progress bar
1934 if (v_client != null)
1937 jalview.bin.Cache.log
1938 .error("Implementation error - load session from a running session is not supported.");
1944 // copy the URL content to a temporary local file
1945 // TODO: be a bit cleverer here with nio (?!)
1946 File file = File.createTempFile("vdocfromurl", ".vdj");
1947 FileOutputStream fos = new FileOutputStream(file);
1948 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1949 byte[] buffer = new byte[2048];
1951 while ((ln = bis.read(buffer)) > -1)
1953 fos.write(buffer, 0, ln);
1957 v_client = new jalview.gui.VamsasApplication(this, file,
1958 url.toExternalForm());
1959 } catch (Exception ex)
1961 jalview.bin.Cache.log.error(
1962 "Failed to create new vamsas session from contents of URL "
1966 setupVamsasConnectedGui();
1967 v_client.initial_update(); // TODO: thread ?
1968 return v_client.inSession();
1972 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1975 * @return true if import was a success and a session was started.
1977 public boolean vamsasImport(File file)
1979 if (v_client != null)
1982 jalview.bin.Cache.log
1983 .error("Implementation error - load session from a running session is not supported.");
1987 setProgressBar(MessageManager.formatMessage(
1988 "status.importing_vamsas_session_from",
1989 new Object[] { file.getName() }), file.hashCode());
1992 v_client = new jalview.gui.VamsasApplication(this, file, null);
1993 } catch (Exception ex)
1995 setProgressBar(MessageManager.formatMessage(
1996 "status.importing_vamsas_session_from",
1997 new Object[] { file.getName() }), file.hashCode());
1998 jalview.bin.Cache.log.error(
1999 "New vamsas session from existing session file failed:", ex);
2002 setupVamsasConnectedGui();
2003 v_client.initial_update(); // TODO: thread ?
2004 setProgressBar(MessageManager.formatMessage(
2005 "status.importing_vamsas_session_from",
2006 new Object[] { file.getName() }), file.hashCode());
2007 return v_client.inSession();
2010 public boolean joinVamsasSession(String mysesid)
2012 if (v_client != null)
2016 .getString("error.try_join_vamsas_session_another"));
2018 if (mysesid == null)
2021 MessageManager.getString("error.invalid_vamsas_session_id"));
2023 v_client = new VamsasApplication(this, mysesid);
2024 setupVamsasConnectedGui();
2025 v_client.initial_update();
2026 return (v_client.inSession());
2030 public void vamsasStart_actionPerformed(ActionEvent e)
2032 if (v_client == null)
2035 // we just start a default session for moment.
2037 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2038 * getProperty("LAST_DIRECTORY"));
2040 * chooser.setFileView(new JalviewFileView());
2041 * chooser.setDialogTitle("Load Vamsas file");
2042 * chooser.setToolTipText("Import");
2044 * int value = chooser.showOpenDialog(this);
2046 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2047 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2049 v_client = new VamsasApplication(this);
2050 setupVamsasConnectedGui();
2051 v_client.initial_update(); // TODO: thread ?
2055 // store current data in session.
2056 v_client.push_update(); // TODO: thread
2060 protected void setupVamsasConnectedGui()
2062 vamsasStart.setText(MessageManager.getString("label.session_update"));
2063 vamsasSave.setVisible(true);
2064 vamsasStop.setVisible(true);
2065 vamsasImport.setVisible(false); // Document import to existing session is
2066 // not possible for vamsas-client-1.0.
2069 protected void setupVamsasDisconnectedGui()
2071 vamsasSave.setVisible(false);
2072 vamsasStop.setVisible(false);
2073 vamsasImport.setVisible(true);
2074 vamsasStart.setText(MessageManager
2075 .getString("label.new_vamsas_session"));
2079 public void vamsasStop_actionPerformed(ActionEvent e)
2081 if (v_client != null)
2083 v_client.end_session();
2085 setupVamsasDisconnectedGui();
2089 protected void buildVamsasStMenu()
2091 if (v_client == null)
2093 String[] sess = null;
2096 sess = VamsasApplication.getSessionList();
2097 } catch (Exception e)
2099 jalview.bin.Cache.log.warn(
2100 "Problem getting current sessions list.", e);
2105 jalview.bin.Cache.log.debug("Got current sessions list: "
2106 + sess.length + " entries.");
2107 VamsasStMenu.removeAll();
2108 for (int i = 0; i < sess.length; i++)
2110 JMenuItem sessit = new JMenuItem();
2111 sessit.setText(sess[i]);
2112 sessit.setToolTipText(MessageManager.formatMessage(
2113 "label.connect_to_session", new Object[] { sess[i] }));
2114 final Desktop dsktp = this;
2115 final String mysesid = sess[i];
2116 sessit.addActionListener(new ActionListener()
2120 public void actionPerformed(ActionEvent e)
2122 if (dsktp.v_client == null)
2124 Thread rthr = new Thread(new Runnable()
2130 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2131 dsktp.setupVamsasConnectedGui();
2132 dsktp.v_client.initial_update();
2140 VamsasStMenu.add(sessit);
2142 // don't show an empty menu.
2143 VamsasStMenu.setVisible(sess.length > 0);
2148 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2149 VamsasStMenu.removeAll();
2150 VamsasStMenu.setVisible(false);
2155 // Not interested in the content. Just hide ourselves.
2156 VamsasStMenu.setVisible(false);
2161 public void vamsasSave_actionPerformed(ActionEvent e)
2163 if (v_client != null)
2165 JalviewFileChooser chooser = new JalviewFileChooser(
2166 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2167 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2168 new String[] { "Vamsas Document" }, "Vamsas Document");
2170 chooser.setFileView(new JalviewFileView());
2171 chooser.setDialogTitle(MessageManager
2172 .getString("label.save_vamsas_document_archive"));
2174 int value = chooser.showSaveDialog(this);
2176 if (value == JalviewFileChooser.APPROVE_OPTION)
2178 java.io.File choice = chooser.getSelectedFile();
2179 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2180 "label.saving_vamsas_doc",
2181 new Object[] { choice.getName() }));
2182 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2183 String warnmsg = null;
2184 String warnttl = null;
2187 v_client.vclient.storeDocument(choice);
2190 warnttl = "Serious Problem saving Vamsas Document";
2191 warnmsg = ex.toString();
2192 jalview.bin.Cache.log.error("Error Whilst saving document to "
2195 } catch (Exception ex)
2197 warnttl = "Problem saving Vamsas Document.";
2198 warnmsg = ex.toString();
2199 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2203 removeProgressPanel(progpanel);
2204 if (warnmsg != null)
2206 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2208 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2214 JPanel vamUpdate = null;
2217 * hide vamsas user gui bits when a vamsas document event is being handled.
2220 * true to hide gui, false to reveal gui
2222 public void setVamsasUpdate(boolean b)
2224 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2225 + (b ? "in progress" : "finished"));
2227 if (vamUpdate != null)
2229 this.removeProgressPanel(vamUpdate);
2233 vamUpdate = this.addProgressPanel(MessageManager
2234 .getString("label.updating_vamsas_session"));
2236 vamsasStart.setVisible(!b);
2237 vamsasStop.setVisible(!b);
2238 vamsasSave.setVisible(!b);
2241 public JInternalFrame[] getAllFrames()
2243 return desktop.getAllFrames();
2247 * Checks the given url to see if it gives a response indicating that the user
2248 * should be informed of a new questionnaire.
2252 public void checkForQuestionnaire(String url)
2254 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2255 // javax.swing.SwingUtilities.invokeLater(jvq);
2256 new Thread(jvq).start();
2260 * Proxy class for JDesktopPane which optionally displays the current memory
2261 * usage and highlights the desktop area with a red bar if free memory runs
2266 public class MyDesktopPane extends JDesktopPane implements Runnable
2269 private static final float ONE_MB = 1048576f;
2271 boolean showMemoryUsage = false;
2275 java.text.NumberFormat df;
2277 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2280 public MyDesktopPane(boolean showMemoryUsage)
2282 showMemoryUsage(showMemoryUsage);
2285 public void showMemoryUsage(boolean showMemory)
2287 this.showMemoryUsage = showMemory;
2290 Thread worker = new Thread(this);
2295 public boolean isShowMemoryUsage()
2297 return showMemoryUsage;
2303 df = java.text.NumberFormat.getNumberInstance();
2304 df.setMaximumFractionDigits(2);
2305 runtime = Runtime.getRuntime();
2307 while (showMemoryUsage)
2311 maxMemory = runtime.maxMemory() / ONE_MB;
2312 allocatedMemory = runtime.totalMemory() / ONE_MB;
2313 freeMemory = runtime.freeMemory() / ONE_MB;
2314 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2316 percentUsage = (totalFreeMemory / maxMemory) * 100;
2318 // if (percentUsage < 20)
2320 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2322 // instance.set.setBorder(border1);
2325 // sleep after showing usage
2327 } catch (Exception ex)
2329 ex.printStackTrace();
2335 public void paintComponent(Graphics g)
2337 if (showMemoryUsage && g != null && df != null)
2339 if (percentUsage < 20)
2341 g.setColor(Color.red);
2343 FontMetrics fm = g.getFontMetrics();
2346 g.drawString(MessageManager.formatMessage(
2347 "label.memory_stats",
2348 new Object[] { df.format(totalFreeMemory),
2349 df.format(maxMemory), df.format(percentUsage) }), 10,
2350 getHeight() - fm.getHeight());
2357 * fixes stacking order after a modal dialog to ensure windows that should be
2358 * on top actually are
2360 public void relayerWindows()
2365 protected JMenuItem groovyShell;
2368 * Accessor method to quickly get all the AlignmentFrames loaded.
2370 * @return an array of AlignFrame, or null if none found
2372 public static AlignFrame[] getAlignFrames()
2374 if (Jalview.isHeadlessMode())
2376 // Desktop.desktop is null in headless mode
2377 return new AlignFrame[] { Jalview.currentAlignFrame };
2380 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2386 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2388 for (int i = frames.length - 1; i > -1; i--)
2390 if (frames[i] instanceof AlignFrame)
2392 avp.add((AlignFrame) frames[i]);
2394 else if (frames[i] instanceof SplitFrame)
2397 * Also check for a split frame containing an AlignFrame
2399 GSplitFrame sf = (GSplitFrame) frames[i];
2400 if (sf.getTopFrame() instanceof AlignFrame)
2402 avp.add((AlignFrame) sf.getTopFrame());
2404 if (sf.getBottomFrame() instanceof AlignFrame)
2406 avp.add((AlignFrame) sf.getBottomFrame());
2410 if (avp.size() == 0)
2414 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2419 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2423 public GStructureViewer[] getJmols()
2425 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2431 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2433 for (int i = frames.length - 1; i > -1; i--)
2435 if (frames[i] instanceof AppJmol)
2437 GStructureViewer af = (GStructureViewer) frames[i];
2441 if (avp.size() == 0)
2445 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2450 * Add Groovy Support to Jalview
2452 public void groovyShell_actionPerformed()
2456 openGroovyConsole();
2457 } catch (Exception ex)
2459 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2460 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2462 MessageManager.getString("label.couldnt_create_groovy_shell"),
2463 MessageManager.getString("label.groovy_support_failed"),
2464 JOptionPane.ERROR_MESSAGE);
2469 * Open the Groovy console
2471 void openGroovyConsole()
2473 if (groovyConsole == null)
2475 groovyConsole = new groovy.ui.Console();
2476 groovyConsole.setVariable("Jalview", this);
2477 groovyConsole.run();
2480 * We allow only one console at a time, so that AlignFrame menu option
2481 * 'Calculate | Run Groovy script' is unambiguous.
2482 * Disable 'Groovy Console', and enable 'Run script', when the console is
2483 * opened, and the reverse when it is closed
2485 Window window = (Window) groovyConsole.getFrame();
2486 window.addWindowListener(new WindowAdapter()
2489 public void windowClosed(WindowEvent e)
2492 * rebind CMD-Q from Groovy Console to Jalview Quit
2495 enableExecuteGroovy(false);
2501 * show Groovy console window (after close and reopen)
2503 ((Window) groovyConsole.getFrame()).setVisible(true);
2506 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2507 * and disable opening a second console
2509 enableExecuteGroovy(true);
2513 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2514 * binding when opened
2516 protected void addQuitHandler()
2518 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
2519 KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
2520 .getDefaultToolkit().getMenuShortcutKeyMask()), "Quit");
2521 getRootPane().getActionMap().put("Quit", new AbstractAction()
2524 public void actionPerformed(ActionEvent e)
2532 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2535 * true if Groovy console is open
2537 public void enableExecuteGroovy(boolean enabled)
2540 * disable opening a second Groovy console
2541 * (or re-enable when the console is closed)
2543 groovyShell.setEnabled(!enabled);
2545 AlignFrame[] alignFrames = getAlignFrames();
2546 if (alignFrames != null)
2548 for (AlignFrame af : alignFrames)
2550 af.setGroovyEnabled(enabled);
2556 * Progress bars managed by the IProgressIndicator method.
2558 private Hashtable<Long, JPanel> progressBars;
2560 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2565 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2568 public void setProgressBar(String message, long id)
2570 if (progressBars == null)
2572 progressBars = new Hashtable<Long, JPanel>();
2573 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2576 if (progressBars.get(new Long(id)) != null)
2578 JPanel panel = progressBars.remove(new Long(id));
2579 if (progressBarHandlers.contains(new Long(id)))
2581 progressBarHandlers.remove(new Long(id));
2583 removeProgressPanel(panel);
2587 progressBars.put(new Long(id), addProgressPanel(message));
2594 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2595 * jalview.gui.IProgressIndicatorHandler)
2598 public void registerHandler(final long id,
2599 final IProgressIndicatorHandler handler)
2601 if (progressBarHandlers == null
2602 || !progressBars.containsKey(new Long(id)))
2606 .getString("error.call_setprogressbar_before_registering_handler"));
2608 progressBarHandlers.put(new Long(id), handler);
2609 final JPanel progressPanel = progressBars.get(new Long(id));
2610 if (handler.canCancel())
2612 JButton cancel = new JButton(
2613 MessageManager.getString("action.cancel"));
2614 final IProgressIndicator us = this;
2615 cancel.addActionListener(new ActionListener()
2619 public void actionPerformed(ActionEvent e)
2621 handler.cancelActivity(id);
2622 us.setProgressBar(MessageManager.formatMessage(
2623 "label.cancelled_params",
2624 new Object[] { ((JLabel) progressPanel.getComponent(0))
2628 progressPanel.add(cancel, BorderLayout.EAST);
2634 * @return true if any progress bars are still active
2637 public boolean operationInProgress()
2639 if (progressBars != null && progressBars.size() > 0)
2647 * This will return the first AlignFrame holding the given viewport instance.
2648 * It will break if there are more than one AlignFrames viewing a particular
2652 * @return alignFrame for viewport
2654 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2656 if (desktop != null)
2658 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2659 for (int panel = 0; aps != null && panel < aps.length; panel++)
2661 if (aps[panel] != null && aps[panel].av == viewport)
2663 return aps[panel].alignFrame;
2670 public VamsasApplication getVamsasApplication()
2677 * flag set if jalview GUI is being operated programmatically
2679 private boolean inBatchMode = false;
2682 * check if jalview GUI is being operated programmatically
2684 * @return inBatchMode
2686 public boolean isInBatchMode()
2692 * set flag if jalview GUI is being operated programmatically
2694 * @param inBatchMode
2696 public void setInBatchMode(boolean inBatchMode)
2698 this.inBatchMode = inBatchMode;
2701 public void startServiceDiscovery()
2703 startServiceDiscovery(false);
2706 public void startServiceDiscovery(boolean blocking)
2708 boolean alive = true;
2709 Thread t0 = null, t1 = null, t2 = null;
2710 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2713 // todo: changesupport handlers need to be transferred
2714 if (discoverer == null)
2716 discoverer = new jalview.ws.jws1.Discoverer();
2717 // register PCS handler for desktop.
2718 discoverer.addPropertyChangeListener(changeSupport);
2720 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2721 // until we phase out completely
2722 (t0 = new Thread(discoverer)).start();
2725 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2727 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2729 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2731 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2737 // TODO: do rest service discovery
2746 } catch (Exception e)
2749 alive = (t1 != null && t1.isAlive())
2750 || (t2 != null && t2.isAlive())
2751 || (t3 != null && t3.isAlive())
2752 || (t0 != null && t0.isAlive());
2758 * called to check if the service discovery process completed successfully.
2762 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2764 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2766 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2767 .getErrorMessages();
2770 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2772 if (serviceChangedDialog == null)
2774 // only run if we aren't already displaying one of these.
2775 addDialogThread(serviceChangedDialog = new Runnable()
2782 * JalviewDialog jd =new JalviewDialog() {
2784 * @Override protected void cancelPressed() { // TODO
2785 * Auto-generated method stub
2787 * }@Override protected void okPressed() { // TODO
2788 * Auto-generated method stub
2790 * }@Override protected void raiseClosed() { // TODO
2791 * Auto-generated method stub
2793 * } }; jd.initDialogFrame(new
2794 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2795 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2796 * + " or mis-configured HTTP proxy settings.<br/>" +
2797 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2799 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2800 * ), true, true, "Web Service Configuration Problem", 450,
2803 * jd.waitForInput();
2809 "<html><table width=\"450\"><tr><td>"
2811 + "</td></tr></table>"
2812 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2813 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2814 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2815 + " Tools->Preferences dialog box to change them.</p></html>"),
2816 "Web Service Configuration Problem",
2817 JOptionPane.DEFAULT_OPTION,
2818 JOptionPane.ERROR_MESSAGE);
2819 serviceChangedDialog = null;
2828 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2835 private Runnable serviceChangedDialog = null;
2838 * start a thread to open a URL in the configured browser. Pops up a warning
2839 * dialog to the user if there is an exception when calling out to the browser
2844 public static void showUrl(final String url)
2846 showUrl(url, Desktop.instance);
2850 * Like showUrl but allows progress handler to be specified
2854 * (null) or object implementing IProgressIndicator
2856 public static void showUrl(final String url,
2857 final IProgressIndicator progress)
2859 new Thread(new Runnable()
2866 if (progress != null)
2868 progress.setProgressBar(MessageManager.formatMessage(
2869 "status.opening_params", new Object[] { url }), this
2872 jalview.util.BrowserLauncher.openURL(url);
2873 } catch (Exception ex)
2875 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2877 .getString("label.web_browser_not_found_unix"),
2878 MessageManager.getString("label.web_browser_not_found"),
2879 JOptionPane.WARNING_MESSAGE);
2881 ex.printStackTrace();
2883 if (progress != null)
2885 progress.setProgressBar(null, this.hashCode());
2891 public static WsParamSetManager wsparamManager = null;
2893 public static ParamManager getUserParameterStore()
2895 if (wsparamManager == null)
2897 wsparamManager = new WsParamSetManager();
2899 return wsparamManager;
2903 * static hyperlink handler proxy method for use by Jalview's internal windows
2907 public static void hyperlinkUpdate(HyperlinkEvent e)
2909 if (e.getEventType() == EventType.ACTIVATED)
2914 url = e.getURL().toString();
2915 Desktop.showUrl(url);
2916 } catch (Exception x)
2920 if (Cache.log != null)
2922 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2926 System.err.println("Couldn't handle string " + url
2930 // ignore any exceptions due to dud links.
2937 * single thread that handles display of dialogs to user.
2939 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2942 * flag indicating if dialogExecutor should try to acquire a permit
2944 private volatile boolean dialogPause = true;
2949 private java.util.concurrent.Semaphore block = new Semaphore(0);
2951 private static groovy.ui.Console groovyConsole;
2954 * add another dialog thread to the queue
2958 public void addDialogThread(final Runnable prompter)
2960 dialogExecutor.submit(new Runnable()
2970 } catch (InterruptedException x)
2975 if (instance == null)
2981 SwingUtilities.invokeAndWait(prompter);
2982 } catch (Exception q)
2984 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2990 public void startDialogQueue()
2992 // set the flag so we don't pause waiting for another permit and semaphore
2993 // the current task to begin
2994 dialogPause = false;
2999 protected void snapShotWindow_actionPerformed(ActionEvent e)
3003 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3004 "View of Desktop", getWidth(), getHeight(), of = new File(
3005 "Jalview_snapshot" + System.currentTimeMillis()
3006 + ".eps"), "View of desktop", null, 0, false);
3009 paintAll(im.getGraphics());
3011 } catch (Exception q)
3013 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3017 Cache.log.info("Successfully written snapshot to file "
3018 + of.getAbsolutePath());
3022 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3023 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3024 * and location last time the view was expanded (if any). However it does not
3025 * remember the split pane divider location - this is set to match the
3026 * 'exploding' frame.
3030 public void explodeViews(SplitFrame sf)
3032 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3033 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3034 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3036 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3038 int viewCount = topPanels.size();
3045 * Processing in reverse order works, forwards order leaves the first panels
3046 * not visible. I don't know why!
3048 for (int i = viewCount - 1; i >= 0; i--)
3051 * Make new top and bottom frames. These take over the respective
3052 * AlignmentPanel objects, including their AlignmentViewports, so the
3053 * cdna/protein relationships between the viewports is carried over to the
3056 * explodedGeometry holds the (x, y) position of the previously exploded
3057 * SplitFrame, and the (width, height) of the AlignFrame component
3059 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3060 AlignFrame newTopFrame = new AlignFrame(topPanel);
3061 newTopFrame.setSize(oldTopFrame.getSize());
3062 newTopFrame.setVisible(true);
3063 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3064 .getExplodedGeometry();
3065 if (geometry != null)
3067 newTopFrame.setSize(geometry.getSize());
3070 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3071 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3072 newBottomFrame.setSize(oldBottomFrame.getSize());
3073 newBottomFrame.setVisible(true);
3074 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3075 .getExplodedGeometry();
3076 if (geometry != null)
3078 newBottomFrame.setSize(geometry.getSize());
3081 topPanel.av.setGatherViewsHere(false);
3082 bottomPanel.av.setGatherViewsHere(false);
3083 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3085 if (geometry != null)
3087 splitFrame.setLocation(geometry.getLocation());
3089 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3093 * Clear references to the panels (now relocated in the new SplitFrames)
3094 * before closing the old SplitFrame.
3097 bottomPanels.clear();
3102 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3103 * back into the given SplitFrame as additional views. Note that the gathered
3104 * frames may themselves have multiple views.
3108 public void gatherViews(GSplitFrame source)
3111 * special handling of explodedGeometry for a view within a SplitFrame: - it
3112 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3113 * height) of the AlignFrame component
3115 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3116 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3117 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3118 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3119 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3120 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3122 myTopFrame.viewport.setGatherViewsHere(true);
3123 myBottomFrame.viewport.setGatherViewsHere(true);
3124 String topViewId = myTopFrame.viewport.getSequenceSetId();
3125 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3127 JInternalFrame[] frames = desktop.getAllFrames();
3128 for (JInternalFrame frame : frames)
3130 if (frame instanceof SplitFrame && frame != source)
3132 SplitFrame sf = (SplitFrame) frame;
3133 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3134 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3135 boolean gatherThis = false;
3136 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3138 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3139 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3140 if (topViewId.equals(topPanel.av.getSequenceSetId())
3141 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3144 topPanel.av.setGatherViewsHere(false);
3145 bottomPanel.av.setGatherViewsHere(false);
3146 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3147 topFrame.getSize()));
3148 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3149 .getLocation(), bottomFrame.getSize()));
3150 myTopFrame.addAlignmentPanel(topPanel, false);
3151 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3157 topFrame.getAlignPanels().clear();
3158 bottomFrame.getAlignPanels().clear();
3165 * The dust settles...give focus to the tab we did this from.
3167 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3170 public static groovy.ui.Console getGroovyConsole()
3172 return groovyConsole;
3175 public static void transferFromDropTarget(List<String> files,
3176 List<String> protocols, DropTargetDropEvent evt, Transferable t)
3180 DataFlavor uriListFlavor = new DataFlavor(
3181 "text/uri-list;class=java.lang.String");
3182 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3184 // Works on Windows and MacOSX
3185 Cache.log.debug("Drop handled as javaFileListFlavor");
3186 for (Object file : (List) t
3187 .getTransferData(DataFlavor.javaFileListFlavor))
3189 files.add(((File) file).toString());
3190 protocols.add(FormatAdapter.FILE);
3195 // Unix like behaviour
3196 boolean added = false;
3198 if (t.isDataFlavorSupported(uriListFlavor))
3200 Cache.log.debug("Drop handled as uriListFlavor");
3201 // This is used by Unix drag system
3202 data = (String) t.getTransferData(uriListFlavor);
3206 // fallback to text: workaround - on OSX where there's a JVM bug
3207 Cache.log.debug("standard URIListFlavor failed. Trying text");
3208 // try text fallback
3209 data = (String) t.getTransferData(new DataFlavor(
3210 "text/plain;class=java.lang.String"));
3211 if (Cache.log.isDebugEnabled())
3213 Cache.log.debug("fallback returned " + data);
3216 while (protocols.size() < files.size())
3218 Cache.log.debug("Adding missing FILE protocol for "
3219 + files.get(protocols.size()));
3220 protocols.add(FormatAdapter.FILE);
3222 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3223 data, "\r\n"); st.hasMoreTokens();)
3226 String s = st.nextToken();
3227 if (s.startsWith("#"))
3229 // the line is a comment (as per the RFC 2483)
3232 java.net.URI uri = new java.net.URI(s);
3233 if (uri.getScheme().toLowerCase().startsWith("http"))
3235 protocols.add(FormatAdapter.URL);
3236 files.add(uri.toString());
3240 // otherwise preserve old behaviour: catch all for file objects
3241 java.io.File file = new java.io.File(uri);
3242 protocols.add(FormatAdapter.FILE);
3243 files.add(file.toString());
3246 if (Cache.log.isDebugEnabled())
3248 if (data == null || !added)
3251 .debug("Couldn't resolve drop data. Here are the supported flavors:");
3252 for (DataFlavor fl : t.getTransferDataFlavors())
3254 Cache.log.debug("Supported transfer dataflavor: "
3256 Object df = t.getTransferData(fl);
3259 Cache.log.debug("Retrieves: " + df);
3263 Cache.log.debug("Retrieved nothing");