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.AppletFormatAdapter;
28 import jalview.io.DataSourceType;
29 import jalview.io.FileFormat;
30 import jalview.io.FileFormatException;
31 import jalview.io.FileFormatI;
32 import jalview.io.FileLoader;
33 import jalview.io.IdentifyFile;
34 import jalview.io.JalviewFileChooser;
35 import jalview.io.JalviewFileView;
36 import jalview.jbgui.GSplitFrame;
37 import jalview.jbgui.GStructureViewer;
38 import jalview.structure.StructureSelectionManager;
39 import jalview.util.ImageMaker;
40 import jalview.util.MessageManager;
41 import jalview.util.Platform;
42 import jalview.viewmodel.AlignmentViewport;
43 import jalview.ws.params.ParamManager;
45 import java.awt.BorderLayout;
46 import java.awt.Color;
47 import java.awt.Dimension;
48 import java.awt.FontMetrics;
49 import java.awt.Graphics;
50 import java.awt.GridLayout;
51 import java.awt.Point;
52 import java.awt.Rectangle;
53 import java.awt.Toolkit;
54 import java.awt.Window;
55 import java.awt.datatransfer.Clipboard;
56 import java.awt.datatransfer.ClipboardOwner;
57 import java.awt.datatransfer.DataFlavor;
58 import java.awt.datatransfer.Transferable;
59 import java.awt.dnd.DnDConstants;
60 import java.awt.dnd.DropTargetDragEvent;
61 import java.awt.dnd.DropTargetDropEvent;
62 import java.awt.dnd.DropTargetEvent;
63 import java.awt.dnd.DropTargetListener;
64 import java.awt.event.ActionEvent;
65 import java.awt.event.ActionListener;
66 import java.awt.event.FocusEvent;
67 import java.awt.event.FocusListener;
68 import java.awt.event.KeyEvent;
69 import java.awt.event.MouseAdapter;
70 import java.awt.event.MouseEvent;
71 import java.awt.event.MouseListener;
72 import java.awt.event.WindowAdapter;
73 import java.awt.event.WindowEvent;
74 import java.beans.PropertyChangeEvent;
75 import java.beans.PropertyChangeListener;
76 import java.beans.PropertyVetoException;
77 import java.io.BufferedInputStream;
79 import java.io.FileOutputStream;
81 import java.util.ArrayList;
82 import java.util.Hashtable;
83 import java.util.List;
84 import java.util.StringTokenizer;
85 import java.util.Vector;
86 import java.util.concurrent.ExecutorService;
87 import java.util.concurrent.Executors;
88 import java.util.concurrent.Semaphore;
90 import javax.swing.AbstractAction;
91 import javax.swing.DefaultDesktopManager;
92 import javax.swing.DesktopManager;
93 import javax.swing.JButton;
94 import javax.swing.JComboBox;
95 import javax.swing.JComponent;
96 import javax.swing.JDesktopPane;
97 import javax.swing.JFrame;
98 import javax.swing.JInternalFrame;
99 import javax.swing.JLabel;
100 import javax.swing.JMenuItem;
101 import javax.swing.JOptionPane;
102 import javax.swing.JPanel;
103 import javax.swing.JPopupMenu;
104 import javax.swing.JProgressBar;
105 import javax.swing.KeyStroke;
106 import javax.swing.SwingUtilities;
107 import javax.swing.event.HyperlinkEvent;
108 import javax.swing.event.HyperlinkEvent.EventType;
109 import javax.swing.event.MenuEvent;
110 import javax.swing.event.MenuListener;
117 * @version $Revision: 1.155 $
119 public class Desktop extends jalview.jbgui.GDesktop implements
120 DropTargetListener, ClipboardOwner, IProgressIndicator,
121 jalview.api.StructureSelectionManagerProvider
124 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
127 * news reader - null if it was never started.
129 private BlogReader jvnews = null;
131 private File projectFile;
135 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
137 public void addJalviewPropertyChangeListener(
138 PropertyChangeListener listener)
140 changeSupport.addJalviewPropertyChangeListener(listener);
144 * @param propertyName
146 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
147 * java.beans.PropertyChangeListener)
149 public void addJalviewPropertyChangeListener(String propertyName,
150 PropertyChangeListener listener)
152 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
156 * @param propertyName
158 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
159 * java.beans.PropertyChangeListener)
161 public void removeJalviewPropertyChangeListener(String propertyName,
162 PropertyChangeListener listener)
164 changeSupport.removeJalviewPropertyChangeListener(propertyName,
168 /** Singleton Desktop instance */
169 public static Desktop instance;
171 public static MyDesktopPane desktop;
173 static int openFrameCount = 0;
175 static final int xOffset = 30;
177 static final int yOffset = 30;
179 public static jalview.ws.jws1.Discoverer discoverer;
181 public static Object[] jalviewClipboard;
183 public static boolean internalCopy = false;
185 static int fileLoadingCount = 0;
187 class MyDesktopManager implements DesktopManager
190 private DesktopManager delegate;
192 public MyDesktopManager(DesktopManager delegate)
194 this.delegate = delegate;
198 public void activateFrame(JInternalFrame f)
202 delegate.activateFrame(f);
203 } catch (NullPointerException npe)
205 Point p = getMousePosition();
206 instance.showPasteMenu(p.x, p.y);
211 public void beginDraggingFrame(JComponent f)
213 delegate.beginDraggingFrame(f);
217 public void beginResizingFrame(JComponent f, int direction)
219 delegate.beginResizingFrame(f, direction);
223 public void closeFrame(JInternalFrame f)
225 delegate.closeFrame(f);
229 public void deactivateFrame(JInternalFrame f)
231 delegate.deactivateFrame(f);
235 public void deiconifyFrame(JInternalFrame f)
237 delegate.deiconifyFrame(f);
241 public void dragFrame(JComponent f, int newX, int newY)
247 delegate.dragFrame(f, newX, newY);
251 public void endDraggingFrame(JComponent f)
253 delegate.endDraggingFrame(f);
257 public void endResizingFrame(JComponent f)
259 delegate.endResizingFrame(f);
263 public void iconifyFrame(JInternalFrame f)
265 delegate.iconifyFrame(f);
269 public void maximizeFrame(JInternalFrame f)
271 delegate.maximizeFrame(f);
275 public void minimizeFrame(JInternalFrame f)
277 delegate.minimizeFrame(f);
281 public void openFrame(JInternalFrame f)
283 delegate.openFrame(f);
287 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
294 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
298 public void setBoundsForFrame(JComponent f, int newX, int newY,
299 int newWidth, int newHeight)
301 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
304 // All other methods, simply delegate
309 * Creates a new Desktop object.
314 * A note to implementors. It is ESSENTIAL that any activities that might
315 * block are spawned off as threads rather than waited for during this
319 doVamsasClientCheck();
321 groovyShell = new JMenuItem();
322 groovyShell.setText(MessageManager.getString("label.groovy_console"));
323 groovyShell.addActionListener(new ActionListener()
326 public void actionPerformed(ActionEvent e)
328 groovyShell_actionPerformed();
331 toolsMenu.add(groovyShell);
332 groovyShell.setVisible(true);
334 doConfigureStructurePrefs();
335 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
336 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
337 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
339 boolean showjconsole = jalview.bin.Cache.getDefault(
340 "SHOW_JAVA_CONSOLE", false);
341 desktop = new MyDesktopPane(selmemusage);
342 if (Platform.isAMac())
344 desktop.setDoubleBuffered(false);
346 showMemusage.setSelected(selmemusage);
347 desktop.setBackground(Color.white);
348 getContentPane().setLayout(new BorderLayout());
349 // alternate config - have scrollbars - see notes in JAL-153
350 // JScrollPane sp = new JScrollPane();
351 // sp.getViewport().setView(desktop);
352 // getContentPane().add(sp, BorderLayout.CENTER);
353 getContentPane().add(desktop, BorderLayout.CENTER);
354 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
356 // This line prevents Windows Look&Feel resizing all new windows to maximum
357 // if previous window was maximised
358 desktop.setDesktopManager(new MyDesktopManager(
359 new DefaultDesktopManager()));
361 Rectangle dims = getLastKnownDimensions("");
368 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
369 setBounds((screenSize.width - 900) / 2,
370 (screenSize.height - 650) / 2, 900, 650);
372 jconsole = new Console(this, showjconsole);
373 // add essential build information
374 jconsole.setHeader("Jalview Version: "
375 + jalview.bin.Cache.getProperty("VERSION") + "\n"
376 + "Jalview Installation: "
377 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
378 + "\n" + "Build Date: "
379 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
380 + "Java version: " + System.getProperty("java.version") + "\n"
381 + System.getProperty("os.arch") + " "
382 + System.getProperty("os.name") + " "
383 + System.getProperty("os.version"));
385 showConsole(showjconsole);
387 showNews.setVisible(false);
389 this.addWindowListener(new WindowAdapter()
392 public void windowClosing(WindowEvent evt)
399 this.addMouseListener(ma = new MouseAdapter()
402 public void mousePressed(MouseEvent evt)
404 if (evt.isPopupTrigger())
406 showPasteMenu(evt.getX(), evt.getY());
410 desktop.addMouseListener(ma);
412 this.addFocusListener(new FocusListener()
416 public void focusLost(FocusEvent e)
418 // TODO Auto-generated method stub
423 public void focusGained(FocusEvent e)
425 Cache.log.debug("Relaying windows after focus gain");
426 // make sure that we sort windows properly after we gain focus
427 instance.relayerWindows();
430 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
431 // Spawn a thread that shows the splashscreen
432 SwingUtilities.invokeLater(new Runnable()
442 // Thread off a new instance of the file chooser - this reduces the time it
443 // takes to open it later on.
444 new Thread(new Runnable()
449 Cache.log.debug("Filechooser init thread started.");
450 new JalviewFileChooser(
451 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
452 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
453 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
454 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
455 Cache.log.debug("Filechooser init thread finished.");
458 // Add the service change listener
459 changeSupport.addJalviewPropertyChangeListener("services",
460 new PropertyChangeListener()
464 public void propertyChange(PropertyChangeEvent evt)
466 Cache.log.debug("Firing service changed event for "
467 + evt.getNewValue());
468 JalviewServicesChanged(evt);
474 public void doConfigureStructurePrefs()
476 // configure services
477 StructureSelectionManager ssm = StructureSelectionManager
478 .getStructureSelectionManager(this);
479 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
481 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
482 Preferences.ADD_TEMPFACT_ANN, true));
483 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
484 Preferences.STRUCT_FROM_PDB, true));
485 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
486 Preferences.USE_RNAVIEW, true));
490 ssm.setAddTempFacAnnot(false);
491 ssm.setProcessSecondaryStructure(false);
492 ssm.setSecStructServices(false);
496 public void checkForNews()
498 final Desktop me = this;
499 // Thread off the news reader, in case there are connection problems.
500 addDialogThread(new Runnable()
505 Cache.log.debug("Starting news thread.");
507 jvnews = new BlogReader(me);
508 showNews.setVisible(true);
509 Cache.log.debug("Completed news thread.");
515 protected void showNews_actionPerformed(ActionEvent e)
517 showNews(showNews.isSelected());
520 void showNews(boolean visible)
523 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
524 showNews.setSelected(visible);
525 if (visible && !jvnews.isVisible())
527 new Thread(new Runnable()
532 long now = System.currentTimeMillis();
533 Desktop.instance.setProgressBar(
534 MessageManager.getString("status.refreshing_news"), now);
535 jvnews.refreshNews();
536 Desktop.instance.setProgressBar(null, now);
545 * recover the last known dimensions for a jalview window
548 * - empty string is desktop, all other windows have unique prefix
549 * @return null or last known dimensions scaled to current geometry (if last
550 * window geom was known)
552 Rectangle getLastKnownDimensions(String windowName)
554 // TODO: lock aspect ratio for scaling desktop Bug #0058199
555 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
556 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
557 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
558 String width = jalview.bin.Cache.getProperty(windowName
560 String height = jalview.bin.Cache.getProperty(windowName
562 if ((x != null) && (y != null) && (width != null) && (height != null))
564 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
565 .parseInt(width), ih = Integer.parseInt(height);
566 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
568 // attempt #1 - try to cope with change in screen geometry - this
569 // version doesn't preserve original jv aspect ratio.
570 // take ratio of current screen size vs original screen size.
571 double sw = ((1f * screenSize.width) / (1f * Integer
572 .parseInt(jalview.bin.Cache
573 .getProperty("SCREENGEOMETRY_WIDTH"))));
574 double sh = ((1f * screenSize.height) / (1f * Integer
575 .parseInt(jalview.bin.Cache
576 .getProperty("SCREENGEOMETRY_HEIGHT"))));
577 // rescale the bounds depending upon the current screen geometry.
578 ix = (int) (ix * sw);
579 iw = (int) (iw * sw);
580 iy = (int) (iy * sh);
581 ih = (int) (ih * sh);
582 while (ix >= screenSize.width)
584 jalview.bin.Cache.log
585 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
586 ix -= screenSize.width;
588 while (iy >= screenSize.height)
590 jalview.bin.Cache.log
591 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
592 iy -= screenSize.height;
594 jalview.bin.Cache.log.debug("Got last known dimensions for "
595 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
598 // return dimensions for new instance
599 return new Rectangle(ix, iy, iw, ih);
604 private void doVamsasClientCheck()
606 if (jalview.bin.Cache.vamsasJarsPresent())
608 setupVamsasDisconnectedGui();
609 VamsasMenu.setVisible(true);
610 final Desktop us = this;
611 VamsasMenu.addMenuListener(new MenuListener()
613 // this listener remembers when the menu was first selected, and
614 // doesn't rebuild the session list until it has been cleared and
616 boolean refresh = true;
619 public void menuCanceled(MenuEvent e)
625 public void menuDeselected(MenuEvent e)
631 public void menuSelected(MenuEvent e)
635 us.buildVamsasStMenu();
640 vamsasStart.setVisible(true);
644 void showPasteMenu(int x, int y)
646 JPopupMenu popup = new JPopupMenu();
647 JMenuItem item = new JMenuItem(
648 MessageManager.getString("label.paste_new_window"));
649 item.addActionListener(new ActionListener()
652 public void actionPerformed(ActionEvent evt)
659 popup.show(this, x, y);
666 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
667 Transferable contents = c.getContents(this);
669 if (contents != null)
671 String file = (String) contents
672 .getTransferData(DataFlavor.stringFlavor);
674 FileFormatI format = new IdentifyFile().identify(file,
675 DataSourceType.PASTE);
677 new FileLoader().LoadFile(file, DataSourceType.PASTE, format);
680 } catch (Exception ex)
683 .println("Unable to paste alignment from system clipboard:\n"
689 * Adds and opens the given frame to the desktop
700 public static synchronized void addInternalFrame(
701 final JInternalFrame frame, String title, int w, int h)
703 addInternalFrame(frame, title, true, w, h, true);
707 * Add an internal frame to the Jalview desktop
714 * When true, display frame immediately, otherwise, caller must call
715 * setVisible themselves.
721 public static synchronized void addInternalFrame(
722 final JInternalFrame frame, String title, boolean makeVisible,
725 addInternalFrame(frame, title, makeVisible, w, h, true);
729 * Add an internal frame to the Jalview desktop and make it visible
742 public static synchronized void addInternalFrame(
743 final JInternalFrame frame, String title, int w, int h,
746 addInternalFrame(frame, title, true, w, h, resizable);
750 * Add an internal frame to the Jalview desktop
757 * When true, display frame immediately, otherwise, caller must call
758 * setVisible themselves.
766 public static synchronized void addInternalFrame(
767 final JInternalFrame frame, String title, boolean makeVisible,
768 int w, int h, boolean resizable)
771 // TODO: allow callers to determine X and Y position of frame (eg. via
773 // TODO: consider fixing method to update entries in the window submenu with
774 // the current window title
776 frame.setTitle(title);
777 if (frame.getWidth() < 1 || frame.getHeight() < 1)
781 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
782 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
783 // IF JALVIEW IS RUNNING HEADLESS
784 // ///////////////////////////////////////////////
786 || (System.getProperty("java.awt.headless") != null && System
787 .getProperty("java.awt.headless").equals("true")))
794 frame.setVisible(makeVisible);
795 frame.setClosable(true);
796 frame.setResizable(resizable);
797 frame.setMaximizable(resizable);
798 frame.setIconifiable(resizable);
799 if (Platform.isAMac())
801 frame.setIconifiable(false);
802 frame.setFrameIcon(null);
803 // frame.setDesktopIcon(null);
804 frame.setDoubleBuffered(false);
806 if (frame.getX() < 1 && frame.getY() < 1)
808 frame.setLocation(xOffset * openFrameCount, yOffset
809 * ((openFrameCount - 1) % 10) + yOffset);
812 final JMenuItem menuItem = new JMenuItem(title);
813 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
816 public void internalFrameActivated(
817 javax.swing.event.InternalFrameEvent evt)
819 JInternalFrame itf = desktop.getSelectedFrame();
828 public void internalFrameClosed(
829 javax.swing.event.InternalFrameEvent evt)
831 PaintRefresher.RemoveComponent(frame);
833 windowMenu.remove(menuItem);
834 JInternalFrame itf = desktop.getSelectedFrame();
843 menuItem.addActionListener(new ActionListener()
846 public void actionPerformed(ActionEvent e)
850 frame.setSelected(true);
851 frame.setIcon(false);
852 } catch (java.beans.PropertyVetoException ex)
858 menuItem.addMouseListener(new MouseListener()
862 public void mouseReleased(MouseEvent e)
867 public void mousePressed(MouseEvent e)
872 public void mouseExited(MouseEvent e)
876 frame.setSelected(false);
877 } catch (PropertyVetoException e1)
883 public void mouseEntered(MouseEvent e)
887 frame.setSelected(true);
888 } catch (PropertyVetoException e1)
894 public void mouseClicked(MouseEvent e)
900 windowMenu.add(menuItem);
906 frame.setSelected(true);
907 frame.requestFocus();
908 } catch (java.beans.PropertyVetoException ve)
910 } catch (java.lang.ClassCastException cex)
913 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
919 public void lostOwnership(Clipboard clipboard, Transferable contents)
923 Desktop.jalviewClipboard = null;
926 internalCopy = false;
930 public void dragEnter(DropTargetDragEvent evt)
935 public void dragExit(DropTargetEvent evt)
940 public void dragOver(DropTargetDragEvent evt)
945 public void dropActionChanged(DropTargetDragEvent evt)
956 public void drop(DropTargetDropEvent evt)
958 boolean success = true;
959 Transferable t = evt.getTransferable();
960 List<String> files = new ArrayList<String>();
961 List<DataSourceType> protocols = new ArrayList<DataSourceType>();
965 Desktop.transferFromDropTarget(files, protocols, evt, t);
966 } catch (Exception e)
976 for (int i = 0; i < files.size(); i++)
978 String file = files.get(i).toString();
979 DataSourceType protocol = (protocols == null) ? DataSourceType.FILE
981 FileFormatI format = null;
983 if (file.endsWith(".jar"))
985 format = FileFormat.Jalview;
990 format = new IdentifyFile().identify(file, protocol);
993 new FileLoader().LoadFile(file, protocol, format);
996 } catch (Exception ex)
1001 evt.dropComplete(success); // need this to ensure input focus is properly
1002 // transfered to any new windows created
1012 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1014 JalviewFileChooser chooser = new JalviewFileChooser(
1015 Cache.getProperty("LAST_DIRECTORY"),
1016 AppletFormatAdapter.READABLE_EXTENSIONS,
1017 AppletFormatAdapter.READABLE_FNAMES,
1018 Cache.getProperty("DEFAULT_FILE_FORMAT"));
1020 chooser.setFileView(new JalviewFileView());
1021 chooser.setDialogTitle(MessageManager
1022 .getString("label.open_local_file"));
1023 chooser.setToolTipText(MessageManager.getString("action.open"));
1025 int value = chooser.showOpenDialog(this);
1027 if (value == JalviewFileChooser.APPROVE_OPTION)
1029 String choice = chooser.getSelectedFile().getPath();
1030 Cache.setProperty("LAST_DIRECTORY", chooser
1031 .getSelectedFile().getParent());
1033 FileFormatI format = null;
1034 if (chooser.getSelectedFormat() != null
1035 && chooser.getSelectedFormat() == FileFormat.Jalview)
1037 format = FileFormat.Jalview;
1043 format = new IdentifyFile().identify(choice, DataSourceType.FILE);
1044 } catch (FileFormatException e)
1050 if (viewport != null)
1052 new FileLoader().LoadFile(viewport, choice, DataSourceType.FILE,
1057 new FileLoader().LoadFile(choice, DataSourceType.FILE, format);
1067 * @throws FileFormatException
1070 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1071 throws FileFormatException
1073 // This construct allows us to have a wider textfield
1075 JLabel label = new JLabel(
1076 MessageManager.getString("label.input_file_url"));
1077 final JComboBox history = new JComboBox();
1079 JPanel panel = new JPanel(new GridLayout(2, 1));
1082 history.setPreferredSize(new Dimension(400, 20));
1083 history.setEditable(true);
1084 history.addItem("http://www.");
1086 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1090 if (historyItems != null)
1092 st = new StringTokenizer(historyItems, "\t");
1094 while (st.hasMoreTokens())
1096 history.addItem(st.nextElement());
1100 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1101 MessageManager.getString("label.input_alignment_from_url"),
1102 JOptionPane.OK_CANCEL_OPTION);
1104 if (reply != JOptionPane.OK_OPTION)
1109 String url = history.getSelectedItem().toString();
1111 if (url.toLowerCase().endsWith(".jar"))
1113 if (viewport != null)
1115 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1116 FileFormat.Jalview);
1120 new FileLoader().LoadFile(url, DataSourceType.URL,
1121 FileFormat.Jalview);
1126 FileFormatI format = new IdentifyFile().identify(url,
1127 DataSourceType.URL);
1129 if (format.equals("URL NOT FOUND"))
1131 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1132 MessageManager.formatMessage("label.couldnt_locate",
1133 new Object[] { url }), MessageManager
1134 .getString("label.url_not_found"),
1135 JOptionPane.WARNING_MESSAGE);
1140 if (viewport != null)
1143 .LoadFile(viewport, url, DataSourceType.URL, format);
1147 new FileLoader().LoadFile(url, DataSourceType.URL, format);
1153 * Opens the CutAndPaste window for the user to paste an alignment in to
1156 * - if not null, the pasted alignment is added to the current
1157 * alignment; if null, to a new alignment window
1160 public void inputTextboxMenuItem_actionPerformed(
1161 AlignmentViewPanel viewPanel)
1163 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1164 cap.setForInput(viewPanel);
1165 Desktop.addInternalFrame(cap,
1166 MessageManager.getString("label.cut_paste_alignmen_file"),
1176 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1178 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1179 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1181 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1182 getBounds().y, getWidth(), getHeight()));
1184 if (jconsole != null)
1186 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1187 jconsole.stopConsole();
1191 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1194 if (dialogExecutor != null)
1196 dialogExecutor.shutdownNow();
1198 closeAll_actionPerformed(null);
1200 if (groovyConsole != null)
1202 // suppress a possible repeat prompt to save script
1203 groovyConsole.setDirty(false);
1204 groovyConsole.exit();
1209 private void storeLastKnownDimensions(String string, Rectangle jc)
1211 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1212 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1213 + " height:" + jc.height);
1215 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1216 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1217 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1218 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1228 public void aboutMenuItem_actionPerformed(ActionEvent e)
1230 // StringBuffer message = getAboutMessage(false);
1231 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1233 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1234 new Thread(new Runnable()
1239 new SplashScreen(true);
1244 public StringBuffer getAboutMessage(boolean shortv)
1246 StringBuffer message = new StringBuffer();
1247 message.append("<html>");
1250 message.append("<h1><strong>Version: "
1251 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1252 message.append("<strong>Last Updated: <em>"
1253 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1254 + "</em></strong>");
1260 message.append("<strong>Version "
1261 + jalview.bin.Cache.getProperty("VERSION")
1262 + "; last updated: "
1263 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1266 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1269 message.append("<br>...Checking latest version...</br>");
1271 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1272 .equals(jalview.bin.Cache.getProperty("VERSION")))
1274 boolean red = false;
1275 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1276 .indexOf("automated build") == -1)
1279 // Displayed when code version and jnlp version do not match and code
1280 // version is not a development build
1281 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1284 message.append("<br>!! Version "
1285 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1287 + " is available for download from "
1288 + jalview.bin.Cache.getDefault("www.jalview.org",
1289 "http://www.jalview.org") + " !!");
1292 message.append("</div>");
1295 message.append("<br>Authors: "
1297 .getDefault("AUTHORFNAMES",
1298 "The Jalview Authors (See AUTHORS file for current list)")
1299 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1300 + "<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"
1301 + "<br><br>If you use Jalview, please cite:"
1302 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1303 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1304 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1316 public void documentationMenuItem_actionPerformed(ActionEvent e)
1320 Help.showHelpWindow();
1321 } catch (Exception ex)
1327 public void closeAll_actionPerformed(ActionEvent e)
1329 JInternalFrame[] frames = desktop.getAllFrames();
1330 for (int i = 0; i < frames.length; i++)
1334 frames[i].setClosed(true);
1335 } catch (java.beans.PropertyVetoException ex)
1339 System.out.println("ALL CLOSED");
1340 if (v_client != null)
1342 // TODO clear binding to vamsas document objects on close_all
1346 * reset state of singleton objects as appropriate (clear down session state
1347 * when all windows are closed)
1349 StructureSelectionManager ssm = StructureSelectionManager
1350 .getStructureSelectionManager(this);
1358 public void raiseRelated_actionPerformed(ActionEvent e)
1360 reorderAssociatedWindows(false, false);
1364 public void minimizeAssociated_actionPerformed(ActionEvent e)
1366 reorderAssociatedWindows(true, false);
1369 void closeAssociatedWindows()
1371 reorderAssociatedWindows(false, true);
1377 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1381 protected void garbageCollect_actionPerformed(ActionEvent e)
1383 // We simply collect the garbage
1384 jalview.bin.Cache.log.debug("Collecting garbage...");
1386 jalview.bin.Cache.log.debug("Finished garbage collection.");
1393 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1397 protected void showMemusage_actionPerformed(ActionEvent e)
1399 desktop.showMemoryUsage(showMemusage.isSelected());
1406 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1410 protected void showConsole_actionPerformed(ActionEvent e)
1412 showConsole(showConsole.isSelected());
1415 Console jconsole = null;
1418 * control whether the java console is visible or not
1422 void showConsole(boolean selected)
1424 showConsole.setSelected(selected);
1425 // TODO: decide if we should update properties file
1426 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1428 jconsole.setVisible(selected);
1431 void reorderAssociatedWindows(boolean minimize, boolean close)
1433 JInternalFrame[] frames = desktop.getAllFrames();
1434 if (frames == null || frames.length < 1)
1439 AlignmentViewport source = null, target = null;
1440 if (frames[0] instanceof AlignFrame)
1442 source = ((AlignFrame) frames[0]).getCurrentView();
1444 else if (frames[0] instanceof TreePanel)
1446 source = ((TreePanel) frames[0]).getViewPort();
1448 else if (frames[0] instanceof PCAPanel)
1450 source = ((PCAPanel) frames[0]).av;
1452 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1454 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1459 for (int i = 0; i < frames.length; i++)
1462 if (frames[i] == null)
1466 if (frames[i] instanceof AlignFrame)
1468 target = ((AlignFrame) frames[i]).getCurrentView();
1470 else if (frames[i] instanceof TreePanel)
1472 target = ((TreePanel) frames[i]).getViewPort();
1474 else if (frames[i] instanceof PCAPanel)
1476 target = ((PCAPanel) frames[i]).av;
1478 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1480 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1483 if (source == target)
1489 frames[i].setClosed(true);
1493 frames[i].setIcon(minimize);
1496 frames[i].toFront();
1500 } catch (java.beans.PropertyVetoException ex)
1515 protected void preferences_actionPerformed(ActionEvent e)
1527 public void saveState_actionPerformed(ActionEvent e)
1529 JalviewFileChooser chooser = new JalviewFileChooser(
1530 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
1531 new String[] { "jvp" }, new String[] { "Jalview Project" },
1534 chooser.setFileView(new JalviewFileView());
1535 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1537 int value = chooser.showSaveDialog(this);
1539 if (value == JalviewFileChooser.APPROVE_OPTION)
1541 final Desktop me = this;
1542 final java.io.File choice = chooser.getSelectedFile();
1543 setProjectFile(choice);
1545 new Thread(new Runnable()
1550 // TODO: refactor to Jalview desktop session controller action.
1551 setProgressBar(MessageManager.formatMessage(
1552 "label.saving_jalview_project",
1553 new Object[] { choice.getName() }), choice.hashCode());
1554 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1555 choice.getParent());
1556 // TODO catch and handle errors for savestate
1557 // TODO prevent user from messing with the Desktop whilst we're saving
1560 new Jalview2XML().saveState(choice);
1561 } catch (OutOfMemoryError oom)
1563 new OOMWarning("Whilst saving current state to "
1564 + choice.getName(), oom);
1565 } catch (Exception ex)
1568 "Problems whilst trying to save to " + choice.getName(),
1570 JOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1571 "label.error_whilst_saving_current_state_to",
1572 new Object[] { choice.getName() }), MessageManager
1573 .getString("label.couldnt_save_project"),
1574 JOptionPane.WARNING_MESSAGE);
1576 setProgressBar(null, choice.hashCode());
1582 private void setProjectFile(File choice)
1584 this.projectFile = choice;
1587 public File getProjectFile()
1589 return this.projectFile;
1599 public void loadState_actionPerformed(ActionEvent e)
1601 JalviewFileChooser chooser = new JalviewFileChooser(
1602 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[] {
1603 "jvp", "jar" }, new String[] { "Jalview Project",
1604 "Jalview Project (old)" }, "Jalview Project");
1605 chooser.setFileView(new JalviewFileView());
1606 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1608 int value = chooser.showOpenDialog(this);
1610 if (value == JalviewFileChooser.APPROVE_OPTION)
1612 final File selectedFile = chooser.getSelectedFile();
1613 setProjectFile(selectedFile);
1614 final String choice = selectedFile.getAbsolutePath();
1615 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1616 selectedFile.getParent());
1617 new Thread(new Runnable()
1623 MessageManager.formatMessage(
1624 "label.loading_jalview_project",
1625 new Object[] { choice }), choice.hashCode());
1628 new Jalview2XML().loadJalviewAlign(choice);
1629 } catch (OutOfMemoryError oom)
1631 new OOMWarning("Whilst loading project from " + choice, oom);
1632 } catch (Exception ex)
1634 Cache.log.error("Problems whilst loading project from "
1636 JOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1638 "label.error_whilst_loading_project_from",
1639 new Object[] { choice }), MessageManager
1640 .getString("label.couldnt_load_project"),
1641 JOptionPane.WARNING_MESSAGE);
1643 setProgressBar(null, choice.hashCode());
1650 public void inputSequence_actionPerformed(ActionEvent e)
1652 new SequenceFetcher(this);
1655 JPanel progressPanel;
1657 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1659 public void startLoading(final String fileName)
1661 if (fileLoadingCount == 0)
1663 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1664 "label.loading_file", new Object[] { fileName })));
1669 private JPanel addProgressPanel(String string)
1671 if (progressPanel == null)
1673 progressPanel = new JPanel(new GridLayout(1, 1));
1674 totalProgressCount = 0;
1675 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1677 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1678 JProgressBar progressBar = new JProgressBar();
1679 progressBar.setIndeterminate(true);
1681 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1683 thisprogress.add(progressBar, BorderLayout.CENTER);
1684 progressPanel.add(thisprogress);
1685 ((GridLayout) progressPanel.getLayout())
1686 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1687 ++totalProgressCount;
1688 instance.validate();
1689 return thisprogress;
1692 int totalProgressCount = 0;
1694 private void removeProgressPanel(JPanel progbar)
1696 if (progressPanel != null)
1698 synchronized (progressPanel)
1700 progressPanel.remove(progbar);
1701 GridLayout gl = (GridLayout) progressPanel.getLayout();
1702 gl.setRows(gl.getRows() - 1);
1703 if (--totalProgressCount < 1)
1705 this.getContentPane().remove(progressPanel);
1706 progressPanel = null;
1713 public void stopLoading()
1716 if (fileLoadingCount < 1)
1718 while (fileLoadingPanels.size() > 0)
1720 removeProgressPanel(fileLoadingPanels.remove(0));
1722 fileLoadingPanels.clear();
1723 fileLoadingCount = 0;
1728 public static int getViewCount(String alignmentId)
1730 AlignmentViewport[] aps = getViewports(alignmentId);
1731 return (aps == null) ? 0 : aps.length;
1736 * @param alignmentId
1737 * - if null, all sets are returned
1738 * @return all AlignmentPanels concerning the alignmentId sequence set
1740 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1742 if (Desktop.desktop == null)
1744 // no frames created and in headless mode
1745 // TODO: verify that frames are recoverable when in headless mode
1748 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1749 AlignFrame[] frames = getAlignFrames();
1754 for (AlignFrame af : frames)
1756 for (AlignmentPanel ap : af.alignPanels)
1758 if (alignmentId == null
1759 || alignmentId.equals(ap.av.getSequenceSetId()))
1765 if (aps.size() == 0)
1769 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1774 * get all the viewports on an alignment.
1776 * @param sequenceSetId
1777 * unique alignment id (may be null - all viewports returned in that
1779 * @return all viewports on the alignment bound to sequenceSetId
1781 public static AlignmentViewport[] getViewports(String sequenceSetId)
1783 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1784 if (desktop != null)
1786 AlignFrame[] frames = Desktop.getAlignFrames();
1788 for (AlignFrame afr : frames)
1790 if (sequenceSetId == null
1791 || afr.getViewport().getSequenceSetId()
1792 .equals(sequenceSetId))
1794 if (afr.alignPanels != null)
1796 for (AlignmentPanel ap : afr.alignPanels)
1798 if (sequenceSetId == null
1799 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1807 viewp.add(afr.getViewport());
1811 if (viewp.size() > 0)
1813 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1820 * Explode the views in the given frame into separate AlignFrame
1824 public void explodeViews(AlignFrame af)
1826 int size = af.alignPanels.size();
1832 for (int i = 0; i < size; i++)
1834 AlignmentPanel ap = af.alignPanels.get(i);
1835 AlignFrame newaf = new AlignFrame(ap);
1838 * Restore the view's last exploded frame geometry if known. Multiple
1839 * views from one exploded frame share and restore the same (frame)
1840 * position and size.
1842 Rectangle geometry = ap.av.getExplodedGeometry();
1843 if (geometry != null)
1845 newaf.setBounds(geometry);
1848 ap.av.setGatherViewsHere(false);
1850 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1851 AlignFrame.DEFAULT_HEIGHT);
1854 af.alignPanels.clear();
1855 af.closeMenuItem_actionPerformed(true);
1860 * Gather expanded views (separate AlignFrame's) with the same sequence set
1861 * identifier back in to this frame as additional views, and close the
1862 * expanded views. Note the expanded frames may themselves have multiple
1863 * views. We take the lot.
1867 public void gatherViews(AlignFrame source)
1869 source.viewport.setGatherViewsHere(true);
1870 source.viewport.setExplodedGeometry(source.getBounds());
1871 JInternalFrame[] frames = desktop.getAllFrames();
1872 String viewId = source.viewport.getSequenceSetId();
1874 for (int t = 0; t < frames.length; t++)
1876 if (frames[t] instanceof AlignFrame && frames[t] != source)
1878 AlignFrame af = (AlignFrame) frames[t];
1879 boolean gatherThis = false;
1880 for (int a = 0; a < af.alignPanels.size(); a++)
1882 AlignmentPanel ap = af.alignPanels.get(a);
1883 if (viewId.equals(ap.av.getSequenceSetId()))
1886 ap.av.setGatherViewsHere(false);
1887 ap.av.setExplodedGeometry(af.getBounds());
1888 source.addAlignmentPanel(ap, false);
1894 af.alignPanels.clear();
1895 af.closeMenuItem_actionPerformed(true);
1902 jalview.gui.VamsasApplication v_client = null;
1905 public void vamsasImport_actionPerformed(ActionEvent e)
1907 if (v_client == null)
1909 // Load and try to start a session.
1910 JalviewFileChooser chooser = new JalviewFileChooser(
1911 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1913 chooser.setFileView(new JalviewFileView());
1914 chooser.setDialogTitle(MessageManager
1915 .getString("label.open_saved_vamsas_session"));
1916 chooser.setToolTipText(MessageManager
1917 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1919 int value = chooser.showOpenDialog(this);
1921 if (value == JalviewFileChooser.APPROVE_OPTION)
1923 String fle = chooser.getSelectedFile().toString();
1924 if (!vamsasImport(chooser.getSelectedFile()))
1927 .showInternalMessageDialog(
1929 MessageManager.formatMessage(
1930 "label.couldnt_import_as_vamsas_session",
1931 new Object[] { fle }),
1933 .getString("label.vamsas_document_import_failed"),
1934 JOptionPane.ERROR_MESSAGE);
1940 jalview.bin.Cache.log
1941 .error("Implementation error - load session from a running session is not supported.");
1946 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1949 * @return true if import was a success and a session was started.
1951 public boolean vamsasImport(URL url)
1953 // TODO: create progress bar
1954 if (v_client != null)
1957 jalview.bin.Cache.log
1958 .error("Implementation error - load session from a running session is not supported.");
1964 // copy the URL content to a temporary local file
1965 // TODO: be a bit cleverer here with nio (?!)
1966 File file = File.createTempFile("vdocfromurl", ".vdj");
1967 FileOutputStream fos = new FileOutputStream(file);
1968 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1969 byte[] buffer = new byte[2048];
1971 while ((ln = bis.read(buffer)) > -1)
1973 fos.write(buffer, 0, ln);
1977 v_client = new jalview.gui.VamsasApplication(this, file,
1978 url.toExternalForm());
1979 } catch (Exception ex)
1981 jalview.bin.Cache.log.error(
1982 "Failed to create new vamsas session from contents of URL "
1986 setupVamsasConnectedGui();
1987 v_client.initial_update(); // TODO: thread ?
1988 return v_client.inSession();
1992 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1995 * @return true if import was a success and a session was started.
1997 public boolean vamsasImport(File file)
1999 if (v_client != null)
2002 jalview.bin.Cache.log
2003 .error("Implementation error - load session from a running session is not supported.");
2007 setProgressBar(MessageManager.formatMessage(
2008 "status.importing_vamsas_session_from",
2009 new Object[] { file.getName() }), file.hashCode());
2012 v_client = new jalview.gui.VamsasApplication(this, file, null);
2013 } catch (Exception ex)
2015 setProgressBar(MessageManager.formatMessage(
2016 "status.importing_vamsas_session_from",
2017 new Object[] { file.getName() }), file.hashCode());
2018 jalview.bin.Cache.log.error(
2019 "New vamsas session from existing session file failed:", ex);
2022 setupVamsasConnectedGui();
2023 v_client.initial_update(); // TODO: thread ?
2024 setProgressBar(MessageManager.formatMessage(
2025 "status.importing_vamsas_session_from",
2026 new Object[] { file.getName() }), file.hashCode());
2027 return v_client.inSession();
2030 public boolean joinVamsasSession(String mysesid)
2032 if (v_client != null)
2036 .getString("error.try_join_vamsas_session_another"));
2038 if (mysesid == null)
2041 MessageManager.getString("error.invalid_vamsas_session_id"));
2043 v_client = new VamsasApplication(this, mysesid);
2044 setupVamsasConnectedGui();
2045 v_client.initial_update();
2046 return (v_client.inSession());
2050 public void vamsasStart_actionPerformed(ActionEvent e)
2052 if (v_client == null)
2055 // we just start a default session for moment.
2057 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2058 * getProperty("LAST_DIRECTORY"));
2060 * chooser.setFileView(new JalviewFileView());
2061 * chooser.setDialogTitle("Load Vamsas file");
2062 * chooser.setToolTipText("Import");
2064 * int value = chooser.showOpenDialog(this);
2066 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2067 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2069 v_client = new VamsasApplication(this);
2070 setupVamsasConnectedGui();
2071 v_client.initial_update(); // TODO: thread ?
2075 // store current data in session.
2076 v_client.push_update(); // TODO: thread
2080 protected void setupVamsasConnectedGui()
2082 vamsasStart.setText(MessageManager.getString("label.session_update"));
2083 vamsasSave.setVisible(true);
2084 vamsasStop.setVisible(true);
2085 vamsasImport.setVisible(false); // Document import to existing session is
2086 // not possible for vamsas-client-1.0.
2089 protected void setupVamsasDisconnectedGui()
2091 vamsasSave.setVisible(false);
2092 vamsasStop.setVisible(false);
2093 vamsasImport.setVisible(true);
2094 vamsasStart.setText(MessageManager
2095 .getString("label.new_vamsas_session"));
2099 public void vamsasStop_actionPerformed(ActionEvent e)
2101 if (v_client != null)
2103 v_client.end_session();
2105 setupVamsasDisconnectedGui();
2109 protected void buildVamsasStMenu()
2111 if (v_client == null)
2113 String[] sess = null;
2116 sess = VamsasApplication.getSessionList();
2117 } catch (Exception e)
2119 jalview.bin.Cache.log.warn(
2120 "Problem getting current sessions list.", e);
2125 jalview.bin.Cache.log.debug("Got current sessions list: "
2126 + sess.length + " entries.");
2127 VamsasStMenu.removeAll();
2128 for (int i = 0; i < sess.length; i++)
2130 JMenuItem sessit = new JMenuItem();
2131 sessit.setText(sess[i]);
2132 sessit.setToolTipText(MessageManager.formatMessage(
2133 "label.connect_to_session", new Object[] { sess[i] }));
2134 final Desktop dsktp = this;
2135 final String mysesid = sess[i];
2136 sessit.addActionListener(new ActionListener()
2140 public void actionPerformed(ActionEvent e)
2142 if (dsktp.v_client == null)
2144 Thread rthr = new Thread(new Runnable()
2150 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2151 dsktp.setupVamsasConnectedGui();
2152 dsktp.v_client.initial_update();
2160 VamsasStMenu.add(sessit);
2162 // don't show an empty menu.
2163 VamsasStMenu.setVisible(sess.length > 0);
2168 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2169 VamsasStMenu.removeAll();
2170 VamsasStMenu.setVisible(false);
2175 // Not interested in the content. Just hide ourselves.
2176 VamsasStMenu.setVisible(false);
2181 public void vamsasSave_actionPerformed(ActionEvent e)
2183 if (v_client != null)
2185 JalviewFileChooser chooser = new JalviewFileChooser(
2186 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2187 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2188 new String[] { "Vamsas Document" }, "Vamsas Document");
2190 chooser.setFileView(new JalviewFileView());
2191 chooser.setDialogTitle(MessageManager
2192 .getString("label.save_vamsas_document_archive"));
2194 int value = chooser.showSaveDialog(this);
2196 if (value == JalviewFileChooser.APPROVE_OPTION)
2198 java.io.File choice = chooser.getSelectedFile();
2199 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2200 "label.saving_vamsas_doc",
2201 new Object[] { choice.getName() }));
2202 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2203 String warnmsg = null;
2204 String warnttl = null;
2207 v_client.vclient.storeDocument(choice);
2210 warnttl = "Serious Problem saving Vamsas Document";
2211 warnmsg = ex.toString();
2212 jalview.bin.Cache.log.error("Error Whilst saving document to "
2215 } catch (Exception ex)
2217 warnttl = "Problem saving Vamsas Document.";
2218 warnmsg = ex.toString();
2219 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2223 removeProgressPanel(progpanel);
2224 if (warnmsg != null)
2226 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2228 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2234 JPanel vamUpdate = null;
2237 * hide vamsas user gui bits when a vamsas document event is being handled.
2240 * true to hide gui, false to reveal gui
2242 public void setVamsasUpdate(boolean b)
2244 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2245 + (b ? "in progress" : "finished"));
2247 if (vamUpdate != null)
2249 this.removeProgressPanel(vamUpdate);
2253 vamUpdate = this.addProgressPanel(MessageManager
2254 .getString("label.updating_vamsas_session"));
2256 vamsasStart.setVisible(!b);
2257 vamsasStop.setVisible(!b);
2258 vamsasSave.setVisible(!b);
2261 public JInternalFrame[] getAllFrames()
2263 return desktop.getAllFrames();
2267 * Checks the given url to see if it gives a response indicating that the user
2268 * should be informed of a new questionnaire.
2272 public void checkForQuestionnaire(String url)
2274 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2275 // javax.swing.SwingUtilities.invokeLater(jvq);
2276 new Thread(jvq).start();
2280 * Proxy class for JDesktopPane which optionally displays the current memory
2281 * usage and highlights the desktop area with a red bar if free memory runs
2286 public class MyDesktopPane extends JDesktopPane implements Runnable
2289 private static final float ONE_MB = 1048576f;
2291 boolean showMemoryUsage = false;
2295 java.text.NumberFormat df;
2297 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2300 public MyDesktopPane(boolean showMemoryUsage)
2302 showMemoryUsage(showMemoryUsage);
2305 public void showMemoryUsage(boolean showMemory)
2307 this.showMemoryUsage = showMemory;
2310 Thread worker = new Thread(this);
2315 public boolean isShowMemoryUsage()
2317 return showMemoryUsage;
2323 df = java.text.NumberFormat.getNumberInstance();
2324 df.setMaximumFractionDigits(2);
2325 runtime = Runtime.getRuntime();
2327 while (showMemoryUsage)
2331 maxMemory = runtime.maxMemory() / ONE_MB;
2332 allocatedMemory = runtime.totalMemory() / ONE_MB;
2333 freeMemory = runtime.freeMemory() / ONE_MB;
2334 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2336 percentUsage = (totalFreeMemory / maxMemory) * 100;
2338 // if (percentUsage < 20)
2340 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2342 // instance.set.setBorder(border1);
2345 // sleep after showing usage
2347 } catch (Exception ex)
2349 ex.printStackTrace();
2355 public void paintComponent(Graphics g)
2357 if (showMemoryUsage && g != null && df != null)
2359 if (percentUsage < 20)
2361 g.setColor(Color.red);
2363 FontMetrics fm = g.getFontMetrics();
2366 g.drawString(MessageManager.formatMessage(
2367 "label.memory_stats",
2368 new Object[] { df.format(totalFreeMemory),
2369 df.format(maxMemory), df.format(percentUsage) }), 10,
2370 getHeight() - fm.getHeight());
2377 * fixes stacking order after a modal dialog to ensure windows that should be
2378 * on top actually are
2380 public void relayerWindows()
2385 protected JMenuItem groovyShell;
2388 * Accessor method to quickly get all the AlignmentFrames loaded.
2390 * @return an array of AlignFrame, or null if none found
2392 public static AlignFrame[] getAlignFrames()
2394 if (Jalview.isHeadlessMode())
2396 // Desktop.desktop is null in headless mode
2397 return new AlignFrame[] { Jalview.currentAlignFrame };
2400 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2406 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2408 for (int i = frames.length - 1; i > -1; i--)
2410 if (frames[i] instanceof AlignFrame)
2412 avp.add((AlignFrame) frames[i]);
2414 else if (frames[i] instanceof SplitFrame)
2417 * Also check for a split frame containing an AlignFrame
2419 GSplitFrame sf = (GSplitFrame) frames[i];
2420 if (sf.getTopFrame() instanceof AlignFrame)
2422 avp.add((AlignFrame) sf.getTopFrame());
2424 if (sf.getBottomFrame() instanceof AlignFrame)
2426 avp.add((AlignFrame) sf.getBottomFrame());
2430 if (avp.size() == 0)
2434 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2439 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2443 public GStructureViewer[] getJmols()
2445 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2451 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2453 for (int i = frames.length - 1; i > -1; i--)
2455 if (frames[i] instanceof AppJmol)
2457 GStructureViewer af = (GStructureViewer) frames[i];
2461 if (avp.size() == 0)
2465 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2470 * Add Groovy Support to Jalview
2472 public void groovyShell_actionPerformed()
2476 openGroovyConsole();
2477 } catch (Exception ex)
2479 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2480 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2482 MessageManager.getString("label.couldnt_create_groovy_shell"),
2483 MessageManager.getString("label.groovy_support_failed"),
2484 JOptionPane.ERROR_MESSAGE);
2489 * Open the Groovy console
2491 void openGroovyConsole()
2493 if (groovyConsole == null)
2495 groovyConsole = new groovy.ui.Console();
2496 groovyConsole.setVariable("Jalview", this);
2497 groovyConsole.run();
2500 * We allow only one console at a time, so that AlignFrame menu option
2501 * 'Calculate | Run Groovy script' is unambiguous.
2502 * Disable 'Groovy Console', and enable 'Run script', when the console is
2503 * opened, and the reverse when it is closed
2505 Window window = (Window) groovyConsole.getFrame();
2506 window.addWindowListener(new WindowAdapter()
2509 public void windowClosed(WindowEvent e)
2512 * rebind CMD-Q from Groovy Console to Jalview Quit
2515 enableExecuteGroovy(false);
2521 * show Groovy console window (after close and reopen)
2523 ((Window) groovyConsole.getFrame()).setVisible(true);
2526 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2527 * and disable opening a second console
2529 enableExecuteGroovy(true);
2533 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2534 * binding when opened
2536 protected void addQuitHandler()
2538 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
2539 KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
2540 .getDefaultToolkit().getMenuShortcutKeyMask()),
2542 getRootPane().getActionMap().put("Quit", new AbstractAction()
2545 public void actionPerformed(ActionEvent e)
2553 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2556 * true if Groovy console is open
2558 public void enableExecuteGroovy(boolean enabled)
2561 * disable opening a second Groovy console
2562 * (or re-enable when the console is closed)
2564 groovyShell.setEnabled(!enabled);
2566 AlignFrame[] alignFrames = getAlignFrames();
2567 if (alignFrames != null)
2569 for (AlignFrame af : alignFrames)
2571 af.setGroovyEnabled(enabled);
2577 * Progress bars managed by the IProgressIndicator method.
2579 private Hashtable<Long, JPanel> progressBars;
2581 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2586 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2589 public void setProgressBar(String message, long id)
2591 if (progressBars == null)
2593 progressBars = new Hashtable<Long, JPanel>();
2594 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2597 if (progressBars.get(new Long(id)) != null)
2599 JPanel panel = progressBars.remove(new Long(id));
2600 if (progressBarHandlers.contains(new Long(id)))
2602 progressBarHandlers.remove(new Long(id));
2604 removeProgressPanel(panel);
2608 progressBars.put(new Long(id), addProgressPanel(message));
2615 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2616 * jalview.gui.IProgressIndicatorHandler)
2619 public void registerHandler(final long id,
2620 final IProgressIndicatorHandler handler)
2622 if (progressBarHandlers == null
2623 || !progressBars.containsKey(new Long(id)))
2627 .getString("error.call_setprogressbar_before_registering_handler"));
2629 progressBarHandlers.put(new Long(id), handler);
2630 final JPanel progressPanel = progressBars.get(new Long(id));
2631 if (handler.canCancel())
2633 JButton cancel = new JButton(
2634 MessageManager.getString("action.cancel"));
2635 final IProgressIndicator us = this;
2636 cancel.addActionListener(new ActionListener()
2640 public void actionPerformed(ActionEvent e)
2642 handler.cancelActivity(id);
2643 us.setProgressBar(MessageManager.formatMessage(
2644 "label.cancelled_params",
2645 new Object[] { ((JLabel) progressPanel.getComponent(0))
2649 progressPanel.add(cancel, BorderLayout.EAST);
2655 * @return true if any progress bars are still active
2658 public boolean operationInProgress()
2660 if (progressBars != null && progressBars.size() > 0)
2668 * This will return the first AlignFrame holding the given viewport instance.
2669 * It will break if there are more than one AlignFrames viewing a particular
2673 * @return alignFrame for viewport
2675 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2677 if (desktop != null)
2679 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2680 for (int panel = 0; aps != null && panel < aps.length; panel++)
2682 if (aps[panel] != null && aps[panel].av == viewport)
2684 return aps[panel].alignFrame;
2691 public VamsasApplication getVamsasApplication()
2698 * flag set if jalview GUI is being operated programmatically
2700 private boolean inBatchMode = false;
2703 * check if jalview GUI is being operated programmatically
2705 * @return inBatchMode
2707 public boolean isInBatchMode()
2713 * set flag if jalview GUI is being operated programmatically
2715 * @param inBatchMode
2717 public void setInBatchMode(boolean inBatchMode)
2719 this.inBatchMode = inBatchMode;
2722 public void startServiceDiscovery()
2724 startServiceDiscovery(false);
2727 public void startServiceDiscovery(boolean blocking)
2729 boolean alive = true;
2730 Thread t0 = null, t1 = null, t2 = null;
2731 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2734 // todo: changesupport handlers need to be transferred
2735 if (discoverer == null)
2737 discoverer = new jalview.ws.jws1.Discoverer();
2738 // register PCS handler for desktop.
2739 discoverer.addPropertyChangeListener(changeSupport);
2741 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2742 // until we phase out completely
2743 (t0 = new Thread(discoverer)).start();
2746 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2748 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2750 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2752 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2758 // TODO: do rest service discovery
2767 } catch (Exception e)
2770 alive = (t1 != null && t1.isAlive())
2771 || (t2 != null && t2.isAlive())
2772 || (t3 != null && t3.isAlive())
2773 || (t0 != null && t0.isAlive());
2779 * called to check if the service discovery process completed successfully.
2783 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2785 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2787 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2788 .getErrorMessages();
2791 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2793 if (serviceChangedDialog == null)
2795 // only run if we aren't already displaying one of these.
2796 addDialogThread(serviceChangedDialog = new Runnable()
2803 * JalviewDialog jd =new JalviewDialog() {
2805 * @Override protected void cancelPressed() { // TODO
2806 * Auto-generated method stub
2808 * }@Override protected void okPressed() { // TODO
2809 * Auto-generated method stub
2811 * }@Override protected void raiseClosed() { // TODO
2812 * Auto-generated method stub
2814 * } }; jd.initDialogFrame(new
2815 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2816 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2817 * + " or mis-configured HTTP proxy settings.<br/>" +
2818 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2820 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2821 * ), true, true, "Web Service Configuration Problem", 450,
2824 * jd.waitForInput();
2830 "<html><table width=\"450\"><tr><td>"
2832 + "</td></tr></table>"
2833 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2834 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2835 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2836 + " Tools->Preferences dialog box to change them.</p></html>"),
2837 "Web Service Configuration Problem",
2838 JOptionPane.DEFAULT_OPTION,
2839 JOptionPane.ERROR_MESSAGE);
2840 serviceChangedDialog = null;
2849 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2856 private Runnable serviceChangedDialog = null;
2859 * start a thread to open a URL in the configured browser. Pops up a warning
2860 * dialog to the user if there is an exception when calling out to the browser
2865 public static void showUrl(final String url)
2867 showUrl(url, Desktop.instance);
2871 * Like showUrl but allows progress handler to be specified
2875 * (null) or object implementing IProgressIndicator
2877 public static void showUrl(final String url,
2878 final IProgressIndicator progress)
2880 new Thread(new Runnable()
2887 if (progress != null)
2889 progress.setProgressBar(MessageManager.formatMessage(
2890 "status.opening_params", new Object[] { url }), this
2893 jalview.util.BrowserLauncher.openURL(url);
2894 } catch (Exception ex)
2896 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2898 .getString("label.web_browser_not_found_unix"),
2899 MessageManager.getString("label.web_browser_not_found"),
2900 JOptionPane.WARNING_MESSAGE);
2902 ex.printStackTrace();
2904 if (progress != null)
2906 progress.setProgressBar(null, this.hashCode());
2912 public static WsParamSetManager wsparamManager = null;
2914 public static ParamManager getUserParameterStore()
2916 if (wsparamManager == null)
2918 wsparamManager = new WsParamSetManager();
2920 return wsparamManager;
2924 * static hyperlink handler proxy method for use by Jalview's internal windows
2928 public static void hyperlinkUpdate(HyperlinkEvent e)
2930 if (e.getEventType() == EventType.ACTIVATED)
2935 url = e.getURL().toString();
2936 Desktop.showUrl(url);
2937 } catch (Exception x)
2941 if (Cache.log != null)
2943 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2947 System.err.println("Couldn't handle string " + url
2951 // ignore any exceptions due to dud links.
2958 * single thread that handles display of dialogs to user.
2960 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2963 * flag indicating if dialogExecutor should try to acquire a permit
2965 private volatile boolean dialogPause = true;
2970 private java.util.concurrent.Semaphore block = new Semaphore(0);
2972 private static groovy.ui.Console groovyConsole;
2975 * add another dialog thread to the queue
2979 public void addDialogThread(final Runnable prompter)
2981 dialogExecutor.submit(new Runnable()
2991 } catch (InterruptedException x)
2996 if (instance == null)
3002 SwingUtilities.invokeAndWait(prompter);
3003 } catch (Exception q)
3005 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3011 public void startDialogQueue()
3013 // set the flag so we don't pause waiting for another permit and semaphore
3014 // the current task to begin
3015 dialogPause = false;
3020 protected void snapShotWindow_actionPerformed(ActionEvent e)
3024 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3025 "View of Desktop", getWidth(), getHeight(), of = new File(
3026 "Jalview_snapshot" + System.currentTimeMillis()
3027 + ".eps"), "View of desktop", null, 0, false);
3030 paintAll(im.getGraphics());
3032 } catch (Exception q)
3034 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3038 Cache.log.info("Successfully written snapshot to file "
3039 + of.getAbsolutePath());
3043 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3044 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3045 * and location last time the view was expanded (if any). However it does not
3046 * remember the split pane divider location - this is set to match the
3047 * 'exploding' frame.
3051 public void explodeViews(SplitFrame sf)
3053 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3054 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3055 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3057 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3059 int viewCount = topPanels.size();
3066 * Processing in reverse order works, forwards order leaves the first panels
3067 * not visible. I don't know why!
3069 for (int i = viewCount - 1; i >= 0; i--)
3072 * Make new top and bottom frames. These take over the respective
3073 * AlignmentPanel objects, including their AlignmentViewports, so the
3074 * cdna/protein relationships between the viewports is carried over to the
3077 * explodedGeometry holds the (x, y) position of the previously exploded
3078 * SplitFrame, and the (width, height) of the AlignFrame component
3080 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3081 AlignFrame newTopFrame = new AlignFrame(topPanel);
3082 newTopFrame.setSize(oldTopFrame.getSize());
3083 newTopFrame.setVisible(true);
3084 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3085 .getExplodedGeometry();
3086 if (geometry != null)
3088 newTopFrame.setSize(geometry.getSize());
3091 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3092 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3093 newBottomFrame.setSize(oldBottomFrame.getSize());
3094 newBottomFrame.setVisible(true);
3095 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3096 .getExplodedGeometry();
3097 if (geometry != null)
3099 newBottomFrame.setSize(geometry.getSize());
3102 topPanel.av.setGatherViewsHere(false);
3103 bottomPanel.av.setGatherViewsHere(false);
3104 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3106 if (geometry != null)
3108 splitFrame.setLocation(geometry.getLocation());
3110 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3114 * Clear references to the panels (now relocated in the new SplitFrames)
3115 * before closing the old SplitFrame.
3118 bottomPanels.clear();
3123 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3124 * back into the given SplitFrame as additional views. Note that the gathered
3125 * frames may themselves have multiple views.
3129 public void gatherViews(GSplitFrame source)
3132 * special handling of explodedGeometry for a view within a SplitFrame: - it
3133 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3134 * height) of the AlignFrame component
3136 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3137 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3138 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3139 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3140 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3141 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3143 myTopFrame.viewport.setGatherViewsHere(true);
3144 myBottomFrame.viewport.setGatherViewsHere(true);
3145 String topViewId = myTopFrame.viewport.getSequenceSetId();
3146 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3148 JInternalFrame[] frames = desktop.getAllFrames();
3149 for (JInternalFrame frame : frames)
3151 if (frame instanceof SplitFrame && frame != source)
3153 SplitFrame sf = (SplitFrame) frame;
3154 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3155 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3156 boolean gatherThis = false;
3157 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3159 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3160 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3161 if (topViewId.equals(topPanel.av.getSequenceSetId())
3162 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3165 topPanel.av.setGatherViewsHere(false);
3166 bottomPanel.av.setGatherViewsHere(false);
3167 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3168 topFrame.getSize()));
3169 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3170 .getLocation(), bottomFrame.getSize()));
3171 myTopFrame.addAlignmentPanel(topPanel, false);
3172 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3178 topFrame.getAlignPanels().clear();
3179 bottomFrame.getAlignPanels().clear();
3186 * The dust settles...give focus to the tab we did this from.
3188 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3191 public static groovy.ui.Console getGroovyConsole()
3193 return groovyConsole;
3196 public static void transferFromDropTarget(List<String> files,
3197 List<DataSourceType> protocols, DropTargetDropEvent evt,
3202 DataFlavor uriListFlavor = new DataFlavor(
3203 "text/uri-list;class=java.lang.String");
3204 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3206 // Works on Windows and MacOSX
3207 Cache.log.debug("Drop handled as javaFileListFlavor");
3208 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3209 for (Object file : (List) t
3210 .getTransferData(DataFlavor.javaFileListFlavor))
3212 files.add(((File)file).toString());
3213 protocols.add(DataSourceType.FILE);
3218 // Unix like behaviour
3219 boolean added = false;
3221 if (t.isDataFlavorSupported(uriListFlavor))
3223 Cache.log.debug("Drop handled as uriListFlavor");
3224 // This is used by Unix drag system
3225 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3226 data = (String) t.getTransferData(uriListFlavor);
3230 // fallback to text: workaround - on OSX where there's a JVM bug
3231 Cache.log.debug("standard URIListFlavor failed. Trying text");
3232 // try text fallback
3233 data = (String) t.getTransferData(new DataFlavor(
3234 "text/plain;class=java.lang.String"));
3235 if (Cache.log.isDebugEnabled())
3237 Cache.log.debug("fallback returned " + data);
3240 while (protocols.size() < files.size())
3242 Cache.log.debug("Adding missing FILE protocol for "
3243 + files.get(protocols.size()));
3244 protocols.add(DataSourceType.FILE);
3246 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3247 data, "\r\n"); st.hasMoreTokens();)
3250 String s = st.nextToken();
3251 if (s.startsWith("#"))
3253 // the line is a comment (as per the RFC 2483)
3256 java.net.URI uri = new java.net.URI(s);
3257 if (uri.getScheme().toLowerCase().startsWith("http"))
3259 protocols.add(DataSourceType.URL);
3260 files.add(uri.toString());
3264 // otherwise preserve old behaviour: catch all for file objects
3265 java.io.File file = new java.io.File(uri);
3266 protocols.add(DataSourceType.FILE);
3267 files.add(file.toString());
3270 if (Cache.log.isDebugEnabled())
3272 if (data == null || !added)
3275 .debug("Couldn't resolve drop data. Here are the supported flavors:");
3276 for (DataFlavor fl : t.getTransferDataFlavors())
3278 Cache.log.debug("Supported transfer dataflavor: "
3280 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
3281 Object df = t.getTransferData(fl);
3284 Cache.log.debug("Retrieves: " + df);
3288 Cache.log.debug("Retrieved nothing");