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 Transferable t = evt.getTransferable();
945 java.util.List<String> files = new ArrayList<String>();
946 java.util.List<String> protocols = new ArrayList<String>();
950 Desktop.transferFromDropTarget(files, protocols, evt, t);
951 } catch (Exception e)
961 for (int i = 0; i < files.size(); i++)
963 String file = files.get(i).toString();
964 String protocol = (protocols == null) ? FormatAdapter.FILE
965 : (String) protocols.get(i);
966 String format = null;
968 if (file.endsWith(".jar"))
975 format = new IdentifyFile().identify(file, protocol);
978 new FileLoader().LoadFile(file, protocol, format);
981 } catch (Exception ex)
986 evt.dropComplete(success); // need this to ensure input focus is properly
987 // transfered to any new windows created
997 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
999 JalviewFileChooser chooser = new JalviewFileChooser(
1000 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1001 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
1002 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
1003 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
1005 chooser.setFileView(new JalviewFileView());
1006 chooser.setDialogTitle(MessageManager
1007 .getString("label.open_local_file"));
1008 chooser.setToolTipText(MessageManager.getString("action.open"));
1010 int value = chooser.showOpenDialog(this);
1012 if (value == JalviewFileChooser.APPROVE_OPTION)
1014 String choice = chooser.getSelectedFile().getPath();
1015 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1016 .getSelectedFile().getParent());
1018 String format = null;
1019 if (chooser.getSelectedFormat() != null
1020 && chooser.getSelectedFormat().equals("Jalview"))
1026 format = new IdentifyFile().identify(choice, FormatAdapter.FILE);
1029 if (viewport != null)
1031 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1036 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1048 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1050 // This construct allows us to have a wider textfield
1052 JLabel label = new JLabel(
1053 MessageManager.getString("label.input_file_url"));
1054 final JComboBox history = new JComboBox();
1056 JPanel panel = new JPanel(new GridLayout(2, 1));
1059 history.setPreferredSize(new Dimension(400, 20));
1060 history.setEditable(true);
1061 history.addItem("http://www.");
1063 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1067 if (historyItems != null)
1069 st = new StringTokenizer(historyItems, "\t");
1071 while (st.hasMoreTokens())
1073 history.addItem(st.nextElement());
1077 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1078 MessageManager.getString("label.input_alignment_from_url"),
1079 JOptionPane.OK_CANCEL_OPTION);
1081 if (reply != JOptionPane.OK_OPTION)
1086 String url = history.getSelectedItem().toString();
1088 if (url.toLowerCase().endsWith(".jar"))
1090 if (viewport != null)
1092 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1097 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1102 String format = new IdentifyFile().identify(url, FormatAdapter.URL);
1104 if (format.equals("URL NOT FOUND"))
1106 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1107 MessageManager.formatMessage("label.couldnt_locate",
1108 new Object[] { url }), MessageManager
1109 .getString("label.url_not_found"),
1110 JOptionPane.WARNING_MESSAGE);
1115 if (viewport != null)
1117 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1121 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1127 * Opens the CutAndPaste window for the user to paste an alignment in to
1130 * - if not null, the pasted alignment is added to the current
1131 * alignment; if null, to a new alignment window
1134 public void inputTextboxMenuItem_actionPerformed(
1135 AlignmentViewPanel viewPanel)
1137 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1138 cap.setForInput(viewPanel);
1139 Desktop.addInternalFrame(cap,
1140 MessageManager.getString("label.cut_paste_alignmen_file"),
1150 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1152 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1153 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1155 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1156 getBounds().y, getWidth(), getHeight()));
1158 if (jconsole != null)
1160 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1161 jconsole.stopConsole();
1165 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1168 if (dialogExecutor != null)
1170 dialogExecutor.shutdownNow();
1172 closeAll_actionPerformed(null);
1174 if (groovyConsole != null)
1176 // suppress a possible repeat prompt to save script
1177 groovyConsole.setDirty(false);
1178 groovyConsole.exit();
1183 private void storeLastKnownDimensions(String string, Rectangle jc)
1185 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1186 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1187 + " height:" + jc.height);
1189 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1190 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1191 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1192 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1202 public void aboutMenuItem_actionPerformed(ActionEvent e)
1204 // StringBuffer message = getAboutMessage(false);
1205 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1207 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1208 new Thread(new Runnable()
1213 new SplashScreen(true);
1218 public StringBuffer getAboutMessage(boolean shortv)
1220 StringBuffer message = new StringBuffer();
1221 message.append("<html>");
1224 message.append("<h1><strong>Version: "
1225 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1226 message.append("<strong>Last Updated: <em>"
1227 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1228 + "</em></strong>");
1234 message.append("<strong>Version "
1235 + jalview.bin.Cache.getProperty("VERSION")
1236 + "; last updated: "
1237 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1240 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1243 message.append("<br>...Checking latest version...</br>");
1245 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1246 .equals(jalview.bin.Cache.getProperty("VERSION")))
1248 boolean red = false;
1249 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1250 .indexOf("automated build") == -1)
1253 // Displayed when code version and jnlp version do not match and code
1254 // version is not a development build
1255 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1258 message.append("<br>!! Version "
1259 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1261 + " is available for download from "
1262 + jalview.bin.Cache.getDefault("www.jalview.org",
1263 "http://www.jalview.org") + " !!");
1266 message.append("</div>");
1269 message.append("<br>Authors: "
1271 .getDefault("AUTHORFNAMES",
1272 "The Jalview Authors (See AUTHORS file for current list)")
1273 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1274 + "<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"
1275 + "<br><br>If you use Jalview, please cite:"
1276 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1277 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1278 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1290 public void documentationMenuItem_actionPerformed(ActionEvent e)
1294 Help.showHelpWindow();
1295 } catch (Exception ex)
1301 public void closeAll_actionPerformed(ActionEvent e)
1303 // TODO show a progress bar while closing?
1304 JInternalFrame[] frames = desktop.getAllFrames();
1305 for (int i = 0; i < frames.length; i++)
1309 frames[i].setClosed(true);
1310 } catch (java.beans.PropertyVetoException ex)
1314 Jalview.setCurrentAlignFrame(null);
1315 System.out.println("ALL CLOSED");
1316 if (v_client != null)
1318 // TODO clear binding to vamsas document objects on close_all
1322 * reset state of singleton objects as appropriate (clear down session state
1323 * when all windows are closed)
1325 StructureSelectionManager ssm = StructureSelectionManager
1326 .getStructureSelectionManager(this);
1335 public void raiseRelated_actionPerformed(ActionEvent e)
1337 reorderAssociatedWindows(false, false);
1341 public void minimizeAssociated_actionPerformed(ActionEvent e)
1343 reorderAssociatedWindows(true, false);
1346 void closeAssociatedWindows()
1348 reorderAssociatedWindows(false, true);
1354 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1358 protected void garbageCollect_actionPerformed(ActionEvent e)
1360 // We simply collect the garbage
1361 jalview.bin.Cache.log.debug("Collecting garbage...");
1363 jalview.bin.Cache.log.debug("Finished garbage collection.");
1370 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1374 protected void showMemusage_actionPerformed(ActionEvent e)
1376 desktop.showMemoryUsage(showMemusage.isSelected());
1383 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1387 protected void showConsole_actionPerformed(ActionEvent e)
1389 showConsole(showConsole.isSelected());
1392 Console jconsole = null;
1395 * control whether the java console is visible or not
1399 void showConsole(boolean selected)
1401 showConsole.setSelected(selected);
1402 // TODO: decide if we should update properties file
1403 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1405 jconsole.setVisible(selected);
1408 void reorderAssociatedWindows(boolean minimize, boolean close)
1410 JInternalFrame[] frames = desktop.getAllFrames();
1411 if (frames == null || frames.length < 1)
1416 AlignmentViewport source = null, target = null;
1417 if (frames[0] instanceof AlignFrame)
1419 source = ((AlignFrame) frames[0]).getCurrentView();
1421 else if (frames[0] instanceof TreePanel)
1423 source = ((TreePanel) frames[0]).getViewPort();
1425 else if (frames[0] instanceof PCAPanel)
1427 source = ((PCAPanel) frames[0]).av;
1429 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1431 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1436 for (int i = 0; i < frames.length; i++)
1439 if (frames[i] == null)
1443 if (frames[i] instanceof AlignFrame)
1445 target = ((AlignFrame) frames[i]).getCurrentView();
1447 else if (frames[i] instanceof TreePanel)
1449 target = ((TreePanel) frames[i]).getViewPort();
1451 else if (frames[i] instanceof PCAPanel)
1453 target = ((PCAPanel) frames[i]).av;
1455 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1457 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1460 if (source == target)
1466 frames[i].setClosed(true);
1470 frames[i].setIcon(minimize);
1473 frames[i].toFront();
1477 } catch (java.beans.PropertyVetoException ex)
1492 protected void preferences_actionPerformed(ActionEvent e)
1504 public void saveState_actionPerformed(ActionEvent e)
1506 JalviewFileChooser chooser = new JalviewFileChooser(
1507 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1508 new String[] { "jvp" }, new String[] { "Jalview Project" },
1511 chooser.setFileView(new JalviewFileView());
1512 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1514 int value = chooser.showSaveDialog(this);
1516 if (value == JalviewFileChooser.APPROVE_OPTION)
1518 final Desktop me = this;
1519 final java.io.File choice = chooser.getSelectedFile();
1520 setProjectFile(choice);
1522 new Thread(new Runnable()
1527 // TODO: refactor to Jalview desktop session controller action.
1528 setProgressBar(MessageManager.formatMessage(
1529 "label.saving_jalview_project",
1530 new Object[] { choice.getName() }), choice.hashCode());
1531 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1532 choice.getParent());
1533 // TODO catch and handle errors for savestate
1534 // TODO prevent user from messing with the Desktop whilst we're saving
1537 new Jalview2XML().saveState(choice);
1538 } catch (OutOfMemoryError oom)
1540 new OOMWarning("Whilst saving current state to "
1541 + choice.getName(), oom);
1542 } catch (Exception ex)
1545 "Problems whilst trying to save to " + choice.getName(),
1547 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1548 "label.error_whilst_saving_current_state_to",
1549 new Object[] { choice.getName() }), MessageManager
1550 .getString("label.couldnt_save_project"),
1551 JOptionPane.WARNING_MESSAGE);
1553 setProgressBar(null, choice.hashCode());
1559 private void setProjectFile(File choice)
1561 this.projectFile = choice;
1564 public File getProjectFile()
1566 return this.projectFile;
1576 public void loadState_actionPerformed(ActionEvent e)
1578 JalviewFileChooser chooser = new JalviewFileChooser(
1579 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1580 "jvp", "jar" }, new String[] { "Jalview Project",
1581 "Jalview Project (old)" }, "Jalview Project");
1582 chooser.setFileView(new JalviewFileView());
1583 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1585 int value = chooser.showOpenDialog(this);
1587 if (value == JalviewFileChooser.APPROVE_OPTION)
1589 final File selectedFile = chooser.getSelectedFile();
1590 setProjectFile(selectedFile);
1591 final String choice = selectedFile.getAbsolutePath();
1592 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1593 selectedFile.getParent());
1594 new Thread(new Runnable()
1600 MessageManager.formatMessage(
1601 "label.loading_jalview_project",
1602 new Object[] { choice }), choice.hashCode());
1605 new Jalview2XML().loadJalviewAlign(choice);
1606 } catch (OutOfMemoryError oom)
1608 new OOMWarning("Whilst loading project from " + choice, oom);
1609 } catch (Exception ex)
1611 Cache.log.error("Problems whilst loading project from "
1613 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1615 "label.error_whilst_loading_project_from",
1616 new Object[] { choice }), MessageManager
1617 .getString("label.couldnt_load_project"),
1618 JOptionPane.WARNING_MESSAGE);
1620 setProgressBar(null, choice.hashCode());
1627 public void inputSequence_actionPerformed(ActionEvent e)
1629 new SequenceFetcher(this);
1632 JPanel progressPanel;
1634 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1636 public void startLoading(final String fileName)
1638 if (fileLoadingCount == 0)
1640 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1641 "label.loading_file", new Object[] { fileName })));
1646 private JPanel addProgressPanel(String string)
1648 if (progressPanel == null)
1650 progressPanel = new JPanel(new GridLayout(1, 1));
1651 totalProgressCount = 0;
1652 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1654 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1655 JProgressBar progressBar = new JProgressBar();
1656 progressBar.setIndeterminate(true);
1658 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1660 thisprogress.add(progressBar, BorderLayout.CENTER);
1661 progressPanel.add(thisprogress);
1662 ((GridLayout) progressPanel.getLayout())
1663 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1664 ++totalProgressCount;
1665 instance.validate();
1666 return thisprogress;
1669 int totalProgressCount = 0;
1671 private void removeProgressPanel(JPanel progbar)
1673 if (progressPanel != null)
1675 synchronized (progressPanel)
1677 progressPanel.remove(progbar);
1678 GridLayout gl = (GridLayout) progressPanel.getLayout();
1679 gl.setRows(gl.getRows() - 1);
1680 if (--totalProgressCount < 1)
1682 this.getContentPane().remove(progressPanel);
1683 progressPanel = null;
1690 public void stopLoading()
1693 if (fileLoadingCount < 1)
1695 while (fileLoadingPanels.size() > 0)
1697 removeProgressPanel(fileLoadingPanels.remove(0));
1699 fileLoadingPanels.clear();
1700 fileLoadingCount = 0;
1705 public static int getViewCount(String alignmentId)
1707 AlignmentViewport[] aps = getViewports(alignmentId);
1708 return (aps == null) ? 0 : aps.length;
1713 * @param alignmentId
1714 * - if null, all sets are returned
1715 * @return all AlignmentPanels concerning the alignmentId sequence set
1717 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1719 if (Desktop.desktop == null)
1721 // no frames created and in headless mode
1722 // TODO: verify that frames are recoverable when in headless mode
1725 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1726 AlignFrame[] frames = getAlignFrames();
1731 for (AlignFrame af : frames)
1733 for (AlignmentPanel ap : af.alignPanels)
1735 if (alignmentId == null
1736 || alignmentId.equals(ap.av.getSequenceSetId()))
1742 if (aps.size() == 0)
1746 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1751 * get all the viewports on an alignment.
1753 * @param sequenceSetId
1754 * unique alignment id (may be null - all viewports returned in that
1756 * @return all viewports on the alignment bound to sequenceSetId
1758 public static AlignmentViewport[] getViewports(String sequenceSetId)
1760 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1761 if (desktop != null)
1763 AlignFrame[] frames = Desktop.getAlignFrames();
1765 for (AlignFrame afr : frames)
1767 if (sequenceSetId == null
1768 || afr.getViewport().getSequenceSetId()
1769 .equals(sequenceSetId))
1771 if (afr.alignPanels != null)
1773 for (AlignmentPanel ap : afr.alignPanels)
1775 if (sequenceSetId == null
1776 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1784 viewp.add(afr.getViewport());
1788 if (viewp.size() > 0)
1790 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1797 * Explode the views in the given frame into separate AlignFrame
1801 public static void explodeViews(AlignFrame af)
1803 int size = af.alignPanels.size();
1809 for (int i = 0; i < size; i++)
1811 AlignmentPanel ap = af.alignPanels.get(i);
1812 AlignFrame newaf = new AlignFrame(ap);
1815 * Restore the view's last exploded frame geometry if known. Multiple
1816 * views from one exploded frame share and restore the same (frame)
1817 * position and size.
1819 Rectangle geometry = ap.av.getExplodedGeometry();
1820 if (geometry != null)
1822 newaf.setBounds(geometry);
1825 ap.av.setGatherViewsHere(false);
1827 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1828 AlignFrame.DEFAULT_HEIGHT);
1831 af.alignPanels.clear();
1832 af.closeMenuItem_actionPerformed(true);
1837 * Gather expanded views (separate AlignFrame's) with the same sequence set
1838 * identifier back in to this frame as additional views, and close the
1839 * expanded views. Note the expanded frames may themselves have multiple
1840 * views. We take the lot.
1844 public void gatherViews(AlignFrame source)
1846 source.viewport.setGatherViewsHere(true);
1847 source.viewport.setExplodedGeometry(source.getBounds());
1848 JInternalFrame[] frames = desktop.getAllFrames();
1849 String viewId = source.viewport.getSequenceSetId();
1851 for (int t = 0; t < frames.length; t++)
1853 if (frames[t] instanceof AlignFrame && frames[t] != source)
1855 AlignFrame af = (AlignFrame) frames[t];
1856 boolean gatherThis = false;
1857 for (int a = 0; a < af.alignPanels.size(); a++)
1859 AlignmentPanel ap = af.alignPanels.get(a);
1860 if (viewId.equals(ap.av.getSequenceSetId()))
1863 ap.av.setGatherViewsHere(false);
1864 ap.av.setExplodedGeometry(af.getBounds());
1865 source.addAlignmentPanel(ap, false);
1871 af.alignPanels.clear();
1872 af.closeMenuItem_actionPerformed(true);
1879 jalview.gui.VamsasApplication v_client = null;
1882 public void vamsasImport_actionPerformed(ActionEvent e)
1884 if (v_client == null)
1886 // Load and try to start a session.
1887 JalviewFileChooser chooser = new JalviewFileChooser(
1888 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1890 chooser.setFileView(new JalviewFileView());
1891 chooser.setDialogTitle(MessageManager
1892 .getString("label.open_saved_vamsas_session"));
1893 chooser.setToolTipText(MessageManager
1894 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1896 int value = chooser.showOpenDialog(this);
1898 if (value == JalviewFileChooser.APPROVE_OPTION)
1900 String fle = chooser.getSelectedFile().toString();
1901 if (!vamsasImport(chooser.getSelectedFile()))
1904 .showInternalMessageDialog(
1906 MessageManager.formatMessage(
1907 "label.couldnt_import_as_vamsas_session",
1908 new Object[] { fle }),
1910 .getString("label.vamsas_document_import_failed"),
1911 JOptionPane.ERROR_MESSAGE);
1917 jalview.bin.Cache.log
1918 .error("Implementation error - load session from a running session is not supported.");
1923 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1926 * @return true if import was a success and a session was started.
1928 public boolean vamsasImport(URL url)
1930 // TODO: create progress bar
1931 if (v_client != null)
1934 jalview.bin.Cache.log
1935 .error("Implementation error - load session from a running session is not supported.");
1941 // copy the URL content to a temporary local file
1942 // TODO: be a bit cleverer here with nio (?!)
1943 File file = File.createTempFile("vdocfromurl", ".vdj");
1944 FileOutputStream fos = new FileOutputStream(file);
1945 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1946 byte[] buffer = new byte[2048];
1948 while ((ln = bis.read(buffer)) > -1)
1950 fos.write(buffer, 0, ln);
1954 v_client = new jalview.gui.VamsasApplication(this, file,
1955 url.toExternalForm());
1956 } catch (Exception ex)
1958 jalview.bin.Cache.log.error(
1959 "Failed to create new vamsas session from contents of URL "
1963 setupVamsasConnectedGui();
1964 v_client.initial_update(); // TODO: thread ?
1965 return v_client.inSession();
1969 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1972 * @return true if import was a success and a session was started.
1974 public boolean vamsasImport(File file)
1976 if (v_client != null)
1979 jalview.bin.Cache.log
1980 .error("Implementation error - load session from a running session is not supported.");
1984 setProgressBar(MessageManager.formatMessage(
1985 "status.importing_vamsas_session_from",
1986 new Object[] { file.getName() }), file.hashCode());
1989 v_client = new jalview.gui.VamsasApplication(this, file, null);
1990 } catch (Exception ex)
1992 setProgressBar(MessageManager.formatMessage(
1993 "status.importing_vamsas_session_from",
1994 new Object[] { file.getName() }), file.hashCode());
1995 jalview.bin.Cache.log.error(
1996 "New vamsas session from existing session file failed:", ex);
1999 setupVamsasConnectedGui();
2000 v_client.initial_update(); // TODO: thread ?
2001 setProgressBar(MessageManager.formatMessage(
2002 "status.importing_vamsas_session_from",
2003 new Object[] { file.getName() }), file.hashCode());
2004 return v_client.inSession();
2007 public boolean joinVamsasSession(String mysesid)
2009 if (v_client != null)
2013 .getString("error.try_join_vamsas_session_another"));
2015 if (mysesid == null)
2018 MessageManager.getString("error.invalid_vamsas_session_id"));
2020 v_client = new VamsasApplication(this, mysesid);
2021 setupVamsasConnectedGui();
2022 v_client.initial_update();
2023 return (v_client.inSession());
2027 public void vamsasStart_actionPerformed(ActionEvent e)
2029 if (v_client == null)
2032 // we just start a default session for moment.
2034 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2035 * getProperty("LAST_DIRECTORY"));
2037 * chooser.setFileView(new JalviewFileView());
2038 * chooser.setDialogTitle("Load Vamsas file");
2039 * chooser.setToolTipText("Import");
2041 * int value = chooser.showOpenDialog(this);
2043 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2044 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2046 v_client = new VamsasApplication(this);
2047 setupVamsasConnectedGui();
2048 v_client.initial_update(); // TODO: thread ?
2052 // store current data in session.
2053 v_client.push_update(); // TODO: thread
2057 protected void setupVamsasConnectedGui()
2059 vamsasStart.setText(MessageManager.getString("label.session_update"));
2060 vamsasSave.setVisible(true);
2061 vamsasStop.setVisible(true);
2062 vamsasImport.setVisible(false); // Document import to existing session is
2063 // not possible for vamsas-client-1.0.
2066 protected void setupVamsasDisconnectedGui()
2068 vamsasSave.setVisible(false);
2069 vamsasStop.setVisible(false);
2070 vamsasImport.setVisible(true);
2071 vamsasStart.setText(MessageManager
2072 .getString("label.new_vamsas_session"));
2076 public void vamsasStop_actionPerformed(ActionEvent e)
2078 if (v_client != null)
2080 v_client.end_session();
2082 setupVamsasDisconnectedGui();
2086 protected void buildVamsasStMenu()
2088 if (v_client == null)
2090 String[] sess = null;
2093 sess = VamsasApplication.getSessionList();
2094 } catch (Exception e)
2096 jalview.bin.Cache.log.warn(
2097 "Problem getting current sessions list.", e);
2102 jalview.bin.Cache.log.debug("Got current sessions list: "
2103 + sess.length + " entries.");
2104 VamsasStMenu.removeAll();
2105 for (int i = 0; i < sess.length; i++)
2107 JMenuItem sessit = new JMenuItem();
2108 sessit.setText(sess[i]);
2109 sessit.setToolTipText(MessageManager.formatMessage(
2110 "label.connect_to_session", new Object[] { sess[i] }));
2111 final Desktop dsktp = this;
2112 final String mysesid = sess[i];
2113 sessit.addActionListener(new ActionListener()
2117 public void actionPerformed(ActionEvent e)
2119 if (dsktp.v_client == null)
2121 Thread rthr = new Thread(new Runnable()
2127 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2128 dsktp.setupVamsasConnectedGui();
2129 dsktp.v_client.initial_update();
2137 VamsasStMenu.add(sessit);
2139 // don't show an empty menu.
2140 VamsasStMenu.setVisible(sess.length > 0);
2145 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2146 VamsasStMenu.removeAll();
2147 VamsasStMenu.setVisible(false);
2152 // Not interested in the content. Just hide ourselves.
2153 VamsasStMenu.setVisible(false);
2158 public void vamsasSave_actionPerformed(ActionEvent e)
2160 if (v_client != null)
2162 JalviewFileChooser chooser = new JalviewFileChooser(
2163 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2164 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2165 new String[] { "Vamsas Document" }, "Vamsas Document");
2167 chooser.setFileView(new JalviewFileView());
2168 chooser.setDialogTitle(MessageManager
2169 .getString("label.save_vamsas_document_archive"));
2171 int value = chooser.showSaveDialog(this);
2173 if (value == JalviewFileChooser.APPROVE_OPTION)
2175 java.io.File choice = chooser.getSelectedFile();
2176 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2177 "label.saving_vamsas_doc",
2178 new Object[] { choice.getName() }));
2179 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2180 String warnmsg = null;
2181 String warnttl = null;
2184 v_client.vclient.storeDocument(choice);
2187 warnttl = "Serious Problem saving Vamsas Document";
2188 warnmsg = ex.toString();
2189 jalview.bin.Cache.log.error("Error Whilst saving document to "
2192 } catch (Exception ex)
2194 warnttl = "Problem saving Vamsas Document.";
2195 warnmsg = ex.toString();
2196 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2200 removeProgressPanel(progpanel);
2201 if (warnmsg != null)
2203 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2205 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2211 JPanel vamUpdate = null;
2214 * hide vamsas user gui bits when a vamsas document event is being handled.
2217 * true to hide gui, false to reveal gui
2219 public void setVamsasUpdate(boolean b)
2221 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2222 + (b ? "in progress" : "finished"));
2224 if (vamUpdate != null)
2226 this.removeProgressPanel(vamUpdate);
2230 vamUpdate = this.addProgressPanel(MessageManager
2231 .getString("label.updating_vamsas_session"));
2233 vamsasStart.setVisible(!b);
2234 vamsasStop.setVisible(!b);
2235 vamsasSave.setVisible(!b);
2238 public JInternalFrame[] getAllFrames()
2240 return desktop.getAllFrames();
2244 * Checks the given url to see if it gives a response indicating that the user
2245 * should be informed of a new questionnaire.
2249 public void checkForQuestionnaire(String url)
2251 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2252 // javax.swing.SwingUtilities.invokeLater(jvq);
2253 new Thread(jvq).start();
2257 * Proxy class for JDesktopPane which optionally displays the current memory
2258 * usage and highlights the desktop area with a red bar if free memory runs
2263 public class MyDesktopPane extends JDesktopPane implements Runnable
2266 private static final float ONE_MB = 1048576f;
2268 boolean showMemoryUsage = false;
2272 java.text.NumberFormat df;
2274 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2277 public MyDesktopPane(boolean showMemoryUsage)
2279 showMemoryUsage(showMemoryUsage);
2282 public void showMemoryUsage(boolean showMemory)
2284 this.showMemoryUsage = showMemory;
2287 Thread worker = new Thread(this);
2292 public boolean isShowMemoryUsage()
2294 return showMemoryUsage;
2300 df = java.text.NumberFormat.getNumberInstance();
2301 df.setMaximumFractionDigits(2);
2302 runtime = Runtime.getRuntime();
2304 while (showMemoryUsage)
2308 maxMemory = runtime.maxMemory() / ONE_MB;
2309 allocatedMemory = runtime.totalMemory() / ONE_MB;
2310 freeMemory = runtime.freeMemory() / ONE_MB;
2311 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2313 percentUsage = (totalFreeMemory / maxMemory) * 100;
2315 // if (percentUsage < 20)
2317 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2319 // instance.set.setBorder(border1);
2322 // sleep after showing usage
2324 } catch (Exception ex)
2326 ex.printStackTrace();
2332 public void paintComponent(Graphics g)
2334 if (showMemoryUsage && g != null && df != null)
2336 if (percentUsage < 20)
2338 g.setColor(Color.red);
2340 FontMetrics fm = g.getFontMetrics();
2343 g.drawString(MessageManager.formatMessage(
2344 "label.memory_stats",
2345 new Object[] { df.format(totalFreeMemory),
2346 df.format(maxMemory), df.format(percentUsage) }), 10,
2347 getHeight() - fm.getHeight());
2354 * fixes stacking order after a modal dialog to ensure windows that should be
2355 * on top actually are
2357 public void relayerWindows()
2362 protected JMenuItem groovyShell;
2365 * Accessor method to quickly get all the AlignmentFrames loaded.
2367 * @return an array of AlignFrame, or null if none found
2369 public static AlignFrame[] getAlignFrames()
2371 if (Jalview.isHeadlessMode())
2373 // Desktop.desktop is null in headless mode
2374 return new AlignFrame[] { Jalview.currentAlignFrame };
2377 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2383 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2385 for (int i = frames.length - 1; i > -1; i--)
2387 if (frames[i] instanceof AlignFrame)
2389 avp.add((AlignFrame) frames[i]);
2391 else if (frames[i] instanceof SplitFrame)
2394 * Also check for a split frame containing an AlignFrame
2396 GSplitFrame sf = (GSplitFrame) frames[i];
2397 if (sf.getTopFrame() instanceof AlignFrame)
2399 avp.add((AlignFrame) sf.getTopFrame());
2401 if (sf.getBottomFrame() instanceof AlignFrame)
2403 avp.add((AlignFrame) sf.getBottomFrame());
2407 if (avp.size() == 0)
2411 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2416 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2420 public GStructureViewer[] getJmols()
2422 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2428 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2430 for (int i = frames.length - 1; i > -1; i--)
2432 if (frames[i] instanceof AppJmol)
2434 GStructureViewer af = (GStructureViewer) frames[i];
2438 if (avp.size() == 0)
2442 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2447 * Add Groovy Support to Jalview
2449 public void groovyShell_actionPerformed()
2453 openGroovyConsole();
2454 } catch (Exception ex)
2456 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2457 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2459 MessageManager.getString("label.couldnt_create_groovy_shell"),
2460 MessageManager.getString("label.groovy_support_failed"),
2461 JOptionPane.ERROR_MESSAGE);
2466 * Open the Groovy console
2468 void openGroovyConsole()
2470 if (groovyConsole == null)
2472 groovyConsole = new groovy.ui.Console();
2473 groovyConsole.setVariable("Jalview", this);
2474 groovyConsole.run();
2477 * We allow only one console at a time, so that AlignFrame menu option
2478 * 'Calculate | Run Groovy script' is unambiguous.
2479 * Disable 'Groovy Console', and enable 'Run script', when the console is
2480 * opened, and the reverse when it is closed
2482 Window window = (Window) groovyConsole.getFrame();
2483 window.addWindowListener(new WindowAdapter()
2486 public void windowClosed(WindowEvent e)
2489 * rebind CMD-Q from Groovy Console to Jalview Quit
2492 enableExecuteGroovy(false);
2498 * show Groovy console window (after close and reopen)
2500 ((Window) groovyConsole.getFrame()).setVisible(true);
2503 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2504 * and disable opening a second console
2506 enableExecuteGroovy(true);
2510 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2511 * binding when opened
2513 protected void addQuitHandler()
2515 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
2516 KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
2517 .getDefaultToolkit().getMenuShortcutKeyMask()),
2519 getRootPane().getActionMap().put("Quit", new AbstractAction()
2522 public void actionPerformed(ActionEvent e)
2530 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2533 * true if Groovy console is open
2535 public void enableExecuteGroovy(boolean enabled)
2538 * disable opening a second Groovy console
2539 * (or re-enable when the console is closed)
2541 groovyShell.setEnabled(!enabled);
2543 AlignFrame[] alignFrames = getAlignFrames();
2544 if (alignFrames != null)
2546 for (AlignFrame af : alignFrames)
2548 af.setGroovyEnabled(enabled);
2554 * Progress bars managed by the IProgressIndicator method.
2556 private Hashtable<Long, JPanel> progressBars;
2558 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2563 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2566 public void setProgressBar(String message, long id)
2568 if (progressBars == null)
2570 progressBars = new Hashtable<Long, JPanel>();
2571 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2574 if (progressBars.get(new Long(id)) != null)
2576 JPanel panel = progressBars.remove(new Long(id));
2577 if (progressBarHandlers.contains(new Long(id)))
2579 progressBarHandlers.remove(new Long(id));
2581 removeProgressPanel(panel);
2585 progressBars.put(new Long(id), addProgressPanel(message));
2592 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2593 * jalview.gui.IProgressIndicatorHandler)
2596 public void registerHandler(final long id,
2597 final IProgressIndicatorHandler handler)
2599 if (progressBarHandlers == null
2600 || !progressBars.containsKey(new Long(id)))
2604 .getString("error.call_setprogressbar_before_registering_handler"));
2606 progressBarHandlers.put(new Long(id), handler);
2607 final JPanel progressPanel = progressBars.get(new Long(id));
2608 if (handler.canCancel())
2610 JButton cancel = new JButton(
2611 MessageManager.getString("action.cancel"));
2612 final IProgressIndicator us = this;
2613 cancel.addActionListener(new ActionListener()
2617 public void actionPerformed(ActionEvent e)
2619 handler.cancelActivity(id);
2620 us.setProgressBar(MessageManager.formatMessage(
2621 "label.cancelled_params",
2622 new Object[] { ((JLabel) progressPanel.getComponent(0))
2626 progressPanel.add(cancel, BorderLayout.EAST);
2632 * @return true if any progress bars are still active
2635 public boolean operationInProgress()
2637 if (progressBars != null && progressBars.size() > 0)
2645 * This will return the first AlignFrame holding the given viewport instance.
2646 * It will break if there are more than one AlignFrames viewing a particular
2650 * @return alignFrame for viewport
2652 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2654 if (desktop != null)
2656 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2657 for (int panel = 0; aps != null && panel < aps.length; panel++)
2659 if (aps[panel] != null && aps[panel].av == viewport)
2661 return aps[panel].alignFrame;
2668 public VamsasApplication getVamsasApplication()
2675 * flag set if jalview GUI is being operated programmatically
2677 private boolean inBatchMode = false;
2680 * check if jalview GUI is being operated programmatically
2682 * @return inBatchMode
2684 public boolean isInBatchMode()
2690 * set flag if jalview GUI is being operated programmatically
2692 * @param inBatchMode
2694 public void setInBatchMode(boolean inBatchMode)
2696 this.inBatchMode = inBatchMode;
2699 public void startServiceDiscovery()
2701 startServiceDiscovery(false);
2704 public void startServiceDiscovery(boolean blocking)
2706 boolean alive = true;
2707 Thread t0 = null, t1 = null, t2 = null;
2708 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2711 // todo: changesupport handlers need to be transferred
2712 if (discoverer == null)
2714 discoverer = new jalview.ws.jws1.Discoverer();
2715 // register PCS handler for desktop.
2716 discoverer.addPropertyChangeListener(changeSupport);
2718 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2719 // until we phase out completely
2720 (t0 = new Thread(discoverer)).start();
2723 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2725 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2727 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2729 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2735 // TODO: do rest service discovery
2744 } catch (Exception e)
2747 alive = (t1 != null && t1.isAlive())
2748 || (t2 != null && t2.isAlive())
2749 || (t3 != null && t3.isAlive())
2750 || (t0 != null && t0.isAlive());
2756 * called to check if the service discovery process completed successfully.
2760 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2762 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2764 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2765 .getErrorMessages();
2768 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2770 if (serviceChangedDialog == null)
2772 // only run if we aren't already displaying one of these.
2773 addDialogThread(serviceChangedDialog = new Runnable()
2780 * JalviewDialog jd =new JalviewDialog() {
2782 * @Override protected void cancelPressed() { // TODO
2783 * Auto-generated method stub
2785 * }@Override protected void okPressed() { // TODO
2786 * Auto-generated method stub
2788 * }@Override protected void raiseClosed() { // TODO
2789 * Auto-generated method stub
2791 * } }; jd.initDialogFrame(new
2792 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2793 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2794 * + " or mis-configured HTTP proxy settings.<br/>" +
2795 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2797 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2798 * ), true, true, "Web Service Configuration Problem", 450,
2801 * jd.waitForInput();
2807 "<html><table width=\"450\"><tr><td>"
2809 + "</td></tr></table>"
2810 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2811 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2812 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2813 + " Tools->Preferences dialog box to change them.</p></html>"),
2814 "Web Service Configuration Problem",
2815 JOptionPane.DEFAULT_OPTION,
2816 JOptionPane.ERROR_MESSAGE);
2817 serviceChangedDialog = null;
2826 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2833 private Runnable serviceChangedDialog = null;
2836 * start a thread to open a URL in the configured browser. Pops up a warning
2837 * dialog to the user if there is an exception when calling out to the browser
2842 public static void showUrl(final String url)
2844 showUrl(url, Desktop.instance);
2848 * Like showUrl but allows progress handler to be specified
2852 * (null) or object implementing IProgressIndicator
2854 public static void showUrl(final String url,
2855 final IProgressIndicator progress)
2857 new Thread(new Runnable()
2864 if (progress != null)
2866 progress.setProgressBar(MessageManager.formatMessage(
2867 "status.opening_params", new Object[] { url }), this
2870 jalview.util.BrowserLauncher.openURL(url);
2871 } catch (Exception ex)
2873 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2875 .getString("label.web_browser_not_found_unix"),
2876 MessageManager.getString("label.web_browser_not_found"),
2877 JOptionPane.WARNING_MESSAGE);
2879 ex.printStackTrace();
2881 if (progress != null)
2883 progress.setProgressBar(null, this.hashCode());
2889 public static WsParamSetManager wsparamManager = null;
2891 public static ParamManager getUserParameterStore()
2893 if (wsparamManager == null)
2895 wsparamManager = new WsParamSetManager();
2897 return wsparamManager;
2901 * static hyperlink handler proxy method for use by Jalview's internal windows
2905 public static void hyperlinkUpdate(HyperlinkEvent e)
2907 if (e.getEventType() == EventType.ACTIVATED)
2912 url = e.getURL().toString();
2913 Desktop.showUrl(url);
2914 } catch (Exception x)
2918 if (Cache.log != null)
2920 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2924 System.err.println("Couldn't handle string " + url
2928 // ignore any exceptions due to dud links.
2935 * single thread that handles display of dialogs to user.
2937 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2940 * flag indicating if dialogExecutor should try to acquire a permit
2942 private volatile boolean dialogPause = true;
2947 private java.util.concurrent.Semaphore block = new Semaphore(0);
2949 private static groovy.ui.Console groovyConsole;
2952 * add another dialog thread to the queue
2956 public void addDialogThread(final Runnable prompter)
2958 dialogExecutor.submit(new Runnable()
2968 } catch (InterruptedException x)
2973 if (instance == null)
2979 SwingUtilities.invokeAndWait(prompter);
2980 } catch (Exception q)
2982 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2988 public void startDialogQueue()
2990 // set the flag so we don't pause waiting for another permit and semaphore
2991 // the current task to begin
2992 dialogPause = false;
2997 protected void snapShotWindow_actionPerformed(ActionEvent e)
3001 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3002 "View of Desktop", getWidth(), getHeight(), of = new File(
3003 "Jalview_snapshot" + System.currentTimeMillis()
3004 + ".eps"), "View of desktop", null, 0, false);
3007 paintAll(im.getGraphics());
3009 } catch (Exception q)
3011 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3015 Cache.log.info("Successfully written snapshot to file "
3016 + of.getAbsolutePath());
3020 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3021 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3022 * and location last time the view was expanded (if any). However it does not
3023 * remember the split pane divider location - this is set to match the
3024 * 'exploding' frame.
3028 public void explodeViews(SplitFrame sf)
3030 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3031 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3032 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3034 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3036 int viewCount = topPanels.size();
3043 * Processing in reverse order works, forwards order leaves the first panels
3044 * not visible. I don't know why!
3046 for (int i = viewCount - 1; i >= 0; i--)
3049 * Make new top and bottom frames. These take over the respective
3050 * AlignmentPanel objects, including their AlignmentViewports, so the
3051 * cdna/protein relationships between the viewports is carried over to the
3054 * explodedGeometry holds the (x, y) position of the previously exploded
3055 * SplitFrame, and the (width, height) of the AlignFrame component
3057 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3058 AlignFrame newTopFrame = new AlignFrame(topPanel);
3059 newTopFrame.setSize(oldTopFrame.getSize());
3060 newTopFrame.setVisible(true);
3061 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3062 .getExplodedGeometry();
3063 if (geometry != null)
3065 newTopFrame.setSize(geometry.getSize());
3068 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3069 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3070 newBottomFrame.setSize(oldBottomFrame.getSize());
3071 newBottomFrame.setVisible(true);
3072 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3073 .getExplodedGeometry();
3074 if (geometry != null)
3076 newBottomFrame.setSize(geometry.getSize());
3079 topPanel.av.setGatherViewsHere(false);
3080 bottomPanel.av.setGatherViewsHere(false);
3081 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3083 if (geometry != null)
3085 splitFrame.setLocation(geometry.getLocation());
3087 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3091 * Clear references to the panels (now relocated in the new SplitFrames)
3092 * before closing the old SplitFrame.
3095 bottomPanels.clear();
3100 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3101 * back into the given SplitFrame as additional views. Note that the gathered
3102 * frames may themselves have multiple views.
3106 public void gatherViews(GSplitFrame source)
3109 * special handling of explodedGeometry for a view within a SplitFrame: - it
3110 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3111 * height) of the AlignFrame component
3113 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3114 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3115 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3116 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3117 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3118 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3120 myTopFrame.viewport.setGatherViewsHere(true);
3121 myBottomFrame.viewport.setGatherViewsHere(true);
3122 String topViewId = myTopFrame.viewport.getSequenceSetId();
3123 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3125 JInternalFrame[] frames = desktop.getAllFrames();
3126 for (JInternalFrame frame : frames)
3128 if (frame instanceof SplitFrame && frame != source)
3130 SplitFrame sf = (SplitFrame) frame;
3131 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3132 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3133 boolean gatherThis = false;
3134 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3136 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3137 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3138 if (topViewId.equals(topPanel.av.getSequenceSetId())
3139 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3142 topPanel.av.setGatherViewsHere(false);
3143 bottomPanel.av.setGatherViewsHere(false);
3144 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3145 topFrame.getSize()));
3146 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3147 .getLocation(), bottomFrame.getSize()));
3148 myTopFrame.addAlignmentPanel(topPanel, false);
3149 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3155 topFrame.getAlignPanels().clear();
3156 bottomFrame.getAlignPanels().clear();
3163 * The dust settles...give focus to the tab we did this from.
3165 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3168 public static groovy.ui.Console getGroovyConsole()
3170 return groovyConsole;
3173 public static void transferFromDropTarget(List<String> files,
3174 List<String> protocols, DropTargetDropEvent evt, Transferable t)
3178 DataFlavor uriListFlavor = new DataFlavor(
3179 "text/uri-list;class=java.lang.String");
3180 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3182 // Works on Windows and MacOSX
3183 Cache.log.debug("Drop handled as javaFileListFlavor");
3184 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3185 for (Object file : (List) t
3186 .getTransferData(DataFlavor.javaFileListFlavor))
3188 files.add(((File)file).toString());
3189 protocols.add(FormatAdapter.FILE);
3194 // Unix like behaviour
3195 boolean added = false;
3197 if (t.isDataFlavorSupported(uriListFlavor))
3199 Cache.log.debug("Drop handled as uriListFlavor");
3200 // This is used by Unix drag system
3201 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
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 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3257 Object df = t.getTransferData(fl);
3260 Cache.log.debug("Retrieves: " + df);
3264 Cache.log.debug("Retrieved nothing");