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 static jalview.util.UrlConstants.SEQUENCE_ID;
25 import jalview.api.AlignViewportI;
26 import jalview.api.AlignmentViewPanel;
27 import jalview.bin.Cache;
28 import jalview.bin.Jalview;
29 import jalview.io.DataSourceType;
30 import jalview.io.FileFormat;
31 import jalview.io.FileFormatException;
32 import jalview.io.FileFormatI;
33 import jalview.io.FileFormats;
34 import jalview.io.FileLoader;
35 import jalview.io.IdentifyFile;
36 import jalview.io.JalviewFileChooser;
37 import jalview.io.JalviewFileView;
38 import jalview.jbgui.GSplitFrame;
39 import jalview.jbgui.GStructureViewer;
40 import jalview.structure.StructureSelectionManager;
41 import jalview.urls.IdOrgSettings;
42 import jalview.util.ImageMaker;
43 import jalview.util.MessageManager;
44 import jalview.util.Platform;
45 import jalview.util.UrlConstants;
46 import jalview.viewmodel.AlignmentViewport;
47 import jalview.ws.params.ParamManager;
48 import jalview.ws.utils.UrlDownloadClient;
50 import java.awt.BorderLayout;
51 import java.awt.Color;
52 import java.awt.Dimension;
53 import java.awt.FontMetrics;
54 import java.awt.Graphics;
55 import java.awt.GridLayout;
56 import java.awt.Point;
57 import java.awt.Rectangle;
58 import java.awt.Toolkit;
59 import java.awt.Window;
60 import java.awt.datatransfer.Clipboard;
61 import java.awt.datatransfer.ClipboardOwner;
62 import java.awt.datatransfer.DataFlavor;
63 import java.awt.datatransfer.Transferable;
64 import java.awt.dnd.DnDConstants;
65 import java.awt.dnd.DropTargetDragEvent;
66 import java.awt.dnd.DropTargetDropEvent;
67 import java.awt.dnd.DropTargetEvent;
68 import java.awt.dnd.DropTargetListener;
69 import java.awt.event.ActionEvent;
70 import java.awt.event.ActionListener;
71 import java.awt.event.FocusEvent;
72 import java.awt.event.FocusListener;
73 import java.awt.event.KeyEvent;
74 import java.awt.event.MouseAdapter;
75 import java.awt.event.MouseEvent;
76 import java.awt.event.WindowAdapter;
77 import java.awt.event.WindowEvent;
78 import java.beans.PropertyChangeEvent;
79 import java.beans.PropertyChangeListener;
80 import java.io.BufferedInputStream;
82 import java.io.FileOutputStream;
83 import java.io.IOException;
85 import java.util.ArrayList;
86 import java.util.Hashtable;
87 import java.util.List;
88 import java.util.ListIterator;
89 import java.util.StringTokenizer;
90 import java.util.Vector;
91 import java.util.concurrent.ExecutorService;
92 import java.util.concurrent.Executors;
93 import java.util.concurrent.Semaphore;
95 import javax.swing.AbstractAction;
96 import javax.swing.Box;
97 import javax.swing.BoxLayout;
98 import javax.swing.DefaultDesktopManager;
99 import javax.swing.DesktopManager;
100 import javax.swing.JButton;
101 import javax.swing.JCheckBox;
102 import javax.swing.JComboBox;
103 import javax.swing.JComponent;
104 import javax.swing.JDesktopPane;
105 import javax.swing.JFrame;
106 import javax.swing.JInternalFrame;
107 import javax.swing.JLabel;
108 import javax.swing.JMenuItem;
109 import javax.swing.JPanel;
110 import javax.swing.JPopupMenu;
111 import javax.swing.JProgressBar;
112 import javax.swing.KeyStroke;
113 import javax.swing.SwingUtilities;
114 import javax.swing.event.HyperlinkEvent;
115 import javax.swing.event.HyperlinkEvent.EventType;
116 import javax.swing.event.InternalFrameAdapter;
117 import javax.swing.event.InternalFrameEvent;
118 import javax.swing.event.MenuEvent;
119 import javax.swing.event.MenuListener;
126 * @version $Revision: 1.155 $
128 public class Desktop extends jalview.jbgui.GDesktop implements
129 DropTargetListener, ClipboardOwner, IProgressIndicator,
130 jalview.api.StructureSelectionManagerProvider
132 private static int DEFAULT_MIN_WIDTH = 300;
134 private static int DEFAULT_MIN_HEIGHT = 250;
136 private static final String EXPERIMENTAL_FEATURES = "EXPERIMENTAL_FEATURES";
138 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
141 * news reader - null if it was never started.
143 private BlogReader jvnews = null;
145 private File projectFile;
149 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
151 public void addJalviewPropertyChangeListener(
152 PropertyChangeListener listener)
154 changeSupport.addJalviewPropertyChangeListener(listener);
158 * @param propertyName
160 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
161 * java.beans.PropertyChangeListener)
163 public void addJalviewPropertyChangeListener(String propertyName,
164 PropertyChangeListener listener)
166 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
170 * @param propertyName
172 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
173 * java.beans.PropertyChangeListener)
175 public void removeJalviewPropertyChangeListener(String propertyName,
176 PropertyChangeListener listener)
178 changeSupport.removeJalviewPropertyChangeListener(propertyName,
182 /** Singleton Desktop instance */
183 public static Desktop instance;
185 public static MyDesktopPane desktop;
187 static int openFrameCount = 0;
189 static final int xOffset = 30;
191 static final int yOffset = 30;
193 public static jalview.ws.jws1.Discoverer discoverer;
195 public static Object[] jalviewClipboard;
197 public static boolean internalCopy = false;
199 static int fileLoadingCount = 0;
201 class MyDesktopManager implements DesktopManager
204 private DesktopManager delegate;
206 public MyDesktopManager(DesktopManager delegate)
208 this.delegate = delegate;
212 public void activateFrame(JInternalFrame f)
216 delegate.activateFrame(f);
217 } catch (NullPointerException npe)
219 Point p = getMousePosition();
220 instance.showPasteMenu(p.x, p.y);
225 public void beginDraggingFrame(JComponent f)
227 delegate.beginDraggingFrame(f);
231 public void beginResizingFrame(JComponent f, int direction)
233 delegate.beginResizingFrame(f, direction);
237 public void closeFrame(JInternalFrame f)
239 delegate.closeFrame(f);
243 public void deactivateFrame(JInternalFrame f)
245 delegate.deactivateFrame(f);
249 public void deiconifyFrame(JInternalFrame f)
251 delegate.deiconifyFrame(f);
255 public void dragFrame(JComponent f, int newX, int newY)
261 delegate.dragFrame(f, newX, newY);
265 public void endDraggingFrame(JComponent f)
267 delegate.endDraggingFrame(f);
271 public void endResizingFrame(JComponent f)
273 delegate.endResizingFrame(f);
277 public void iconifyFrame(JInternalFrame f)
279 delegate.iconifyFrame(f);
283 public void maximizeFrame(JInternalFrame f)
285 delegate.maximizeFrame(f);
289 public void minimizeFrame(JInternalFrame f)
291 delegate.minimizeFrame(f);
295 public void openFrame(JInternalFrame f)
297 delegate.openFrame(f);
301 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
308 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
312 public void setBoundsForFrame(JComponent f, int newX, int newY,
313 int newWidth, int newHeight)
315 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
318 // All other methods, simply delegate
323 * Creates a new Desktop object.
328 * A note to implementors. It is ESSENTIAL that any activities that might
329 * block are spawned off as threads rather than waited for during this
333 doVamsasClientCheck();
335 doConfigureStructurePrefs();
336 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
337 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
338 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
340 boolean showjconsole = jalview.bin.Cache.getDefault(
341 "SHOW_JAVA_CONSOLE", false);
342 desktop = new MyDesktopPane(selmemusage);
343 if (Platform.isAMac())
345 desktop.setDoubleBuffered(false);
347 showMemusage.setSelected(selmemusage);
348 desktop.setBackground(Color.white);
349 getContentPane().setLayout(new BorderLayout());
350 // alternate config - have scrollbars - see notes in JAL-153
351 // JScrollPane sp = new JScrollPane();
352 // sp.getViewport().setView(desktop);
353 // getContentPane().add(sp, BorderLayout.CENTER);
354 getContentPane().add(desktop, BorderLayout.CENTER);
355 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
357 // This line prevents Windows Look&Feel resizing all new windows to maximum
358 // if previous window was maximised
359 desktop.setDesktopManager(new MyDesktopManager(
360 new DefaultDesktopManager()));
362 Rectangle dims = getLastKnownDimensions("");
369 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
370 setBounds((screenSize.width - 900) / 2,
371 (screenSize.height - 650) / 2, 900, 650);
373 jconsole = new Console(this, showjconsole);
374 // add essential build information
375 jconsole.setHeader("Jalview Version: "
376 + jalview.bin.Cache.getProperty("VERSION") + "\n"
377 + "Jalview Installation: "
378 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
379 + "\n" + "Build Date: "
380 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
381 + "Java version: " + System.getProperty("java.version") + "\n"
382 + System.getProperty("os.arch") + " "
383 + System.getProperty("os.name") + " "
384 + System.getProperty("os.version"));
386 showConsole(showjconsole);
388 showNews.setVisible(false);
390 experimentalFeatures.setSelected(showExperimental());
392 getIdentifiersOrgData();
396 this.addWindowListener(new WindowAdapter()
399 public void windowClosing(WindowEvent evt)
406 this.addMouseListener(ma = new MouseAdapter()
409 public void mousePressed(MouseEvent evt)
411 if (evt.isPopupTrigger()) // Mac
413 showPasteMenu(evt.getX(), evt.getY());
418 public void mouseReleased(MouseEvent evt)
420 if (evt.isPopupTrigger()) // Windows
422 showPasteMenu(evt.getX(), evt.getY());
426 desktop.addMouseListener(ma);
428 this.addFocusListener(new FocusListener()
432 public void focusLost(FocusEvent e)
434 // TODO Auto-generated method stub
439 public void focusGained(FocusEvent e)
441 Cache.log.debug("Relaying windows after focus gain");
442 // make sure that we sort windows properly after we gain focus
443 instance.relayerWindows();
446 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
447 // Spawn a thread that shows the splashscreen
448 SwingUtilities.invokeLater(new Runnable()
457 // Thread off a new instance of the file chooser - this reduces the time it
458 // takes to open it later on.
459 new Thread(new Runnable()
464 Cache.log.debug("Filechooser init thread started.");
465 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
466 JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"),
468 Cache.log.debug("Filechooser init thread finished.");
471 // Add the service change listener
472 changeSupport.addJalviewPropertyChangeListener("services",
473 new PropertyChangeListener()
477 public void propertyChange(PropertyChangeEvent evt)
479 Cache.log.debug("Firing service changed event for "
480 + evt.getNewValue());
481 JalviewServicesChanged(evt);
488 * Answers true if user preferences to enable experimental features is True
493 public boolean showExperimental()
495 String experimental = Cache.getDefault(EXPERIMENTAL_FEATURES,
496 Boolean.FALSE.toString());
497 return Boolean.valueOf(experimental).booleanValue();
500 public void doConfigureStructurePrefs()
502 // configure services
503 StructureSelectionManager ssm = StructureSelectionManager
504 .getStructureSelectionManager(this);
505 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
507 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
508 Preferences.ADD_TEMPFACT_ANN, true));
509 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(
510 Preferences.STRUCT_FROM_PDB, true));
511 ssm.setSecStructServices(jalview.bin.Cache.getDefault(
512 Preferences.USE_RNAVIEW, true));
516 ssm.setAddTempFacAnnot(false);
517 ssm.setProcessSecondaryStructure(false);
518 ssm.setSecStructServices(false);
522 public void checkForNews()
524 final Desktop me = this;
525 // Thread off the news reader, in case there are connection problems.
526 addDialogThread(new Runnable()
531 Cache.log.debug("Starting news thread.");
533 jvnews = new BlogReader(me);
534 showNews.setVisible(true);
535 Cache.log.debug("Completed news thread.");
540 public void getIdentifiersOrgData()
542 // Thread off the identifiers fetcher
543 addDialogThread(new Runnable()
548 Cache.log.debug("Downloading data from identifiers.org");
549 UrlDownloadClient client = new UrlDownloadClient();
552 client.download(IdOrgSettings.getUrl(),
553 IdOrgSettings.getDownloadLocation());
554 } catch (IOException e)
556 Cache.log.debug("Exception downloading identifiers.org data"
564 protected void showNews_actionPerformed(ActionEvent e)
566 showNews(showNews.isSelected());
569 void showNews(boolean visible)
572 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
573 showNews.setSelected(visible);
574 if (visible && !jvnews.isVisible())
576 new Thread(new Runnable()
581 long now = System.currentTimeMillis();
582 Desktop.instance.setProgressBar(
583 MessageManager.getString("status.refreshing_news"), now);
584 jvnews.refreshNews();
585 Desktop.instance.setProgressBar(null, now);
594 * recover the last known dimensions for a jalview window
597 * - empty string is desktop, all other windows have unique prefix
598 * @return null or last known dimensions scaled to current geometry (if last
599 * window geom was known)
601 Rectangle getLastKnownDimensions(String windowName)
603 // TODO: lock aspect ratio for scaling desktop Bug #0058199
604 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
605 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
606 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
607 String width = jalview.bin.Cache.getProperty(windowName
609 String height = jalview.bin.Cache.getProperty(windowName
611 if ((x != null) && (y != null) && (width != null) && (height != null))
613 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
614 .parseInt(width), ih = Integer.parseInt(height);
615 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
617 // attempt #1 - try to cope with change in screen geometry - this
618 // version doesn't preserve original jv aspect ratio.
619 // take ratio of current screen size vs original screen size.
620 double sw = ((1f * screenSize.width) / (1f * Integer
621 .parseInt(jalview.bin.Cache
622 .getProperty("SCREENGEOMETRY_WIDTH"))));
623 double sh = ((1f * screenSize.height) / (1f * Integer
624 .parseInt(jalview.bin.Cache
625 .getProperty("SCREENGEOMETRY_HEIGHT"))));
626 // rescale the bounds depending upon the current screen geometry.
627 ix = (int) (ix * sw);
628 iw = (int) (iw * sw);
629 iy = (int) (iy * sh);
630 ih = (int) (ih * sh);
631 while (ix >= screenSize.width)
633 jalview.bin.Cache.log
634 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
635 ix -= screenSize.width;
637 while (iy >= screenSize.height)
639 jalview.bin.Cache.log
640 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
641 iy -= screenSize.height;
643 jalview.bin.Cache.log.debug("Got last known dimensions for "
644 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
647 // return dimensions for new instance
648 return new Rectangle(ix, iy, iw, ih);
653 private void doVamsasClientCheck()
655 if (jalview.bin.Cache.vamsasJarsPresent())
657 setupVamsasDisconnectedGui();
658 VamsasMenu.setVisible(true);
659 final Desktop us = this;
660 VamsasMenu.addMenuListener(new MenuListener()
662 // this listener remembers when the menu was first selected, and
663 // doesn't rebuild the session list until it has been cleared and
665 boolean refresh = true;
668 public void menuCanceled(MenuEvent e)
674 public void menuDeselected(MenuEvent e)
680 public void menuSelected(MenuEvent e)
684 us.buildVamsasStMenu();
689 vamsasStart.setVisible(true);
693 void showPasteMenu(int x, int y)
695 JPopupMenu popup = new JPopupMenu();
696 JMenuItem item = new JMenuItem(
697 MessageManager.getString("label.paste_new_window"));
698 item.addActionListener(new ActionListener()
701 public void actionPerformed(ActionEvent evt)
708 popup.show(this, x, y);
715 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
716 Transferable contents = c.getContents(this);
718 if (contents != null)
720 String file = (String) contents
721 .getTransferData(DataFlavor.stringFlavor);
723 FileFormatI format = new IdentifyFile().identify(file,
724 DataSourceType.PASTE);
726 new FileLoader().LoadFile(file, DataSourceType.PASTE, format);
729 } catch (Exception ex)
732 .println("Unable to paste alignment from system clipboard:\n"
738 * Adds and opens the given frame to the desktop
749 public static synchronized void addInternalFrame(
750 final JInternalFrame frame, String title, int w, int h)
752 addInternalFrame(frame, title, true, w, h, true, false);
756 * Add an internal frame to the Jalview desktop
763 * When true, display frame immediately, otherwise, caller must call
764 * setVisible themselves.
770 public static synchronized void addInternalFrame(
771 final JInternalFrame frame, String title, boolean makeVisible,
774 addInternalFrame(frame, title, makeVisible, w, h, true, false);
778 * Add an internal frame to the Jalview desktop and make it visible
791 public static synchronized void addInternalFrame(
792 final JInternalFrame frame, String title, int w, int h,
795 addInternalFrame(frame, title, true, w, h, resizable, false);
799 * Add an internal frame to the Jalview desktop
806 * When true, display frame immediately, otherwise, caller must call
807 * setVisible themselves.
814 * @param ignoreMinSize
815 * Do not set the default minimum size for frame
817 public static synchronized void addInternalFrame(
818 final JInternalFrame frame, String title, boolean makeVisible,
819 int w, int h, boolean resizable, boolean ignoreMinSize)
822 // TODO: allow callers to determine X and Y position of frame (eg. via
824 // TODO: consider fixing method to update entries in the window submenu with
825 // the current window title
827 frame.setTitle(title);
828 if (frame.getWidth() < 1 || frame.getHeight() < 1)
832 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
833 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
834 // IF JALVIEW IS RUNNING HEADLESS
835 // ///////////////////////////////////////////////
837 || (System.getProperty("java.awt.headless") != null && System
838 .getProperty("java.awt.headless").equals("true")))
847 frame.setMinimumSize(new Dimension(DEFAULT_MIN_WIDTH,
848 DEFAULT_MIN_HEIGHT));
850 frame.setVisible(makeVisible);
851 frame.setClosable(true);
852 frame.setResizable(resizable);
853 frame.setMaximizable(resizable);
854 frame.setIconifiable(resizable);
855 if (Platform.isAMac())
857 frame.setIconifiable(false);
858 frame.setFrameIcon(null);
859 // frame.setDesktopIcon(null);
860 frame.setDoubleBuffered(false);
862 if (frame.getX() < 1 && frame.getY() < 1)
864 frame.setLocation(xOffset * openFrameCount, yOffset
865 * ((openFrameCount - 1) % 10) + yOffset);
869 * add an entry for the new frame in the Window menu
870 * (and remove it when the frame is closed)
872 final JMenuItem menuItem = new JMenuItem(title);
873 frame.addInternalFrameListener(new InternalFrameAdapter()
876 public void internalFrameActivated(InternalFrameEvent evt)
878 JInternalFrame itf = desktop.getSelectedFrame();
886 public void internalFrameClosed(InternalFrameEvent evt)
888 PaintRefresher.RemoveComponent(frame);
891 * defensive check to prevent frames being
892 * added half off the window
894 if (openFrameCount > 0)
900 * ensure no reference to alignFrame retained by menu item listener
902 if (menuItem.getActionListeners().length > 0)
904 menuItem.removeActionListener(menuItem.getActionListeners()[0]);
906 windowMenu.remove(menuItem);
907 JInternalFrame itf = desktop.getSelectedFrame();
911 if (itf instanceof AlignFrame)
913 Jalview.setCurrentAlignFrame((AlignFrame) itf);
920 menuItem.addActionListener(new ActionListener()
923 public void actionPerformed(ActionEvent e)
927 frame.setSelected(true);
928 frame.setIcon(false);
929 } catch (java.beans.PropertyVetoException ex)
938 windowMenu.add(menuItem);
943 frame.setSelected(true);
944 frame.requestFocus();
945 } catch (java.beans.PropertyVetoException ve)
947 } catch (java.lang.ClassCastException cex)
950 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
956 public void lostOwnership(Clipboard clipboard, Transferable contents)
960 Desktop.jalviewClipboard = null;
963 internalCopy = false;
967 public void dragEnter(DropTargetDragEvent evt)
972 public void dragExit(DropTargetEvent evt)
977 public void dragOver(DropTargetDragEvent evt)
982 public void dropActionChanged(DropTargetDragEvent evt)
993 public void drop(DropTargetDropEvent evt)
995 boolean success = true;
996 // JAL-1552 - acceptDrop required before getTransferable call for
997 // Java's Transferable for native dnd
998 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
999 Transferable t = evt.getTransferable();
1000 List<String> files = new ArrayList<String>();
1001 List<DataSourceType> protocols = new ArrayList<DataSourceType>();
1005 Desktop.transferFromDropTarget(files, protocols, evt, t);
1006 } catch (Exception e)
1008 e.printStackTrace();
1016 for (int i = 0; i < files.size(); i++)
1018 String file = files.get(i).toString();
1019 DataSourceType protocol = (protocols == null) ? DataSourceType.FILE
1021 FileFormatI format = null;
1023 if (file.endsWith(".jar"))
1025 format = FileFormat.Jalview;
1030 format = new IdentifyFile().identify(file, protocol);
1033 new FileLoader().LoadFile(file, protocol, format);
1036 } catch (Exception ex)
1041 evt.dropComplete(success); // need this to ensure input focus is properly
1042 // transfered to any new windows created
1052 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1054 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1055 JalviewFileChooser chooser = JalviewFileChooser.forRead(
1056 Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1058 chooser.setFileView(new JalviewFileView());
1059 chooser.setDialogTitle(MessageManager
1060 .getString("label.open_local_file"));
1061 chooser.setToolTipText(MessageManager.getString("action.open"));
1063 int value = chooser.showOpenDialog(this);
1065 if (value == JalviewFileChooser.APPROVE_OPTION)
1067 String choice = chooser.getSelectedFile().getPath();
1068 Cache.setProperty("LAST_DIRECTORY", chooser
1069 .getSelectedFile().getParent());
1071 FileFormatI format = chooser.getSelectedFormat();
1074 * Call IdentifyFile to verify the file contains what its extension implies.
1075 * Skip this step for dynamically added file formats, because
1076 * IdentifyFile does not know how to recognise them.
1078 if (FileFormats.getInstance().isIdentifiable(format))
1082 format = new IdentifyFile().identify(choice, DataSourceType.FILE);
1083 } catch (FileFormatException e)
1085 // format = null; //??
1089 if (viewport != null)
1091 new FileLoader().LoadFile(viewport, choice, DataSourceType.FILE,
1096 new FileLoader().LoadFile(choice, DataSourceType.FILE, format);
1108 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1110 // This construct allows us to have a wider textfield
1112 JLabel label = new JLabel(
1113 MessageManager.getString("label.input_file_url"));
1114 final JComboBox history = new JComboBox();
1116 JPanel panel = new JPanel(new GridLayout(2, 1));
1119 history.setPreferredSize(new Dimension(400, 20));
1120 history.setEditable(true);
1121 history.addItem("http://www.");
1123 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1127 if (historyItems != null)
1129 st = new StringTokenizer(historyItems, "\t");
1131 while (st.hasMoreTokens())
1133 history.addItem(st.nextElement());
1137 int reply = JvOptionPane.showInternalConfirmDialog(desktop, panel,
1138 MessageManager.getString("label.input_alignment_from_url"),
1139 JvOptionPane.OK_CANCEL_OPTION);
1141 if (reply != JvOptionPane.OK_OPTION)
1146 String url = history.getSelectedItem().toString();
1148 if (url.toLowerCase().endsWith(".jar"))
1150 if (viewport != null)
1152 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1153 FileFormat.Jalview);
1157 new FileLoader().LoadFile(url, DataSourceType.URL,
1158 FileFormat.Jalview);
1163 FileFormatI format = null;
1166 format = new IdentifyFile().identify(url, DataSourceType.URL);
1167 } catch (FileFormatException e)
1169 // TODO revise error handling, distinguish between
1170 // URL not found and response not valid
1175 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1176 MessageManager.formatMessage("label.couldnt_locate",
1177 new Object[] { url }), MessageManager
1178 .getString("label.url_not_found"),
1179 JvOptionPane.WARNING_MESSAGE);
1184 if (viewport != null)
1187 .LoadFile(viewport, url, DataSourceType.URL, format);
1191 new FileLoader().LoadFile(url, DataSourceType.URL, format);
1197 * Opens the CutAndPaste window for the user to paste an alignment in to
1200 * - if not null, the pasted alignment is added to the current
1201 * alignment; if null, to a new alignment window
1204 public void inputTextboxMenuItem_actionPerformed(
1205 AlignmentViewPanel viewPanel)
1207 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1208 cap.setForInput(viewPanel);
1209 Desktop.addInternalFrame(cap,
1210 MessageManager.getString("label.cut_paste_alignmen_file"),
1220 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1222 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1223 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1225 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1226 getBounds().y, getWidth(), getHeight()));
1228 if (jconsole != null)
1230 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1231 jconsole.stopConsole();
1235 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1238 if (dialogExecutor != null)
1240 dialogExecutor.shutdownNow();
1242 closeAll_actionPerformed(null);
1244 if (groovyConsole != null)
1246 // suppress a possible repeat prompt to save script
1247 groovyConsole.setDirty(false);
1248 groovyConsole.exit();
1253 private void storeLastKnownDimensions(String string, Rectangle jc)
1255 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1256 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1257 + " height:" + jc.height);
1259 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1260 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1261 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1262 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1272 public void aboutMenuItem_actionPerformed(ActionEvent e)
1274 // StringBuffer message = getAboutMessage(false);
1275 // JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1277 // message.toString(), "About Jalview", JvOptionPane.INFORMATION_MESSAGE);
1278 new Thread(new Runnable()
1283 new SplashScreen(true);
1288 public StringBuffer getAboutMessage(boolean shortv)
1290 StringBuffer message = new StringBuffer();
1291 message.append("<html>");
1294 message.append("<h1><strong>Version: "
1295 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1>");
1296 message.append("<strong>Last Updated: <em>"
1297 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1298 + "</em></strong>");
1304 message.append("<strong>Version "
1305 + jalview.bin.Cache.getProperty("VERSION")
1306 + "; last updated: "
1307 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1310 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1313 message.append("<br>...Checking latest version...</br>");
1315 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1316 .equals(jalview.bin.Cache.getProperty("VERSION")))
1318 boolean red = false;
1319 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1320 .indexOf("automated build") == -1)
1323 // Displayed when code version and jnlp version do not match and code
1324 // version is not a development build
1325 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1328 message.append("<br>!! Version "
1329 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1331 + " is available for download from "
1332 + jalview.bin.Cache.getDefault("www.jalview.org",
1333 "http://www.jalview.org") + " !!");
1336 message.append("</div>");
1339 message.append("<br>Authors: "
1341 .getDefault("AUTHORFNAMES",
1342 "The Jalview Authors (See AUTHORS file for current list)")
1343 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1344 + "<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"
1345 + "<br><br>If you use Jalview, please cite:"
1346 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1347 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1348 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1360 public void documentationMenuItem_actionPerformed(ActionEvent e)
1364 Help.showHelpWindow();
1365 } catch (Exception ex)
1371 public void closeAll_actionPerformed(ActionEvent e)
1373 // TODO show a progress bar while closing?
1374 JInternalFrame[] frames = desktop.getAllFrames();
1375 for (int i = 0; i < frames.length; i++)
1379 frames[i].setClosed(true);
1380 } catch (java.beans.PropertyVetoException ex)
1384 Jalview.setCurrentAlignFrame(null);
1385 System.out.println("ALL CLOSED");
1386 if (v_client != null)
1388 // TODO clear binding to vamsas document objects on close_all
1392 * reset state of singleton objects as appropriate (clear down session state
1393 * when all windows are closed)
1395 StructureSelectionManager ssm = StructureSelectionManager
1396 .getStructureSelectionManager(this);
1405 public void raiseRelated_actionPerformed(ActionEvent e)
1407 reorderAssociatedWindows(false, false);
1411 public void minimizeAssociated_actionPerformed(ActionEvent e)
1413 reorderAssociatedWindows(true, false);
1416 void closeAssociatedWindows()
1418 reorderAssociatedWindows(false, true);
1424 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1428 protected void garbageCollect_actionPerformed(ActionEvent e)
1430 // We simply collect the garbage
1431 jalview.bin.Cache.log.debug("Collecting garbage...");
1433 jalview.bin.Cache.log.debug("Finished garbage collection.");
1440 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1444 protected void showMemusage_actionPerformed(ActionEvent e)
1446 desktop.showMemoryUsage(showMemusage.isSelected());
1453 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1457 protected void showConsole_actionPerformed(ActionEvent e)
1459 showConsole(showConsole.isSelected());
1462 Console jconsole = null;
1465 * control whether the java console is visible or not
1469 void showConsole(boolean selected)
1471 showConsole.setSelected(selected);
1472 // TODO: decide if we should update properties file
1473 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1475 jconsole.setVisible(selected);
1478 void reorderAssociatedWindows(boolean minimize, boolean close)
1480 JInternalFrame[] frames = desktop.getAllFrames();
1481 if (frames == null || frames.length < 1)
1486 AlignmentViewport source = null, target = null;
1487 if (frames[0] instanceof AlignFrame)
1489 source = ((AlignFrame) frames[0]).getCurrentView();
1491 else if (frames[0] instanceof TreePanel)
1493 source = ((TreePanel) frames[0]).getViewPort();
1495 else if (frames[0] instanceof PCAPanel)
1497 source = ((PCAPanel) frames[0]).av;
1499 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1501 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1506 for (int i = 0; i < frames.length; i++)
1509 if (frames[i] == null)
1513 if (frames[i] instanceof AlignFrame)
1515 target = ((AlignFrame) frames[i]).getCurrentView();
1517 else if (frames[i] instanceof TreePanel)
1519 target = ((TreePanel) frames[i]).getViewPort();
1521 else if (frames[i] instanceof PCAPanel)
1523 target = ((PCAPanel) frames[i]).av;
1525 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1527 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1530 if (source == target)
1536 frames[i].setClosed(true);
1540 frames[i].setIcon(minimize);
1543 frames[i].toFront();
1547 } catch (java.beans.PropertyVetoException ex)
1562 protected void preferences_actionPerformed(ActionEvent e)
1574 public void saveState_actionPerformed(ActionEvent e)
1576 JalviewFileChooser chooser = new JalviewFileChooser("jvp",
1579 chooser.setFileView(new JalviewFileView());
1580 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1582 int value = chooser.showSaveDialog(this);
1584 if (value == JalviewFileChooser.APPROVE_OPTION)
1586 final Desktop me = this;
1587 final java.io.File choice = chooser.getSelectedFile();
1588 setProjectFile(choice);
1590 new Thread(new Runnable()
1595 // TODO: refactor to Jalview desktop session controller action.
1596 setProgressBar(MessageManager.formatMessage(
1597 "label.saving_jalview_project",
1598 new Object[] { choice.getName() }), choice.hashCode());
1599 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1600 choice.getParent());
1601 // TODO catch and handle errors for savestate
1602 // TODO prevent user from messing with the Desktop whilst we're saving
1605 new Jalview2XML().saveState(choice);
1606 } catch (OutOfMemoryError oom)
1608 new OOMWarning("Whilst saving current state to "
1609 + choice.getName(), oom);
1610 } catch (Exception ex)
1613 "Problems whilst trying to save to " + choice.getName(),
1615 JvOptionPane.showMessageDialog(me, MessageManager.formatMessage(
1616 "label.error_whilst_saving_current_state_to",
1617 new Object[] { choice.getName() }), MessageManager
1618 .getString("label.couldnt_save_project"),
1619 JvOptionPane.WARNING_MESSAGE);
1621 setProgressBar(null, choice.hashCode());
1627 private void setProjectFile(File choice)
1629 this.projectFile = choice;
1632 public File getProjectFile()
1634 return this.projectFile;
1644 public void loadState_actionPerformed(ActionEvent e)
1646 JalviewFileChooser chooser = new JalviewFileChooser(
1647 Cache.getProperty("LAST_DIRECTORY"), new String[] {
1648 "jvp", "jar" }, new String[] { "Jalview Project",
1649 "Jalview Project (old)" }, "Jalview Project");
1650 chooser.setFileView(new JalviewFileView());
1651 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1653 int value = chooser.showOpenDialog(this);
1655 if (value == JalviewFileChooser.APPROVE_OPTION)
1657 final File selectedFile = chooser.getSelectedFile();
1658 setProjectFile(selectedFile);
1659 final String choice = selectedFile.getAbsolutePath();
1660 Cache.setProperty("LAST_DIRECTORY",
1661 selectedFile.getParent());
1662 new Thread(new Runnable()
1668 MessageManager.formatMessage(
1669 "label.loading_jalview_project",
1670 new Object[] { choice }), choice.hashCode());
1673 new Jalview2XML().loadJalviewAlign(choice);
1674 } catch (OutOfMemoryError oom)
1676 new OOMWarning("Whilst loading project from " + choice, oom);
1677 } catch (Exception ex)
1679 Cache.log.error("Problems whilst loading project from "
1681 JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
1683 "label.error_whilst_loading_project_from",
1684 new Object[] { choice }), MessageManager
1685 .getString("label.couldnt_load_project"),
1686 JvOptionPane.WARNING_MESSAGE);
1688 setProgressBar(null, choice.hashCode());
1695 public void inputSequence_actionPerformed(ActionEvent e)
1697 new SequenceFetcher(this);
1700 JPanel progressPanel;
1702 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1704 public void startLoading(final String fileName)
1706 if (fileLoadingCount == 0)
1708 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage(
1709 "label.loading_file", new Object[] { fileName })));
1714 private JPanel addProgressPanel(String string)
1716 if (progressPanel == null)
1718 progressPanel = new JPanel(new GridLayout(1, 1));
1719 totalProgressCount = 0;
1720 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1722 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1723 JProgressBar progressBar = new JProgressBar();
1724 progressBar.setIndeterminate(true);
1726 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1728 thisprogress.add(progressBar, BorderLayout.CENTER);
1729 progressPanel.add(thisprogress);
1730 ((GridLayout) progressPanel.getLayout())
1731 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1732 ++totalProgressCount;
1733 instance.validate();
1734 return thisprogress;
1737 int totalProgressCount = 0;
1739 private void removeProgressPanel(JPanel progbar)
1741 if (progressPanel != null)
1743 synchronized (progressPanel)
1745 progressPanel.remove(progbar);
1746 GridLayout gl = (GridLayout) progressPanel.getLayout();
1747 gl.setRows(gl.getRows() - 1);
1748 if (--totalProgressCount < 1)
1750 this.getContentPane().remove(progressPanel);
1751 progressPanel = null;
1758 public void stopLoading()
1761 if (fileLoadingCount < 1)
1763 while (fileLoadingPanels.size() > 0)
1765 removeProgressPanel(fileLoadingPanels.remove(0));
1767 fileLoadingPanels.clear();
1768 fileLoadingCount = 0;
1773 public static int getViewCount(String alignmentId)
1775 AlignmentViewport[] aps = getViewports(alignmentId);
1776 return (aps == null) ? 0 : aps.length;
1781 * @param alignmentId
1782 * - if null, all sets are returned
1783 * @return all AlignmentPanels concerning the alignmentId sequence set
1785 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1787 if (Desktop.desktop == null)
1789 // no frames created and in headless mode
1790 // TODO: verify that frames are recoverable when in headless mode
1793 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1794 AlignFrame[] frames = getAlignFrames();
1799 for (AlignFrame af : frames)
1801 for (AlignmentPanel ap : af.alignPanels)
1803 if (alignmentId == null
1804 || alignmentId.equals(ap.av.getSequenceSetId()))
1810 if (aps.size() == 0)
1814 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1819 * get all the viewports on an alignment.
1821 * @param sequenceSetId
1822 * unique alignment id (may be null - all viewports returned in that
1824 * @return all viewports on the alignment bound to sequenceSetId
1826 public static AlignmentViewport[] getViewports(String sequenceSetId)
1828 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1829 if (desktop != null)
1831 AlignFrame[] frames = Desktop.getAlignFrames();
1833 for (AlignFrame afr : frames)
1835 if (sequenceSetId == null
1836 || afr.getViewport().getSequenceSetId()
1837 .equals(sequenceSetId))
1839 if (afr.alignPanels != null)
1841 for (AlignmentPanel ap : afr.alignPanels)
1843 if (sequenceSetId == null
1844 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1852 viewp.add(afr.getViewport());
1856 if (viewp.size() > 0)
1858 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1865 * Explode the views in the given frame into separate AlignFrame
1869 public static void explodeViews(AlignFrame af)
1871 int size = af.alignPanels.size();
1877 for (int i = 0; i < size; i++)
1879 AlignmentPanel ap = af.alignPanels.get(i);
1880 AlignFrame newaf = new AlignFrame(ap);
1883 * Restore the view's last exploded frame geometry if known. Multiple
1884 * views from one exploded frame share and restore the same (frame)
1885 * position and size.
1887 Rectangle geometry = ap.av.getExplodedGeometry();
1888 if (geometry != null)
1890 newaf.setBounds(geometry);
1893 ap.av.setGatherViewsHere(false);
1895 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1896 AlignFrame.DEFAULT_HEIGHT);
1899 af.alignPanels.clear();
1900 af.closeMenuItem_actionPerformed(true);
1905 * Gather expanded views (separate AlignFrame's) with the same sequence set
1906 * identifier back in to this frame as additional views, and close the
1907 * expanded views. Note the expanded frames may themselves have multiple
1908 * views. We take the lot.
1912 public void gatherViews(AlignFrame source)
1914 source.viewport.setGatherViewsHere(true);
1915 source.viewport.setExplodedGeometry(source.getBounds());
1916 JInternalFrame[] frames = desktop.getAllFrames();
1917 String viewId = source.viewport.getSequenceSetId();
1919 for (int t = 0; t < frames.length; t++)
1921 if (frames[t] instanceof AlignFrame && frames[t] != source)
1923 AlignFrame af = (AlignFrame) frames[t];
1924 boolean gatherThis = false;
1925 for (int a = 0; a < af.alignPanels.size(); a++)
1927 AlignmentPanel ap = af.alignPanels.get(a);
1928 if (viewId.equals(ap.av.getSequenceSetId()))
1931 ap.av.setGatherViewsHere(false);
1932 ap.av.setExplodedGeometry(af.getBounds());
1933 source.addAlignmentPanel(ap, false);
1939 af.alignPanels.clear();
1940 af.closeMenuItem_actionPerformed(true);
1947 jalview.gui.VamsasApplication v_client = null;
1950 public void vamsasImport_actionPerformed(ActionEvent e)
1952 if (v_client == null)
1954 // Load and try to start a session.
1955 JalviewFileChooser chooser = new JalviewFileChooser(
1956 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1958 chooser.setFileView(new JalviewFileView());
1959 chooser.setDialogTitle(MessageManager
1960 .getString("label.open_saved_vamsas_session"));
1961 chooser.setToolTipText(MessageManager
1962 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1964 int value = chooser.showOpenDialog(this);
1966 if (value == JalviewFileChooser.APPROVE_OPTION)
1968 String fle = chooser.getSelectedFile().toString();
1969 if (!vamsasImport(chooser.getSelectedFile()))
1972 .showInternalMessageDialog(
1974 MessageManager.formatMessage(
1975 "label.couldnt_import_as_vamsas_session",
1976 new Object[] { fle }),
1978 .getString("label.vamsas_document_import_failed"),
1979 JvOptionPane.ERROR_MESSAGE);
1985 jalview.bin.Cache.log
1986 .error("Implementation error - load session from a running session is not supported.");
1991 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1994 * @return true if import was a success and a session was started.
1996 public boolean vamsasImport(URL url)
1998 // TODO: create progress bar
1999 if (v_client != null)
2002 jalview.bin.Cache.log
2003 .error("Implementation error - load session from a running session is not supported.");
2009 // copy the URL content to a temporary local file
2010 // TODO: be a bit cleverer here with nio (?!)
2011 File file = File.createTempFile("vdocfromurl", ".vdj");
2012 FileOutputStream fos = new FileOutputStream(file);
2013 BufferedInputStream bis = new BufferedInputStream(url.openStream());
2014 byte[] buffer = new byte[2048];
2016 while ((ln = bis.read(buffer)) > -1)
2018 fos.write(buffer, 0, ln);
2022 v_client = new jalview.gui.VamsasApplication(this, file,
2023 url.toExternalForm());
2024 } catch (Exception ex)
2026 jalview.bin.Cache.log.error(
2027 "Failed to create new vamsas session from contents of URL "
2031 setupVamsasConnectedGui();
2032 v_client.initial_update(); // TODO: thread ?
2033 return v_client.inSession();
2037 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2040 * @return true if import was a success and a session was started.
2042 public boolean vamsasImport(File file)
2044 if (v_client != null)
2047 jalview.bin.Cache.log
2048 .error("Implementation error - load session from a running session is not supported.");
2052 setProgressBar(MessageManager.formatMessage(
2053 "status.importing_vamsas_session_from",
2054 new Object[] { file.getName() }), file.hashCode());
2057 v_client = new jalview.gui.VamsasApplication(this, file, null);
2058 } catch (Exception ex)
2060 setProgressBar(MessageManager.formatMessage(
2061 "status.importing_vamsas_session_from",
2062 new Object[] { file.getName() }), file.hashCode());
2063 jalview.bin.Cache.log.error(
2064 "New vamsas session from existing session file failed:", ex);
2067 setupVamsasConnectedGui();
2068 v_client.initial_update(); // TODO: thread ?
2069 setProgressBar(MessageManager.formatMessage(
2070 "status.importing_vamsas_session_from",
2071 new Object[] { file.getName() }), file.hashCode());
2072 return v_client.inSession();
2075 public boolean joinVamsasSession(String mysesid)
2077 if (v_client != null)
2081 .getString("error.try_join_vamsas_session_another"));
2083 if (mysesid == null)
2086 MessageManager.getString("error.invalid_vamsas_session_id"));
2088 v_client = new VamsasApplication(this, mysesid);
2089 setupVamsasConnectedGui();
2090 v_client.initial_update();
2091 return (v_client.inSession());
2095 public void vamsasStart_actionPerformed(ActionEvent e)
2097 if (v_client == null)
2100 // we just start a default session for moment.
2102 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2103 * getProperty("LAST_DIRECTORY"));
2105 * chooser.setFileView(new JalviewFileView());
2106 * chooser.setDialogTitle("Load Vamsas file");
2107 * chooser.setToolTipText("Import");
2109 * int value = chooser.showOpenDialog(this);
2111 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2112 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2114 v_client = new VamsasApplication(this);
2115 setupVamsasConnectedGui();
2116 v_client.initial_update(); // TODO: thread ?
2120 // store current data in session.
2121 v_client.push_update(); // TODO: thread
2125 protected void setupVamsasConnectedGui()
2127 vamsasStart.setText(MessageManager.getString("label.session_update"));
2128 vamsasSave.setVisible(true);
2129 vamsasStop.setVisible(true);
2130 vamsasImport.setVisible(false); // Document import to existing session is
2131 // not possible for vamsas-client-1.0.
2134 protected void setupVamsasDisconnectedGui()
2136 vamsasSave.setVisible(false);
2137 vamsasStop.setVisible(false);
2138 vamsasImport.setVisible(true);
2139 vamsasStart.setText(MessageManager
2140 .getString("label.new_vamsas_session"));
2144 public void vamsasStop_actionPerformed(ActionEvent e)
2146 if (v_client != null)
2148 v_client.end_session();
2150 setupVamsasDisconnectedGui();
2154 protected void buildVamsasStMenu()
2156 if (v_client == null)
2158 String[] sess = null;
2161 sess = VamsasApplication.getSessionList();
2162 } catch (Exception e)
2164 jalview.bin.Cache.log.warn(
2165 "Problem getting current sessions list.", e);
2170 jalview.bin.Cache.log.debug("Got current sessions list: "
2171 + sess.length + " entries.");
2172 VamsasStMenu.removeAll();
2173 for (int i = 0; i < sess.length; i++)
2175 JMenuItem sessit = new JMenuItem();
2176 sessit.setText(sess[i]);
2177 sessit.setToolTipText(MessageManager.formatMessage(
2178 "label.connect_to_session", new Object[] { sess[i] }));
2179 final Desktop dsktp = this;
2180 final String mysesid = sess[i];
2181 sessit.addActionListener(new ActionListener()
2185 public void actionPerformed(ActionEvent e)
2187 if (dsktp.v_client == null)
2189 Thread rthr = new Thread(new Runnable()
2195 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2196 dsktp.setupVamsasConnectedGui();
2197 dsktp.v_client.initial_update();
2205 VamsasStMenu.add(sessit);
2207 // don't show an empty menu.
2208 VamsasStMenu.setVisible(sess.length > 0);
2213 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2214 VamsasStMenu.removeAll();
2215 VamsasStMenu.setVisible(false);
2220 // Not interested in the content. Just hide ourselves.
2221 VamsasStMenu.setVisible(false);
2226 public void vamsasSave_actionPerformed(ActionEvent e)
2228 if (v_client != null)
2230 // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2231 JalviewFileChooser chooser = new JalviewFileChooser("vdj",
2234 chooser.setFileView(new JalviewFileView());
2235 chooser.setDialogTitle(MessageManager
2236 .getString("label.save_vamsas_document_archive"));
2238 int value = chooser.showSaveDialog(this);
2240 if (value == JalviewFileChooser.APPROVE_OPTION)
2242 java.io.File choice = chooser.getSelectedFile();
2243 JPanel progpanel = addProgressPanel(MessageManager.formatMessage(
2244 "label.saving_vamsas_doc",
2245 new Object[] { choice.getName() }));
2246 Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2247 String warnmsg = null;
2248 String warnttl = null;
2251 v_client.vclient.storeDocument(choice);
2254 warnttl = "Serious Problem saving Vamsas Document";
2255 warnmsg = ex.toString();
2256 jalview.bin.Cache.log.error("Error Whilst saving document to "
2259 } catch (Exception ex)
2261 warnttl = "Problem saving Vamsas Document.";
2262 warnmsg = ex.toString();
2263 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2267 removeProgressPanel(progpanel);
2268 if (warnmsg != null)
2270 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2272 warnmsg, warnttl, JvOptionPane.ERROR_MESSAGE);
2278 JPanel vamUpdate = null;
2281 * hide vamsas user gui bits when a vamsas document event is being handled.
2284 * true to hide gui, false to reveal gui
2286 public void setVamsasUpdate(boolean b)
2288 Cache.log.debug("Setting gui for Vamsas update "
2289 + (b ? "in progress" : "finished"));
2291 if (vamUpdate != null)
2293 this.removeProgressPanel(vamUpdate);
2297 vamUpdate = this.addProgressPanel(MessageManager
2298 .getString("label.updating_vamsas_session"));
2300 vamsasStart.setVisible(!b);
2301 vamsasStop.setVisible(!b);
2302 vamsasSave.setVisible(!b);
2305 public JInternalFrame[] getAllFrames()
2307 return desktop.getAllFrames();
2311 * Checks the given url to see if it gives a response indicating that the user
2312 * should be informed of a new questionnaire.
2316 public void checkForQuestionnaire(String url)
2318 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2319 // javax.swing.SwingUtilities.invokeLater(jvq);
2320 new Thread(jvq).start();
2323 public void checkURLLinks()
2325 // Thread off the URL link checker
2326 addDialogThread(new Runnable()
2331 if (Cache.getDefault("CHECKURLLINKS", true))
2333 // check what the actual links are - if it's just the default don't
2334 // bother with the warning
2335 List<String> links = Preferences.sequenceUrlLinks
2338 // only need to check links if there is one with a
2339 // SEQUENCE_ID which is not the default EMBL_EBI link
2340 ListIterator<String> li = links.listIterator();
2341 boolean check = false;
2342 List<JLabel> urls = new ArrayList<JLabel>();
2343 while (li.hasNext())
2345 String link = li.next();
2346 if (link.contains(SEQUENCE_ID)
2347 && !link.equals(UrlConstants.DEFAULT_STRING))
2350 int barPos = link.indexOf("|");
2351 String urlMsg = barPos == -1 ? link : link.substring(0,
2352 barPos) + ": " + link.substring(barPos + 1);
2353 urls.add(new JLabel(urlMsg));
2361 // ask user to check in case URL links use old style tokens
2362 // ($SEQUENCE_ID$ for sequence id _or_ accession id)
2363 JPanel msgPanel = new JPanel();
2364 msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
2365 msgPanel.add(Box.createVerticalGlue());
2366 JLabel msg = new JLabel(
2368 .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
2369 JLabel msg2 = new JLabel(
2371 .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
2373 for (JLabel url : urls)
2379 final JCheckBox jcb = new JCheckBox(
2380 MessageManager.getString("label.do_not_display_again"));
2381 jcb.addActionListener(new ActionListener()
2384 public void actionPerformed(ActionEvent e)
2386 // update Cache settings for "don't show this again"
2387 boolean showWarningAgain = !jcb.isSelected();
2388 Cache.setProperty("CHECKURLLINKS",
2389 Boolean.valueOf(showWarningAgain).toString());
2394 JvOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
2396 .getString("label.SEQUENCE_ID_no_longer_used"),
2397 JvOptionPane.WARNING_MESSAGE);
2404 * Proxy class for JDesktopPane which optionally displays the current memory
2405 * usage and highlights the desktop area with a red bar if free memory runs
2410 public class MyDesktopPane extends JDesktopPane implements Runnable
2413 private static final float ONE_MB = 1048576f;
2415 boolean showMemoryUsage = false;
2419 java.text.NumberFormat df;
2421 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2424 public MyDesktopPane(boolean showMemoryUsage)
2426 showMemoryUsage(showMemoryUsage);
2429 public void showMemoryUsage(boolean showMemory)
2431 this.showMemoryUsage = showMemory;
2434 Thread worker = new Thread(this);
2439 public boolean isShowMemoryUsage()
2441 return showMemoryUsage;
2447 df = java.text.NumberFormat.getNumberInstance();
2448 df.setMaximumFractionDigits(2);
2449 runtime = Runtime.getRuntime();
2451 while (showMemoryUsage)
2455 maxMemory = runtime.maxMemory() / ONE_MB;
2456 allocatedMemory = runtime.totalMemory() / ONE_MB;
2457 freeMemory = runtime.freeMemory() / ONE_MB;
2458 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2460 percentUsage = (totalFreeMemory / maxMemory) * 100;
2462 // if (percentUsage < 20)
2464 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2466 // instance.set.setBorder(border1);
2469 // sleep after showing usage
2471 } catch (Exception ex)
2473 ex.printStackTrace();
2479 public void paintComponent(Graphics g)
2481 if (showMemoryUsage && g != null && df != null)
2483 if (percentUsage < 20)
2485 g.setColor(Color.red);
2487 FontMetrics fm = g.getFontMetrics();
2490 g.drawString(MessageManager.formatMessage(
2491 "label.memory_stats",
2492 new Object[] { df.format(totalFreeMemory),
2493 df.format(maxMemory), df.format(percentUsage) }), 10,
2494 getHeight() - fm.getHeight());
2501 * fixes stacking order after a modal dialog to ensure windows that should be
2502 * on top actually are
2504 public void relayerWindows()
2510 * Accessor method to quickly get all the AlignmentFrames loaded.
2512 * @return an array of AlignFrame, or null if none found
2514 public static AlignFrame[] getAlignFrames()
2516 if (Jalview.isHeadlessMode())
2518 // Desktop.desktop is null in headless mode
2519 return new AlignFrame[] { Jalview.currentAlignFrame };
2522 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2528 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2530 for (int i = frames.length - 1; i > -1; i--)
2532 if (frames[i] instanceof AlignFrame)
2534 avp.add((AlignFrame) frames[i]);
2536 else if (frames[i] instanceof SplitFrame)
2539 * Also check for a split frame containing an AlignFrame
2541 GSplitFrame sf = (GSplitFrame) frames[i];
2542 if (sf.getTopFrame() instanceof AlignFrame)
2544 avp.add((AlignFrame) sf.getTopFrame());
2546 if (sf.getBottomFrame() instanceof AlignFrame)
2548 avp.add((AlignFrame) sf.getBottomFrame());
2552 if (avp.size() == 0)
2556 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2561 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2565 public GStructureViewer[] getJmols()
2567 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2573 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2575 for (int i = frames.length - 1; i > -1; i--)
2577 if (frames[i] instanceof AppJmol)
2579 GStructureViewer af = (GStructureViewer) frames[i];
2583 if (avp.size() == 0)
2587 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2592 * Add Groovy Support to Jalview
2595 public void groovyShell_actionPerformed()
2599 openGroovyConsole();
2600 } catch (Exception ex)
2602 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2603 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2605 MessageManager.getString("label.couldnt_create_groovy_shell"),
2606 MessageManager.getString("label.groovy_support_failed"),
2607 JvOptionPane.ERROR_MESSAGE);
2612 * Open the Groovy console
2614 void openGroovyConsole()
2616 if (groovyConsole == null)
2618 groovyConsole = new groovy.ui.Console();
2619 groovyConsole.setVariable("Jalview", this);
2620 groovyConsole.run();
2623 * We allow only one console at a time, so that AlignFrame menu option
2624 * 'Calculate | Run Groovy script' is unambiguous.
2625 * Disable 'Groovy Console', and enable 'Run script', when the console is
2626 * opened, and the reverse when it is closed
2628 Window window = (Window) groovyConsole.getFrame();
2629 window.addWindowListener(new WindowAdapter()
2632 public void windowClosed(WindowEvent e)
2635 * rebind CMD-Q from Groovy Console to Jalview Quit
2638 enableExecuteGroovy(false);
2644 * show Groovy console window (after close and reopen)
2646 ((Window) groovyConsole.getFrame()).setVisible(true);
2649 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2650 * and disable opening a second console
2652 enableExecuteGroovy(true);
2656 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2657 * binding when opened
2659 protected void addQuitHandler()
2661 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
2662 KeyStroke.getKeyStroke(KeyEvent.VK_Q, Toolkit
2663 .getDefaultToolkit().getMenuShortcutKeyMask()), "Quit");
2664 getRootPane().getActionMap().put("Quit", new AbstractAction()
2667 public void actionPerformed(ActionEvent e)
2675 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2678 * true if Groovy console is open
2680 public void enableExecuteGroovy(boolean enabled)
2683 * disable opening a second Groovy console
2684 * (or re-enable when the console is closed)
2686 groovyShell.setEnabled(!enabled);
2688 AlignFrame[] alignFrames = getAlignFrames();
2689 if (alignFrames != null)
2691 for (AlignFrame af : alignFrames)
2693 af.setGroovyEnabled(enabled);
2699 * Progress bars managed by the IProgressIndicator method.
2701 private Hashtable<Long, JPanel> progressBars;
2703 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2708 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2711 public void setProgressBar(String message, long id)
2713 if (progressBars == null)
2715 progressBars = new Hashtable<Long, JPanel>();
2716 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2719 if (progressBars.get(new Long(id)) != null)
2721 JPanel panel = progressBars.remove(new Long(id));
2722 if (progressBarHandlers.contains(new Long(id)))
2724 progressBarHandlers.remove(new Long(id));
2726 removeProgressPanel(panel);
2730 progressBars.put(new Long(id), addProgressPanel(message));
2737 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2738 * jalview.gui.IProgressIndicatorHandler)
2741 public void registerHandler(final long id,
2742 final IProgressIndicatorHandler handler)
2744 if (progressBarHandlers == null
2745 || !progressBars.containsKey(new Long(id)))
2749 .getString("error.call_setprogressbar_before_registering_handler"));
2751 progressBarHandlers.put(new Long(id), handler);
2752 final JPanel progressPanel = progressBars.get(new Long(id));
2753 if (handler.canCancel())
2755 JButton cancel = new JButton(
2756 MessageManager.getString("action.cancel"));
2757 final IProgressIndicator us = this;
2758 cancel.addActionListener(new ActionListener()
2762 public void actionPerformed(ActionEvent e)
2764 handler.cancelActivity(id);
2765 us.setProgressBar(MessageManager.formatMessage(
2766 "label.cancelled_params",
2767 new Object[] { ((JLabel) progressPanel.getComponent(0))
2771 progressPanel.add(cancel, BorderLayout.EAST);
2777 * @return true if any progress bars are still active
2780 public boolean operationInProgress()
2782 if (progressBars != null && progressBars.size() > 0)
2790 * This will return the first AlignFrame holding the given viewport instance.
2791 * It will break if there are more than one AlignFrames viewing a particular
2795 * @return alignFrame for viewport
2797 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2799 if (desktop != null)
2801 AlignmentPanel[] aps = getAlignmentPanels(viewport.getSequenceSetId());
2802 for (int panel = 0; aps != null && panel < aps.length; panel++)
2804 if (aps[panel] != null && aps[panel].av == viewport)
2806 return aps[panel].alignFrame;
2813 public VamsasApplication getVamsasApplication()
2820 * flag set if jalview GUI is being operated programmatically
2822 private boolean inBatchMode = false;
2825 * check if jalview GUI is being operated programmatically
2827 * @return inBatchMode
2829 public boolean isInBatchMode()
2835 * set flag if jalview GUI is being operated programmatically
2837 * @param inBatchMode
2839 public void setInBatchMode(boolean inBatchMode)
2841 this.inBatchMode = inBatchMode;
2844 public void startServiceDiscovery()
2846 startServiceDiscovery(false);
2849 public void startServiceDiscovery(boolean blocking)
2851 boolean alive = true;
2852 Thread t0 = null, t1 = null, t2 = null;
2853 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2856 // todo: changesupport handlers need to be transferred
2857 if (discoverer == null)
2859 discoverer = new jalview.ws.jws1.Discoverer();
2860 // register PCS handler for desktop.
2861 discoverer.addPropertyChangeListener(changeSupport);
2863 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2864 // until we phase out completely
2865 (t0 = new Thread(discoverer)).start();
2868 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2870 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2875 // TODO: do rest service discovery
2884 } catch (Exception e)
2887 alive = (t1 != null && t1.isAlive())
2888 || (t2 != null && t2.isAlive())
2889 || (t3 != null && t3.isAlive())
2890 || (t0 != null && t0.isAlive());
2896 * called to check if the service discovery process completed successfully.
2900 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2902 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2904 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2905 .getErrorMessages();
2908 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2910 if (serviceChangedDialog == null)
2912 // only run if we aren't already displaying one of these.
2913 addDialogThread(serviceChangedDialog = new Runnable()
2920 * JalviewDialog jd =new JalviewDialog() {
2922 * @Override protected void cancelPressed() { // TODO
2923 * Auto-generated method stub
2925 * }@Override protected void okPressed() { // TODO
2926 * Auto-generated method stub
2928 * }@Override protected void raiseClosed() { // TODO
2929 * Auto-generated method stub
2931 * } }; jd.initDialogFrame(new
2932 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2933 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2934 * + " or mis-configured HTTP proxy settings.<br/>" +
2935 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2937 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2938 * ), true, true, "Web Service Configuration Problem", 450,
2941 * jd.waitForInput();
2947 "<html><table width=\"450\"><tr><td>"
2949 + "</td></tr></table>"
2950 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2951 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2952 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2953 + " Tools->Preferences dialog box to change them.</p></html>"),
2954 "Web Service Configuration Problem",
2955 JvOptionPane.DEFAULT_OPTION,
2956 JvOptionPane.ERROR_MESSAGE);
2957 serviceChangedDialog = null;
2966 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2973 private Runnable serviceChangedDialog = null;
2976 * start a thread to open a URL in the configured browser. Pops up a warning
2977 * dialog to the user if there is an exception when calling out to the browser
2982 public static void showUrl(final String url)
2984 showUrl(url, Desktop.instance);
2988 * Like showUrl but allows progress handler to be specified
2992 * (null) or object implementing IProgressIndicator
2994 public static void showUrl(final String url,
2995 final IProgressIndicator progress)
2997 new Thread(new Runnable()
3004 if (progress != null)
3006 progress.setProgressBar(MessageManager.formatMessage(
3007 "status.opening_params", new Object[] { url }), this
3010 jalview.util.BrowserLauncher.openURL(url);
3011 } catch (Exception ex)
3013 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
3015 .getString("label.web_browser_not_found_unix"),
3016 MessageManager.getString("label.web_browser_not_found"),
3017 JvOptionPane.WARNING_MESSAGE);
3019 ex.printStackTrace();
3021 if (progress != null)
3023 progress.setProgressBar(null, this.hashCode());
3029 public static WsParamSetManager wsparamManager = null;
3031 public static ParamManager getUserParameterStore()
3033 if (wsparamManager == null)
3035 wsparamManager = new WsParamSetManager();
3037 return wsparamManager;
3041 * static hyperlink handler proxy method for use by Jalview's internal windows
3045 public static void hyperlinkUpdate(HyperlinkEvent e)
3047 if (e.getEventType() == EventType.ACTIVATED)
3052 url = e.getURL().toString();
3053 Desktop.showUrl(url);
3054 } catch (Exception x)
3058 if (Cache.log != null)
3060 Cache.log.error("Couldn't handle string " + url + " as a URL.");
3064 System.err.println("Couldn't handle string " + url
3068 // ignore any exceptions due to dud links.
3075 * single thread that handles display of dialogs to user.
3077 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
3080 * flag indicating if dialogExecutor should try to acquire a permit
3082 private volatile boolean dialogPause = true;
3087 private java.util.concurrent.Semaphore block = new Semaphore(0);
3089 private static groovy.ui.Console groovyConsole;
3092 * add another dialog thread to the queue
3096 public void addDialogThread(final Runnable prompter)
3098 dialogExecutor.submit(new Runnable()
3108 } catch (InterruptedException x)
3113 if (instance == null)
3119 SwingUtilities.invokeAndWait(prompter);
3120 } catch (Exception q)
3122 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3128 public void startDialogQueue()
3130 // set the flag so we don't pause waiting for another permit and semaphore
3131 // the current task to begin
3132 dialogPause = false;
3137 protected void snapShotWindow_actionPerformed(ActionEvent e)
3141 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
3142 "View of Desktop", getWidth(), getHeight(), of = new File(
3143 "Jalview_snapshot" + System.currentTimeMillis()
3144 + ".eps"), "View of desktop", null, 0, false);
3147 paintAll(im.getGraphics());
3149 } catch (Exception q)
3151 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3155 Cache.log.info("Successfully written snapshot to file "
3156 + of.getAbsolutePath());
3160 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3161 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3162 * and location last time the view was expanded (if any). However it does not
3163 * remember the split pane divider location - this is set to match the
3164 * 'exploding' frame.
3168 public void explodeViews(SplitFrame sf)
3170 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3171 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3172 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3174 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3176 int viewCount = topPanels.size();
3183 * Processing in reverse order works, forwards order leaves the first panels
3184 * not visible. I don't know why!
3186 for (int i = viewCount - 1; i >= 0; i--)
3189 * Make new top and bottom frames. These take over the respective
3190 * AlignmentPanel objects, including their AlignmentViewports, so the
3191 * cdna/protein relationships between the viewports is carried over to the
3194 * explodedGeometry holds the (x, y) position of the previously exploded
3195 * SplitFrame, and the (width, height) of the AlignFrame component
3197 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3198 AlignFrame newTopFrame = new AlignFrame(topPanel);
3199 newTopFrame.setSize(oldTopFrame.getSize());
3200 newTopFrame.setVisible(true);
3201 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3202 .getExplodedGeometry();
3203 if (geometry != null)
3205 newTopFrame.setSize(geometry.getSize());
3208 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3209 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3210 newBottomFrame.setSize(oldBottomFrame.getSize());
3211 newBottomFrame.setVisible(true);
3212 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3213 .getExplodedGeometry();
3214 if (geometry != null)
3216 newBottomFrame.setSize(geometry.getSize());
3219 topPanel.av.setGatherViewsHere(false);
3220 bottomPanel.av.setGatherViewsHere(false);
3221 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3223 if (geometry != null)
3225 splitFrame.setLocation(geometry.getLocation());
3227 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3231 * Clear references to the panels (now relocated in the new SplitFrames)
3232 * before closing the old SplitFrame.
3235 bottomPanels.clear();
3240 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3241 * back into the given SplitFrame as additional views. Note that the gathered
3242 * frames may themselves have multiple views.
3246 public void gatherViews(GSplitFrame source)
3249 * special handling of explodedGeometry for a view within a SplitFrame: - it
3250 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3251 * height) of the AlignFrame component
3253 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3254 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3255 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3256 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3257 myBottomFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3258 source.getY(), myBottomFrame.getWidth(), myBottomFrame
3260 myTopFrame.viewport.setGatherViewsHere(true);
3261 myBottomFrame.viewport.setGatherViewsHere(true);
3262 String topViewId = myTopFrame.viewport.getSequenceSetId();
3263 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3265 JInternalFrame[] frames = desktop.getAllFrames();
3266 for (JInternalFrame frame : frames)
3268 if (frame instanceof SplitFrame && frame != source)
3270 SplitFrame sf = (SplitFrame) frame;
3271 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3272 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3273 boolean gatherThis = false;
3274 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3276 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3277 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3278 if (topViewId.equals(topPanel.av.getSequenceSetId())
3279 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3282 topPanel.av.setGatherViewsHere(false);
3283 bottomPanel.av.setGatherViewsHere(false);
3284 topPanel.av.setExplodedGeometry(new Rectangle(sf.getLocation(),
3285 topFrame.getSize()));
3286 bottomPanel.av.setExplodedGeometry(new Rectangle(sf
3287 .getLocation(), bottomFrame.getSize()));
3288 myTopFrame.addAlignmentPanel(topPanel, false);
3289 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3295 topFrame.getAlignPanels().clear();
3296 bottomFrame.getAlignPanels().clear();
3303 * The dust settles...give focus to the tab we did this from.
3305 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3308 public static groovy.ui.Console getGroovyConsole()
3310 return groovyConsole;
3313 public static void transferFromDropTarget(List<String> files,
3314 List<DataSourceType> protocols, DropTargetDropEvent evt,
3319 DataFlavor uriListFlavor = new DataFlavor(
3320 "text/uri-list;class=java.lang.String");
3321 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3323 // Works on Windows and MacOSX
3324 Cache.log.debug("Drop handled as javaFileListFlavor");
3325 for (Object file : (List) t
3326 .getTransferData(DataFlavor.javaFileListFlavor))
3328 files.add(((File) file).toString());
3329 protocols.add(DataSourceType.FILE);
3334 // Unix like behaviour
3335 boolean added = false;
3337 if (t.isDataFlavorSupported(uriListFlavor))
3339 Cache.log.debug("Drop handled as uriListFlavor");
3340 // This is used by Unix drag system
3341 data = (String) t.getTransferData(uriListFlavor);
3345 // fallback to text: workaround - on OSX where there's a JVM bug
3346 Cache.log.debug("standard URIListFlavor failed. Trying text");
3347 // try text fallback
3348 data = (String) t.getTransferData(new DataFlavor(
3349 "text/plain;class=java.lang.String"));
3350 if (Cache.log.isDebugEnabled())
3352 Cache.log.debug("fallback returned " + data);
3355 while (protocols.size() < files.size())
3357 Cache.log.debug("Adding missing FILE protocol for "
3358 + files.get(protocols.size()));
3359 protocols.add(DataSourceType.FILE);
3361 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3362 data, "\r\n"); st.hasMoreTokens();)
3365 String s = st.nextToken();
3366 if (s.startsWith("#"))
3368 // the line is a comment (as per the RFC 2483)
3371 java.net.URI uri = new java.net.URI(s);
3372 if (uri.getScheme().toLowerCase().startsWith("http"))
3374 protocols.add(DataSourceType.URL);
3375 files.add(uri.toString());
3379 // otherwise preserve old behaviour: catch all for file objects
3380 java.io.File file = new java.io.File(uri);
3381 protocols.add(DataSourceType.FILE);
3382 files.add(file.toString());
3385 if (Cache.log.isDebugEnabled())
3387 if (data == null || !added)
3390 .debug("Couldn't resolve drop data. Here are the supported flavors:");
3391 for (DataFlavor fl : t.getTransferDataFlavors())
3393 Cache.log.debug("Supported transfer dataflavor: "
3395 Object df = t.getTransferData(fl);
3398 Cache.log.debug("Retrieves: " + df);
3402 Cache.log.debug("Retrieved nothing");
3411 * Sets the Preferences property for experimental features to True or False
3412 * depending on the state of the controlling menu item
3415 protected void showExperimental_actionPerformed(boolean selected)
3417 Cache.setProperty(EXPERIMENTAL_FEATURES, Boolean.toString(selected));