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
129 implements 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 int ALIGN_FRAME_DEFAULT_MIN_WIDTH = 600;
138 private static int ALIGN_FRAME_DEFAULT_MIN_HEIGHT = 70;
140 private static final String EXPERIMENTAL_FEATURES = "EXPERIMENTAL_FEATURES";
142 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
145 * news reader - null if it was never started.
147 private BlogReader jvnews = null;
149 private File projectFile;
153 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
155 public void addJalviewPropertyChangeListener(
156 PropertyChangeListener listener)
158 changeSupport.addJalviewPropertyChangeListener(listener);
162 * @param propertyName
164 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
165 * java.beans.PropertyChangeListener)
167 public void addJalviewPropertyChangeListener(String propertyName,
168 PropertyChangeListener listener)
170 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
174 * @param propertyName
176 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
177 * java.beans.PropertyChangeListener)
179 public void removeJalviewPropertyChangeListener(String propertyName,
180 PropertyChangeListener listener)
182 changeSupport.removeJalviewPropertyChangeListener(propertyName,
186 /** Singleton Desktop instance */
187 public static Desktop instance;
189 public static MyDesktopPane desktop;
191 static int openFrameCount = 0;
193 static final int xOffset = 30;
195 static final int yOffset = 30;
197 public static jalview.ws.jws1.Discoverer discoverer;
199 public static Object[] jalviewClipboard;
201 public static boolean internalCopy = false;
203 static int fileLoadingCount = 0;
205 class MyDesktopManager implements DesktopManager
208 private DesktopManager delegate;
210 public MyDesktopManager(DesktopManager delegate)
212 this.delegate = delegate;
216 public void activateFrame(JInternalFrame f)
220 delegate.activateFrame(f);
221 } catch (NullPointerException npe)
223 Point p = getMousePosition();
224 instance.showPasteMenu(p.x, p.y);
229 public void beginDraggingFrame(JComponent f)
231 delegate.beginDraggingFrame(f);
235 public void beginResizingFrame(JComponent f, int direction)
237 delegate.beginResizingFrame(f, direction);
241 public void closeFrame(JInternalFrame f)
243 delegate.closeFrame(f);
247 public void deactivateFrame(JInternalFrame f)
249 delegate.deactivateFrame(f);
253 public void deiconifyFrame(JInternalFrame f)
255 delegate.deiconifyFrame(f);
259 public void dragFrame(JComponent f, int newX, int newY)
265 delegate.dragFrame(f, newX, newY);
269 public void endDraggingFrame(JComponent f)
271 delegate.endDraggingFrame(f);
275 public void endResizingFrame(JComponent f)
277 delegate.endResizingFrame(f);
281 public void iconifyFrame(JInternalFrame f)
283 delegate.iconifyFrame(f);
287 public void maximizeFrame(JInternalFrame f)
289 delegate.maximizeFrame(f);
293 public void minimizeFrame(JInternalFrame f)
295 delegate.minimizeFrame(f);
299 public void openFrame(JInternalFrame f)
301 delegate.openFrame(f);
305 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
312 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
316 public void setBoundsForFrame(JComponent f, int newX, int newY,
317 int newWidth, int newHeight)
319 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
322 // All other methods, simply delegate
327 * Creates a new Desktop object.
332 * A note to implementors. It is ESSENTIAL that any activities that might
333 * block are spawned off as threads rather than waited for during this
337 doVamsasClientCheck();
339 doConfigureStructurePrefs();
340 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
341 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
342 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
344 boolean showjconsole = jalview.bin.Cache.getDefault("SHOW_JAVA_CONSOLE",
346 desktop = new MyDesktopPane(selmemusage);
347 if (Platform.isAMac())
349 desktop.setDoubleBuffered(false);
351 showMemusage.setSelected(selmemusage);
352 desktop.setBackground(Color.white);
353 getContentPane().setLayout(new BorderLayout());
354 // alternate config - have scrollbars - see notes in JAL-153
355 // JScrollPane sp = new JScrollPane();
356 // sp.getViewport().setView(desktop);
357 // getContentPane().add(sp, BorderLayout.CENTER);
358 getContentPane().add(desktop, BorderLayout.CENTER);
359 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
361 // This line prevents Windows Look&Feel resizing all new windows to maximum
362 // if previous window was maximised
363 desktop.setDesktopManager(
364 new MyDesktopManager(new DefaultDesktopManager()));
366 Rectangle dims = getLastKnownDimensions("");
373 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
374 setBounds((screenSize.width - 900) / 2, (screenSize.height - 650) / 2,
377 jconsole = new Console(this, showjconsole);
378 // add essential build information
380 "Jalview Version: " + jalview.bin.Cache.getProperty("VERSION")
381 + "\n" + "Jalview Installation: "
382 + jalview.bin.Cache.getDefault("INSTALLATION",
384 + "\n" + "Build Date: "
385 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
386 + "\n" + "Java version: "
387 + System.getProperty("java.version") + "\n"
388 + System.getProperty("os.arch") + " "
389 + System.getProperty("os.name") + " "
390 + System.getProperty("os.version"));
392 showConsole(showjconsole);
394 showNews.setVisible(false);
396 experimentalFeatures.setSelected(showExperimental());
398 getIdentifiersOrgData();
402 this.addWindowListener(new WindowAdapter()
405 public void windowClosing(WindowEvent evt)
412 this.addMouseListener(ma = new MouseAdapter()
415 public void mousePressed(MouseEvent evt)
417 if (evt.isPopupTrigger()) // Mac
419 showPasteMenu(evt.getX(), evt.getY());
424 public void mouseReleased(MouseEvent evt)
426 if (evt.isPopupTrigger()) // Windows
428 showPasteMenu(evt.getX(), evt.getY());
432 desktop.addMouseListener(ma);
434 this.addFocusListener(new FocusListener()
438 public void focusLost(FocusEvent e)
440 // TODO Auto-generated method stub
445 public void focusGained(FocusEvent e)
447 Cache.log.debug("Relaying windows after focus gain");
448 // make sure that we sort windows properly after we gain focus
449 instance.relayerWindows();
452 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
453 // Spawn a thread that shows the splashscreen
454 SwingUtilities.invokeLater(new Runnable()
463 // Thread off a new instance of the file chooser - this reduces the time it
464 // takes to open it later on.
465 new Thread(new Runnable()
470 Cache.log.debug("Filechooser init thread started.");
471 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
472 JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"),
474 Cache.log.debug("Filechooser init thread finished.");
477 // Add the service change listener
478 changeSupport.addJalviewPropertyChangeListener("services",
479 new PropertyChangeListener()
483 public void propertyChange(PropertyChangeEvent evt)
485 Cache.log.debug("Firing service changed event for "
486 + evt.getNewValue());
487 JalviewServicesChanged(evt);
494 * Answers true if user preferences to enable experimental features is True
499 public boolean showExperimental()
501 String experimental = Cache.getDefault(EXPERIMENTAL_FEATURES,
502 Boolean.FALSE.toString());
503 return Boolean.valueOf(experimental).booleanValue();
506 public void doConfigureStructurePrefs()
508 // configure services
509 StructureSelectionManager ssm = StructureSelectionManager
510 .getStructureSelectionManager(this);
511 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
513 ssm.setAddTempFacAnnot(jalview.bin.Cache
514 .getDefault(Preferences.ADD_TEMPFACT_ANN, true));
515 ssm.setProcessSecondaryStructure(jalview.bin.Cache
516 .getDefault(Preferences.STRUCT_FROM_PDB, true));
517 ssm.setSecStructServices(
518 jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW, true));
522 ssm.setAddTempFacAnnot(false);
523 ssm.setProcessSecondaryStructure(false);
524 ssm.setSecStructServices(false);
528 public void checkForNews()
530 final Desktop me = this;
531 // Thread off the news reader, in case there are connection problems.
532 addDialogThread(new Runnable()
537 Cache.log.debug("Starting news thread.");
539 jvnews = new BlogReader(me);
540 showNews.setVisible(true);
541 Cache.log.debug("Completed news thread.");
546 public void getIdentifiersOrgData()
548 // Thread off the identifiers fetcher
549 addDialogThread(new Runnable()
554 Cache.log.debug("Downloading data from identifiers.org");
555 UrlDownloadClient client = new UrlDownloadClient();
558 client.download(IdOrgSettings.getUrl(),
559 IdOrgSettings.getDownloadLocation());
560 } catch (IOException e)
562 Cache.log.debug("Exception downloading identifiers.org data"
570 protected void showNews_actionPerformed(ActionEvent e)
572 showNews(showNews.isSelected());
575 void showNews(boolean visible)
578 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
579 showNews.setSelected(visible);
580 if (visible && !jvnews.isVisible())
582 new Thread(new Runnable()
587 long now = System.currentTimeMillis();
588 Desktop.instance.setProgressBar(
589 MessageManager.getString("status.refreshing_news"),
591 jvnews.refreshNews();
592 Desktop.instance.setProgressBar(null, now);
601 * recover the last known dimensions for a jalview window
604 * - empty string is desktop, all other windows have unique prefix
605 * @return null or last known dimensions scaled to current geometry (if last
606 * window geom was known)
608 Rectangle getLastKnownDimensions(String windowName)
610 // TODO: lock aspect ratio for scaling desktop Bug #0058199
611 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
612 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
613 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
614 String width = jalview.bin.Cache
615 .getProperty(windowName + "SCREEN_WIDTH");
616 String height = jalview.bin.Cache
617 .getProperty(windowName + "SCREEN_HEIGHT");
618 if ((x != null) && (y != null) && (width != null) && (height != null))
620 int ix = Integer.parseInt(x), iy = Integer.parseInt(y),
621 iw = Integer.parseInt(width), ih = Integer.parseInt(height);
622 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
624 // attempt #1 - try to cope with change in screen geometry - this
625 // version doesn't preserve original jv aspect ratio.
626 // take ratio of current screen size vs original screen size.
627 double sw = ((1f * screenSize.width) / (1f * Integer.parseInt(
628 jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH"))));
629 double sh = ((1f * screenSize.height) / (1f * Integer.parseInt(
630 jalview.bin.Cache.getProperty("SCREENGEOMETRY_HEIGHT"))));
631 // rescale the bounds depending upon the current screen geometry.
632 ix = (int) (ix * sw);
633 iw = (int) (iw * sw);
634 iy = (int) (iy * sh);
635 ih = (int) (ih * sh);
636 while (ix >= screenSize.width)
638 jalview.bin.Cache.log.debug(
639 "Window geometry location recall error: shifting horizontal to within screenbounds.");
640 ix -= screenSize.width;
642 while (iy >= screenSize.height)
644 jalview.bin.Cache.log.debug(
645 "Window geometry location recall error: shifting vertical to within screenbounds.");
646 iy -= screenSize.height;
648 jalview.bin.Cache.log.debug(
649 "Got last known dimensions for " + windowName + ": x:" + ix
650 + " y:" + iy + " width:" + iw + " height:" + ih);
652 // return dimensions for new instance
653 return new Rectangle(ix, iy, iw, ih);
658 private void doVamsasClientCheck()
660 if (jalview.bin.Cache.vamsasJarsPresent())
662 setupVamsasDisconnectedGui();
663 VamsasMenu.setVisible(true);
664 final Desktop us = this;
665 VamsasMenu.addMenuListener(new MenuListener()
667 // this listener remembers when the menu was first selected, and
668 // doesn't rebuild the session list until it has been cleared and
670 boolean refresh = true;
673 public void menuCanceled(MenuEvent e)
679 public void menuDeselected(MenuEvent e)
685 public void menuSelected(MenuEvent e)
689 us.buildVamsasStMenu();
694 vamsasStart.setVisible(true);
698 void showPasteMenu(int x, int y)
700 JPopupMenu popup = new JPopupMenu();
701 JMenuItem item = new JMenuItem(
702 MessageManager.getString("label.paste_new_window"));
703 item.addActionListener(new ActionListener()
706 public void actionPerformed(ActionEvent evt)
713 popup.show(this, x, y);
720 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
721 Transferable contents = c.getContents(this);
723 if (contents != null)
725 String file = (String) contents
726 .getTransferData(DataFlavor.stringFlavor);
728 FileFormatI format = new IdentifyFile().identify(file,
729 DataSourceType.PASTE);
731 new FileLoader().LoadFile(file, DataSourceType.PASTE, format);
734 } catch (Exception ex)
737 "Unable to paste alignment from system clipboard:\n" + ex);
742 * Adds and opens the given frame to the desktop
753 public static synchronized void addInternalFrame(
754 final JInternalFrame frame, String title, int w, int h)
756 addInternalFrame(frame, title, true, w, h, true, false);
760 * Add an internal frame to the Jalview desktop
767 * When true, display frame immediately, otherwise, caller must call
768 * setVisible themselves.
774 public static synchronized void addInternalFrame(
775 final JInternalFrame frame, String title, boolean makeVisible,
778 addInternalFrame(frame, title, makeVisible, w, h, true, false);
782 * Add an internal frame to the Jalview desktop and make it visible
795 public static synchronized void addInternalFrame(
796 final JInternalFrame frame, String title, int w, int h,
799 addInternalFrame(frame, title, true, w, h, resizable, false);
803 * Add an internal frame to the Jalview desktop
810 * When true, display frame immediately, otherwise, caller must call
811 * setVisible themselves.
818 * @param ignoreMinSize
819 * Do not set the default minimum size for frame
821 public static synchronized void addInternalFrame(
822 final JInternalFrame frame, String title, boolean makeVisible,
823 int w, int h, boolean resizable, boolean ignoreMinSize)
826 // TODO: allow callers to determine X and Y position of frame (eg. via
828 // TODO: consider fixing method to update entries in the window submenu with
829 // the current window title
831 frame.setTitle(title);
832 if (frame.getWidth() < 1 || frame.getHeight() < 1)
836 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
837 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
838 // IF JALVIEW IS RUNNING HEADLESS
839 // ///////////////////////////////////////////////
840 if (instance == null || (System.getProperty("java.awt.headless") != null
841 && System.getProperty("java.awt.headless").equals("true")))
850 frame.setMinimumSize(
851 new Dimension(DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT));
853 // Set default dimension for Alignment Frame window.
854 // The Alignment Frame window could be added from a number of places,
856 // I did this here in order not to miss out on any Alignment frame.
857 if (frame instanceof AlignFrame)
859 frame.setMinimumSize(new Dimension(ALIGN_FRAME_DEFAULT_MIN_WIDTH,
860 ALIGN_FRAME_DEFAULT_MIN_HEIGHT));
864 frame.setVisible(makeVisible);
865 frame.setClosable(true);
866 frame.setResizable(resizable);
867 frame.setMaximizable(resizable);
868 frame.setIconifiable(resizable);
869 if (Platform.isAMac())
871 frame.setIconifiable(false);
872 frame.setFrameIcon(null);
873 // frame.setDesktopIcon(null);
874 frame.setDoubleBuffered(false);
876 if (frame.getX() < 1 && frame.getY() < 1)
878 frame.setLocation(xOffset * openFrameCount,
879 yOffset * ((openFrameCount - 1) % 10) + yOffset);
883 * add an entry for the new frame in the Window menu
884 * (and remove it when the frame is closed)
886 final JMenuItem menuItem = new JMenuItem(title);
887 frame.addInternalFrameListener(new InternalFrameAdapter()
890 public void internalFrameActivated(InternalFrameEvent evt)
892 JInternalFrame itf = desktop.getSelectedFrame();
900 public void internalFrameClosed(InternalFrameEvent evt)
902 PaintRefresher.RemoveComponent(frame);
905 * defensive check to prevent frames being
906 * added half off the window
908 if (openFrameCount > 0)
914 * ensure no reference to alignFrame retained by menu item listener
916 if (menuItem.getActionListeners().length > 0)
918 menuItem.removeActionListener(menuItem.getActionListeners()[0]);
920 windowMenu.remove(menuItem);
921 JInternalFrame itf = desktop.getSelectedFrame();
925 if (itf instanceof AlignFrame)
927 Jalview.setCurrentAlignFrame((AlignFrame) itf);
934 menuItem.addActionListener(new ActionListener()
937 public void actionPerformed(ActionEvent e)
941 frame.setSelected(true);
942 frame.setIcon(false);
943 } catch (java.beans.PropertyVetoException ex)
952 windowMenu.add(menuItem);
957 frame.setSelected(true);
958 frame.requestFocus();
959 } catch (java.beans.PropertyVetoException ve)
961 } catch (java.lang.ClassCastException cex)
964 "Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
970 public void lostOwnership(Clipboard clipboard, Transferable contents)
974 Desktop.jalviewClipboard = null;
977 internalCopy = false;
981 public void dragEnter(DropTargetDragEvent evt)
986 public void dragExit(DropTargetEvent evt)
991 public void dragOver(DropTargetDragEvent evt)
996 public void dropActionChanged(DropTargetDragEvent evt)
1007 public void drop(DropTargetDropEvent evt)
1009 boolean success = true;
1010 // JAL-1552 - acceptDrop required before getTransferable call for
1011 // Java's Transferable for native dnd
1012 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
1013 Transferable t = evt.getTransferable();
1014 List<String> files = new ArrayList<String>();
1015 List<DataSourceType> protocols = new ArrayList<DataSourceType>();
1019 Desktop.transferFromDropTarget(files, protocols, evt, t);
1020 } catch (Exception e)
1022 e.printStackTrace();
1030 for (int i = 0; i < files.size(); i++)
1032 String file = files.get(i).toString();
1033 DataSourceType protocol = (protocols == null)
1034 ? DataSourceType.FILE
1036 FileFormatI format = null;
1038 if (file.endsWith(".jar"))
1040 format = FileFormat.Jalview;
1045 format = new IdentifyFile().identify(file, protocol);
1048 new FileLoader().LoadFile(file, protocol, format);
1051 } catch (Exception ex)
1056 evt.dropComplete(success); // need this to ensure input focus is properly
1057 // transfered to any new windows created
1067 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1069 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1070 JalviewFileChooser chooser = JalviewFileChooser
1071 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1073 chooser.setFileView(new JalviewFileView());
1074 chooser.setDialogTitle(
1075 MessageManager.getString("label.open_local_file"));
1076 chooser.setToolTipText(MessageManager.getString("action.open"));
1078 int value = chooser.showOpenDialog(this);
1080 if (value == JalviewFileChooser.APPROVE_OPTION)
1082 String choice = chooser.getSelectedFile().getPath();
1083 Cache.setProperty("LAST_DIRECTORY",
1084 chooser.getSelectedFile().getParent());
1086 FileFormatI format = chooser.getSelectedFormat();
1089 * Call IdentifyFile to verify the file contains what its extension implies.
1090 * Skip this step for dynamically added file formats, because
1091 * IdentifyFile does not know how to recognise them.
1093 if (FileFormats.getInstance().isIdentifiable(format))
1097 format = new IdentifyFile().identify(choice, DataSourceType.FILE);
1098 } catch (FileFormatException e)
1100 // format = null; //??
1104 if (viewport != null)
1106 new FileLoader().LoadFile(viewport, choice, DataSourceType.FILE,
1111 new FileLoader().LoadFile(choice, DataSourceType.FILE, format);
1123 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1125 // This construct allows us to have a wider textfield
1127 JLabel label = new JLabel(
1128 MessageManager.getString("label.input_file_url"));
1129 final JComboBox history = new JComboBox();
1131 JPanel panel = new JPanel(new GridLayout(2, 1));
1134 history.setPreferredSize(new Dimension(400, 20));
1135 history.setEditable(true);
1136 history.addItem("http://www.");
1138 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1142 if (historyItems != null)
1144 st = new StringTokenizer(historyItems, "\t");
1146 while (st.hasMoreTokens())
1148 history.addItem(st.nextElement());
1152 int reply = JvOptionPane.showInternalConfirmDialog(desktop, panel,
1153 MessageManager.getString("label.input_alignment_from_url"),
1154 JvOptionPane.OK_CANCEL_OPTION);
1156 if (reply != JvOptionPane.OK_OPTION)
1161 String url = history.getSelectedItem().toString();
1163 if (url.toLowerCase().endsWith(".jar"))
1165 if (viewport != null)
1167 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1168 FileFormat.Jalview);
1172 new FileLoader().LoadFile(url, DataSourceType.URL,
1173 FileFormat.Jalview);
1178 FileFormatI format = null;
1181 format = new IdentifyFile().identify(url, DataSourceType.URL);
1182 } catch (FileFormatException e)
1184 // TODO revise error handling, distinguish between
1185 // URL not found and response not valid
1190 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1191 MessageManager.formatMessage("label.couldnt_locate",
1194 MessageManager.getString("label.url_not_found"),
1195 JvOptionPane.WARNING_MESSAGE);
1200 if (viewport != null)
1202 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1207 new FileLoader().LoadFile(url, DataSourceType.URL, format);
1213 * Opens the CutAndPaste window for the user to paste an alignment in to
1216 * - if not null, the pasted alignment is added to the current
1217 * alignment; if null, to a new alignment window
1220 public void inputTextboxMenuItem_actionPerformed(
1221 AlignmentViewPanel viewPanel)
1223 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1224 cap.setForInput(viewPanel);
1225 Desktop.addInternalFrame(cap,
1226 MessageManager.getString("label.cut_paste_alignmen_file"), true,
1236 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1237 jalview.bin.Cache.setProperty("SCREENGEOMETRY_WIDTH",
1239 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT",
1240 screen.height + "");
1241 storeLastKnownDimensions("", new Rectangle(getBounds().x, getBounds().y,
1242 getWidth(), getHeight()));
1244 if (jconsole != null)
1246 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1247 jconsole.stopConsole();
1251 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1254 if (dialogExecutor != null)
1256 dialogExecutor.shutdownNow();
1258 closeAll_actionPerformed(null);
1260 if (groovyConsole != null)
1262 // suppress a possible repeat prompt to save script
1263 groovyConsole.setDirty(false);
1264 groovyConsole.exit();
1269 private void storeLastKnownDimensions(String string, Rectangle jc)
1271 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1272 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1273 + " height:" + jc.height);
1275 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1276 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1277 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1278 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1288 public void aboutMenuItem_actionPerformed(ActionEvent e)
1290 // StringBuffer message = getAboutMessage(false);
1291 // JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1293 // message.toString(), "About Jalview", JvOptionPane.INFORMATION_MESSAGE);
1294 new Thread(new Runnable()
1299 new SplashScreen(true);
1304 public StringBuffer getAboutMessage(boolean shortv)
1306 StringBuffer message = new StringBuffer();
1307 message.append("<html>");
1310 message.append("<h1><strong>Version: "
1311 + jalview.bin.Cache.getProperty("VERSION")
1312 + "</strong></h1>");
1313 message.append("<strong>Last Updated: <em>"
1314 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1315 + "</em></strong>");
1321 message.append("<strong>Version "
1322 + jalview.bin.Cache.getProperty("VERSION")
1323 + "; last updated: "
1324 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1327 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1328 .equals("Checking"))
1330 message.append("<br>...Checking latest version...</br>");
1332 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1333 .equals(jalview.bin.Cache.getProperty("VERSION")))
1335 boolean red = false;
1336 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1337 .indexOf("automated build") == -1)
1340 // Displayed when code version and jnlp version do not match and code
1341 // version is not a development build
1342 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1345 message.append("<br>!! Version "
1346 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1348 + " is available for download from "
1349 + jalview.bin.Cache.getDefault("www.jalview.org",
1350 "http://www.jalview.org")
1354 message.append("</div>");
1357 message.append("<br>Authors: " + jalview.bin.Cache.getDefault(
1359 "The Jalview Authors (See AUTHORS file for current list)")
1360 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1361 + "<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"
1362 + "<br><br>If you use Jalview, please cite:"
1363 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1364 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1365 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1377 public void documentationMenuItem_actionPerformed(ActionEvent e)
1381 Help.showHelpWindow();
1382 } catch (Exception ex)
1388 public void closeAll_actionPerformed(ActionEvent e)
1390 // TODO show a progress bar while closing?
1391 JInternalFrame[] frames = desktop.getAllFrames();
1392 for (int i = 0; i < frames.length; i++)
1396 frames[i].setClosed(true);
1397 } catch (java.beans.PropertyVetoException ex)
1401 Jalview.setCurrentAlignFrame(null);
1402 System.out.println("ALL CLOSED");
1403 if (v_client != null)
1405 // TODO clear binding to vamsas document objects on close_all
1409 * reset state of singleton objects as appropriate (clear down session state
1410 * when all windows are closed)
1412 StructureSelectionManager ssm = StructureSelectionManager
1413 .getStructureSelectionManager(this);
1422 public void raiseRelated_actionPerformed(ActionEvent e)
1424 reorderAssociatedWindows(false, false);
1428 public void minimizeAssociated_actionPerformed(ActionEvent e)
1430 reorderAssociatedWindows(true, false);
1433 void closeAssociatedWindows()
1435 reorderAssociatedWindows(false, true);
1441 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1445 protected void garbageCollect_actionPerformed(ActionEvent e)
1447 // We simply collect the garbage
1448 jalview.bin.Cache.log.debug("Collecting garbage...");
1450 jalview.bin.Cache.log.debug("Finished garbage collection.");
1457 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1461 protected void showMemusage_actionPerformed(ActionEvent e)
1463 desktop.showMemoryUsage(showMemusage.isSelected());
1470 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1474 protected void showConsole_actionPerformed(ActionEvent e)
1476 showConsole(showConsole.isSelected());
1479 Console jconsole = null;
1482 * control whether the java console is visible or not
1486 void showConsole(boolean selected)
1488 showConsole.setSelected(selected);
1489 // TODO: decide if we should update properties file
1490 Cache.setProperty("SHOW_JAVA_CONSOLE",
1491 Boolean.valueOf(selected).toString());
1492 jconsole.setVisible(selected);
1495 void reorderAssociatedWindows(boolean minimize, boolean close)
1497 JInternalFrame[] frames = desktop.getAllFrames();
1498 if (frames == null || frames.length < 1)
1503 AlignmentViewport source = null, target = null;
1504 if (frames[0] instanceof AlignFrame)
1506 source = ((AlignFrame) frames[0]).getCurrentView();
1508 else if (frames[0] instanceof TreePanel)
1510 source = ((TreePanel) frames[0]).getViewPort();
1512 else if (frames[0] instanceof PCAPanel)
1514 source = ((PCAPanel) frames[0]).av;
1516 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1518 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1523 for (int i = 0; i < frames.length; i++)
1526 if (frames[i] == null)
1530 if (frames[i] instanceof AlignFrame)
1532 target = ((AlignFrame) frames[i]).getCurrentView();
1534 else if (frames[i] instanceof TreePanel)
1536 target = ((TreePanel) frames[i]).getViewPort();
1538 else if (frames[i] instanceof PCAPanel)
1540 target = ((PCAPanel) frames[i]).av;
1542 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1544 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1547 if (source == target)
1553 frames[i].setClosed(true);
1557 frames[i].setIcon(minimize);
1560 frames[i].toFront();
1564 } catch (java.beans.PropertyVetoException ex)
1579 protected void preferences_actionPerformed(ActionEvent e)
1591 public void saveState_actionPerformed(ActionEvent e)
1593 JalviewFileChooser chooser = new JalviewFileChooser("jvp",
1596 chooser.setFileView(new JalviewFileView());
1597 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1599 int value = chooser.showSaveDialog(this);
1601 if (value == JalviewFileChooser.APPROVE_OPTION)
1603 final Desktop me = this;
1604 final java.io.File choice = chooser.getSelectedFile();
1605 setProjectFile(choice);
1607 new Thread(new Runnable()
1612 // TODO: refactor to Jalview desktop session controller action.
1613 setProgressBar(MessageManager.formatMessage(
1614 "label.saving_jalview_project", new Object[]
1615 { choice.getName() }), choice.hashCode());
1616 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1617 choice.getParent());
1618 // TODO catch and handle errors for savestate
1619 // TODO prevent user from messing with the Desktop whilst we're saving
1622 new Jalview2XML().saveState(choice);
1623 } catch (OutOfMemoryError oom)
1626 "Whilst saving current state to " + choice.getName(),
1628 } catch (Exception ex)
1631 "Problems whilst trying to save to " + choice.getName(),
1633 JvOptionPane.showMessageDialog(me,
1634 MessageManager.formatMessage(
1635 "label.error_whilst_saving_current_state_to",
1637 { choice.getName() }),
1638 MessageManager.getString("label.couldnt_save_project"),
1639 JvOptionPane.WARNING_MESSAGE);
1641 setProgressBar(null, choice.hashCode());
1647 private void setProjectFile(File choice)
1649 this.projectFile = choice;
1652 public File getProjectFile()
1654 return this.projectFile;
1664 public void loadState_actionPerformed(ActionEvent e)
1666 JalviewFileChooser chooser = new JalviewFileChooser(
1667 Cache.getProperty("LAST_DIRECTORY"), new String[]
1670 { "Jalview Project", "Jalview Project (old)" },
1672 chooser.setFileView(new JalviewFileView());
1673 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1675 int value = chooser.showOpenDialog(this);
1677 if (value == JalviewFileChooser.APPROVE_OPTION)
1679 final File selectedFile = chooser.getSelectedFile();
1680 setProjectFile(selectedFile);
1681 final String choice = selectedFile.getAbsolutePath();
1682 Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
1683 new Thread(new Runnable()
1688 setProgressBar(MessageManager.formatMessage(
1689 "label.loading_jalview_project", new Object[]
1690 { choice }), choice.hashCode());
1693 new Jalview2XML().loadJalviewAlign(choice);
1694 } catch (OutOfMemoryError oom)
1696 new OOMWarning("Whilst loading project from " + choice, oom);
1697 } catch (Exception ex)
1700 "Problems whilst loading project from " + choice, ex);
1701 JvOptionPane.showMessageDialog(Desktop.desktop,
1702 MessageManager.formatMessage(
1703 "label.error_whilst_loading_project_from",
1706 MessageManager.getString("label.couldnt_load_project"),
1707 JvOptionPane.WARNING_MESSAGE);
1709 setProgressBar(null, choice.hashCode());
1716 public void inputSequence_actionPerformed(ActionEvent e)
1718 new SequenceFetcher(this);
1721 JPanel progressPanel;
1723 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1725 public void startLoading(final String fileName)
1727 if (fileLoadingCount == 0)
1729 fileLoadingPanels.add(addProgressPanel(MessageManager
1730 .formatMessage("label.loading_file", new Object[]
1736 private JPanel addProgressPanel(String string)
1738 if (progressPanel == null)
1740 progressPanel = new JPanel(new GridLayout(1, 1));
1741 totalProgressCount = 0;
1742 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1744 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1745 JProgressBar progressBar = new JProgressBar();
1746 progressBar.setIndeterminate(true);
1748 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1750 thisprogress.add(progressBar, BorderLayout.CENTER);
1751 progressPanel.add(thisprogress);
1752 ((GridLayout) progressPanel.getLayout()).setRows(
1753 ((GridLayout) progressPanel.getLayout()).getRows() + 1);
1754 ++totalProgressCount;
1755 instance.validate();
1756 return thisprogress;
1759 int totalProgressCount = 0;
1761 private void removeProgressPanel(JPanel progbar)
1763 if (progressPanel != null)
1765 synchronized (progressPanel)
1767 progressPanel.remove(progbar);
1768 GridLayout gl = (GridLayout) progressPanel.getLayout();
1769 gl.setRows(gl.getRows() - 1);
1770 if (--totalProgressCount < 1)
1772 this.getContentPane().remove(progressPanel);
1773 progressPanel = null;
1780 public void stopLoading()
1783 if (fileLoadingCount < 1)
1785 while (fileLoadingPanels.size() > 0)
1787 removeProgressPanel(fileLoadingPanels.remove(0));
1789 fileLoadingPanels.clear();
1790 fileLoadingCount = 0;
1795 public static int getViewCount(String alignmentId)
1797 AlignmentViewport[] aps = getViewports(alignmentId);
1798 return (aps == null) ? 0 : aps.length;
1803 * @param alignmentId
1804 * - if null, all sets are returned
1805 * @return all AlignmentPanels concerning the alignmentId sequence set
1807 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1809 if (Desktop.desktop == null)
1811 // no frames created and in headless mode
1812 // TODO: verify that frames are recoverable when in headless mode
1815 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1816 AlignFrame[] frames = getAlignFrames();
1821 for (AlignFrame af : frames)
1823 for (AlignmentPanel ap : af.alignPanels)
1825 if (alignmentId == null
1826 || alignmentId.equals(ap.av.getSequenceSetId()))
1832 if (aps.size() == 0)
1836 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1841 * get all the viewports on an alignment.
1843 * @param sequenceSetId
1844 * unique alignment id (may be null - all viewports returned in that
1846 * @return all viewports on the alignment bound to sequenceSetId
1848 public static AlignmentViewport[] getViewports(String sequenceSetId)
1850 List<AlignmentViewport> viewp = new ArrayList<AlignmentViewport>();
1851 if (desktop != null)
1853 AlignFrame[] frames = Desktop.getAlignFrames();
1855 for (AlignFrame afr : frames)
1857 if (sequenceSetId == null || afr.getViewport().getSequenceSetId()
1858 .equals(sequenceSetId))
1860 if (afr.alignPanels != null)
1862 for (AlignmentPanel ap : afr.alignPanels)
1864 if (sequenceSetId == null
1865 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1873 viewp.add(afr.getViewport());
1877 if (viewp.size() > 0)
1879 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1886 * Explode the views in the given frame into separate AlignFrame
1890 public static void explodeViews(AlignFrame af)
1892 int size = af.alignPanels.size();
1898 for (int i = 0; i < size; i++)
1900 AlignmentPanel ap = af.alignPanels.get(i);
1901 AlignFrame newaf = new AlignFrame(ap);
1904 * Restore the view's last exploded frame geometry if known. Multiple
1905 * views from one exploded frame share and restore the same (frame)
1906 * position and size.
1908 Rectangle geometry = ap.av.getExplodedGeometry();
1909 if (geometry != null)
1911 newaf.setBounds(geometry);
1914 ap.av.setGatherViewsHere(false);
1916 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1917 AlignFrame.DEFAULT_HEIGHT);
1920 af.alignPanels.clear();
1921 af.closeMenuItem_actionPerformed(true);
1926 * Gather expanded views (separate AlignFrame's) with the same sequence set
1927 * identifier back in to this frame as additional views, and close the
1928 * expanded views. Note the expanded frames may themselves have multiple
1929 * views. We take the lot.
1933 public void gatherViews(AlignFrame source)
1935 source.viewport.setGatherViewsHere(true);
1936 source.viewport.setExplodedGeometry(source.getBounds());
1937 JInternalFrame[] frames = desktop.getAllFrames();
1938 String viewId = source.viewport.getSequenceSetId();
1940 for (int t = 0; t < frames.length; t++)
1942 if (frames[t] instanceof AlignFrame && frames[t] != source)
1944 AlignFrame af = (AlignFrame) frames[t];
1945 boolean gatherThis = false;
1946 for (int a = 0; a < af.alignPanels.size(); a++)
1948 AlignmentPanel ap = af.alignPanels.get(a);
1949 if (viewId.equals(ap.av.getSequenceSetId()))
1952 ap.av.setGatherViewsHere(false);
1953 ap.av.setExplodedGeometry(af.getBounds());
1954 source.addAlignmentPanel(ap, false);
1960 af.alignPanels.clear();
1961 af.closeMenuItem_actionPerformed(true);
1968 jalview.gui.VamsasApplication v_client = null;
1971 public void vamsasImport_actionPerformed(ActionEvent e)
1973 if (v_client == null)
1975 // Load and try to start a session.
1976 JalviewFileChooser chooser = new JalviewFileChooser(
1977 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1979 chooser.setFileView(new JalviewFileView());
1980 chooser.setDialogTitle(
1981 MessageManager.getString("label.open_saved_vamsas_session"));
1982 chooser.setToolTipText(MessageManager.getString(
1983 "label.select_vamsas_session_opened_as_new_vamsas_session"));
1985 int value = chooser.showOpenDialog(this);
1987 if (value == JalviewFileChooser.APPROVE_OPTION)
1989 String fle = chooser.getSelectedFile().toString();
1990 if (!vamsasImport(chooser.getSelectedFile()))
1992 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1993 MessageManager.formatMessage(
1994 "label.couldnt_import_as_vamsas_session",
1998 .getString("label.vamsas_document_import_failed"),
1999 JvOptionPane.ERROR_MESSAGE);
2005 jalview.bin.Cache.log.error(
2006 "Implementation error - load session from a running session is not supported.");
2011 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2014 * @return true if import was a success and a session was started.
2016 public boolean vamsasImport(URL url)
2018 // TODO: create progress bar
2019 if (v_client != null)
2022 jalview.bin.Cache.log.error(
2023 "Implementation error - load session from a running session is not supported.");
2029 // copy the URL content to a temporary local file
2030 // TODO: be a bit cleverer here with nio (?!)
2031 File file = File.createTempFile("vdocfromurl", ".vdj");
2032 FileOutputStream fos = new FileOutputStream(file);
2033 BufferedInputStream bis = new BufferedInputStream(url.openStream());
2034 byte[] buffer = new byte[2048];
2036 while ((ln = bis.read(buffer)) > -1)
2038 fos.write(buffer, 0, ln);
2042 v_client = new jalview.gui.VamsasApplication(this, file,
2043 url.toExternalForm());
2044 } catch (Exception ex)
2046 jalview.bin.Cache.log.error(
2047 "Failed to create new vamsas session from contents of URL "
2052 setupVamsasConnectedGui();
2053 v_client.initial_update(); // TODO: thread ?
2054 return v_client.inSession();
2058 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2061 * @return true if import was a success and a session was started.
2063 public boolean vamsasImport(File file)
2065 if (v_client != null)
2068 jalview.bin.Cache.log.error(
2069 "Implementation error - load session from a running session is not supported.");
2073 setProgressBar(MessageManager.formatMessage(
2074 "status.importing_vamsas_session_from", new Object[]
2075 { file.getName() }), file.hashCode());
2078 v_client = new jalview.gui.VamsasApplication(this, file, null);
2079 } catch (Exception ex)
2081 setProgressBar(MessageManager.formatMessage(
2082 "status.importing_vamsas_session_from", new Object[]
2083 { file.getName() }), file.hashCode());
2084 jalview.bin.Cache.log.error(
2085 "New vamsas session from existing session file failed:", ex);
2088 setupVamsasConnectedGui();
2089 v_client.initial_update(); // TODO: thread ?
2090 setProgressBar(MessageManager.formatMessage(
2091 "status.importing_vamsas_session_from", new Object[]
2092 { file.getName() }), file.hashCode());
2093 return v_client.inSession();
2096 public boolean joinVamsasSession(String mysesid)
2098 if (v_client != null)
2100 throw new Error(MessageManager
2101 .getString("error.try_join_vamsas_session_another"));
2103 if (mysesid == null)
2106 MessageManager.getString("error.invalid_vamsas_session_id"));
2108 v_client = new VamsasApplication(this, mysesid);
2109 setupVamsasConnectedGui();
2110 v_client.initial_update();
2111 return (v_client.inSession());
2115 public void vamsasStart_actionPerformed(ActionEvent e)
2117 if (v_client == null)
2120 // we just start a default session for moment.
2122 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2123 * getProperty("LAST_DIRECTORY"));
2125 * chooser.setFileView(new JalviewFileView());
2126 * chooser.setDialogTitle("Load Vamsas file");
2127 * chooser.setToolTipText("Import");
2129 * int value = chooser.showOpenDialog(this);
2131 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2132 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2134 v_client = new VamsasApplication(this);
2135 setupVamsasConnectedGui();
2136 v_client.initial_update(); // TODO: thread ?
2140 // store current data in session.
2141 v_client.push_update(); // TODO: thread
2145 protected void setupVamsasConnectedGui()
2147 vamsasStart.setText(MessageManager.getString("label.session_update"));
2148 vamsasSave.setVisible(true);
2149 vamsasStop.setVisible(true);
2150 vamsasImport.setVisible(false); // Document import to existing session is
2151 // not possible for vamsas-client-1.0.
2154 protected void setupVamsasDisconnectedGui()
2156 vamsasSave.setVisible(false);
2157 vamsasStop.setVisible(false);
2158 vamsasImport.setVisible(true);
2160 .setText(MessageManager.getString("label.new_vamsas_session"));
2164 public void vamsasStop_actionPerformed(ActionEvent e)
2166 if (v_client != null)
2168 v_client.end_session();
2170 setupVamsasDisconnectedGui();
2174 protected void buildVamsasStMenu()
2176 if (v_client == null)
2178 String[] sess = null;
2181 sess = VamsasApplication.getSessionList();
2182 } catch (Exception e)
2184 jalview.bin.Cache.log.warn("Problem getting current sessions list.",
2190 jalview.bin.Cache.log.debug(
2191 "Got current sessions list: " + sess.length + " entries.");
2192 VamsasStMenu.removeAll();
2193 for (int i = 0; i < sess.length; i++)
2195 JMenuItem sessit = new JMenuItem();
2196 sessit.setText(sess[i]);
2197 sessit.setToolTipText(MessageManager
2198 .formatMessage("label.connect_to_session", new Object[]
2200 final Desktop dsktp = this;
2201 final String mysesid = sess[i];
2202 sessit.addActionListener(new ActionListener()
2206 public void actionPerformed(ActionEvent e)
2208 if (dsktp.v_client == null)
2210 Thread rthr = new Thread(new Runnable()
2216 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2217 dsktp.setupVamsasConnectedGui();
2218 dsktp.v_client.initial_update();
2226 VamsasStMenu.add(sessit);
2228 // don't show an empty menu.
2229 VamsasStMenu.setVisible(sess.length > 0);
2234 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2235 VamsasStMenu.removeAll();
2236 VamsasStMenu.setVisible(false);
2241 // Not interested in the content. Just hide ourselves.
2242 VamsasStMenu.setVisible(false);
2247 public void vamsasSave_actionPerformed(ActionEvent e)
2249 if (v_client != null)
2251 // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2252 JalviewFileChooser chooser = new JalviewFileChooser("vdj",
2255 chooser.setFileView(new JalviewFileView());
2256 chooser.setDialogTitle(MessageManager
2257 .getString("label.save_vamsas_document_archive"));
2259 int value = chooser.showSaveDialog(this);
2261 if (value == JalviewFileChooser.APPROVE_OPTION)
2263 java.io.File choice = chooser.getSelectedFile();
2264 JPanel progpanel = addProgressPanel(MessageManager
2265 .formatMessage("label.saving_vamsas_doc", new Object[]
2266 { choice.getName() }));
2267 Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2268 String warnmsg = null;
2269 String warnttl = null;
2272 v_client.vclient.storeDocument(choice);
2275 warnttl = "Serious Problem saving Vamsas Document";
2276 warnmsg = ex.toString();
2277 jalview.bin.Cache.log
2278 .error("Error Whilst saving document to " + choice, ex);
2280 } catch (Exception ex)
2282 warnttl = "Problem saving Vamsas Document.";
2283 warnmsg = ex.toString();
2284 jalview.bin.Cache.log.warn(
2285 "Exception Whilst saving document to " + choice, ex);
2288 removeProgressPanel(progpanel);
2289 if (warnmsg != null)
2291 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2293 warnmsg, warnttl, JvOptionPane.ERROR_MESSAGE);
2299 JPanel vamUpdate = null;
2302 * hide vamsas user gui bits when a vamsas document event is being handled.
2305 * true to hide gui, false to reveal gui
2307 public void setVamsasUpdate(boolean b)
2309 Cache.log.debug("Setting gui for Vamsas update "
2310 + (b ? "in progress" : "finished"));
2312 if (vamUpdate != null)
2314 this.removeProgressPanel(vamUpdate);
2318 vamUpdate = this.addProgressPanel(
2319 MessageManager.getString("label.updating_vamsas_session"));
2321 vamsasStart.setVisible(!b);
2322 vamsasStop.setVisible(!b);
2323 vamsasSave.setVisible(!b);
2326 public JInternalFrame[] getAllFrames()
2328 return desktop.getAllFrames();
2332 * Checks the given url to see if it gives a response indicating that the user
2333 * should be informed of a new questionnaire.
2337 public void checkForQuestionnaire(String url)
2339 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2340 // javax.swing.SwingUtilities.invokeLater(jvq);
2341 new Thread(jvq).start();
2344 public void checkURLLinks()
2346 // Thread off the URL link checker
2347 addDialogThread(new Runnable()
2352 if (Cache.getDefault("CHECKURLLINKS", true))
2354 // check what the actual links are - if it's just the default don't
2355 // bother with the warning
2356 List<String> links = Preferences.sequenceUrlLinks
2359 // only need to check links if there is one with a
2360 // SEQUENCE_ID which is not the default EMBL_EBI link
2361 ListIterator<String> li = links.listIterator();
2362 boolean check = false;
2363 List<JLabel> urls = new ArrayList<JLabel>();
2364 while (li.hasNext())
2366 String link = li.next();
2367 if (link.contains(SEQUENCE_ID)
2368 && !link.equals(UrlConstants.DEFAULT_STRING))
2371 int barPos = link.indexOf("|");
2372 String urlMsg = barPos == -1 ? link
2373 : link.substring(0, barPos) + ": "
2374 + link.substring(barPos + 1);
2375 urls.add(new JLabel(urlMsg));
2383 // ask user to check in case URL links use old style tokens
2384 // ($SEQUENCE_ID$ for sequence id _or_ accession id)
2385 JPanel msgPanel = new JPanel();
2386 msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
2387 msgPanel.add(Box.createVerticalGlue());
2388 JLabel msg = new JLabel(MessageManager
2389 .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
2390 JLabel msg2 = new JLabel(MessageManager
2391 .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
2393 for (JLabel url : urls)
2399 final JCheckBox jcb = new JCheckBox(
2400 MessageManager.getString("label.do_not_display_again"));
2401 jcb.addActionListener(new ActionListener()
2404 public void actionPerformed(ActionEvent e)
2406 // update Cache settings for "don't show this again"
2407 boolean showWarningAgain = !jcb.isSelected();
2408 Cache.setProperty("CHECKURLLINKS",
2409 Boolean.valueOf(showWarningAgain).toString());
2414 JvOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
2416 .getString("label.SEQUENCE_ID_no_longer_used"),
2417 JvOptionPane.WARNING_MESSAGE);
2424 * Proxy class for JDesktopPane which optionally displays the current memory
2425 * usage and highlights the desktop area with a red bar if free memory runs
2430 public class MyDesktopPane extends JDesktopPane implements Runnable
2433 private static final float ONE_MB = 1048576f;
2435 boolean showMemoryUsage = false;
2439 java.text.NumberFormat df;
2441 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2444 public MyDesktopPane(boolean showMemoryUsage)
2446 showMemoryUsage(showMemoryUsage);
2449 public void showMemoryUsage(boolean showMemory)
2451 this.showMemoryUsage = showMemory;
2454 Thread worker = new Thread(this);
2459 public boolean isShowMemoryUsage()
2461 return showMemoryUsage;
2467 df = java.text.NumberFormat.getNumberInstance();
2468 df.setMaximumFractionDigits(2);
2469 runtime = Runtime.getRuntime();
2471 while (showMemoryUsage)
2475 maxMemory = runtime.maxMemory() / ONE_MB;
2476 allocatedMemory = runtime.totalMemory() / ONE_MB;
2477 freeMemory = runtime.freeMemory() / ONE_MB;
2478 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2480 percentUsage = (totalFreeMemory / maxMemory) * 100;
2482 // if (percentUsage < 20)
2484 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2486 // instance.set.setBorder(border1);
2489 // sleep after showing usage
2491 } catch (Exception ex)
2493 ex.printStackTrace();
2499 public void paintComponent(Graphics g)
2501 if (showMemoryUsage && g != null && df != null)
2503 if (percentUsage < 20)
2505 g.setColor(Color.red);
2507 FontMetrics fm = g.getFontMetrics();
2510 g.drawString(MessageManager.formatMessage("label.memory_stats",
2512 { df.format(totalFreeMemory), df.format(maxMemory),
2513 df.format(percentUsage) }),
2514 10, getHeight() - fm.getHeight());
2521 * fixes stacking order after a modal dialog to ensure windows that should be
2522 * on top actually are
2524 public void relayerWindows()
2530 * Accessor method to quickly get all the AlignmentFrames loaded.
2532 * @return an array of AlignFrame, or null if none found
2534 public static AlignFrame[] getAlignFrames()
2536 if (Jalview.isHeadlessMode())
2538 // Desktop.desktop is null in headless mode
2539 return new AlignFrame[] { Jalview.currentAlignFrame };
2542 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2548 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2550 for (int i = frames.length - 1; i > -1; i--)
2552 if (frames[i] instanceof AlignFrame)
2554 avp.add((AlignFrame) frames[i]);
2556 else if (frames[i] instanceof SplitFrame)
2559 * Also check for a split frame containing an AlignFrame
2561 GSplitFrame sf = (GSplitFrame) frames[i];
2562 if (sf.getTopFrame() instanceof AlignFrame)
2564 avp.add((AlignFrame) sf.getTopFrame());
2566 if (sf.getBottomFrame() instanceof AlignFrame)
2568 avp.add((AlignFrame) sf.getBottomFrame());
2572 if (avp.size() == 0)
2576 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2581 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2585 public GStructureViewer[] getJmols()
2587 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2593 List<GStructureViewer> avp = new ArrayList<GStructureViewer>();
2595 for (int i = frames.length - 1; i > -1; i--)
2597 if (frames[i] instanceof AppJmol)
2599 GStructureViewer af = (GStructureViewer) frames[i];
2603 if (avp.size() == 0)
2607 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2612 * Add Groovy Support to Jalview
2615 public void groovyShell_actionPerformed()
2619 openGroovyConsole();
2620 } catch (Exception ex)
2622 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2623 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2625 MessageManager.getString("label.couldnt_create_groovy_shell"),
2626 MessageManager.getString("label.groovy_support_failed"),
2627 JvOptionPane.ERROR_MESSAGE);
2632 * Open the Groovy console
2634 void openGroovyConsole()
2636 if (groovyConsole == null)
2638 groovyConsole = new groovy.ui.Console();
2639 groovyConsole.setVariable("Jalview", this);
2640 groovyConsole.run();
2643 * We allow only one console at a time, so that AlignFrame menu option
2644 * 'Calculate | Run Groovy script' is unambiguous.
2645 * Disable 'Groovy Console', and enable 'Run script', when the console is
2646 * opened, and the reverse when it is closed
2648 Window window = (Window) groovyConsole.getFrame();
2649 window.addWindowListener(new WindowAdapter()
2652 public void windowClosed(WindowEvent e)
2655 * rebind CMD-Q from Groovy Console to Jalview Quit
2658 enableExecuteGroovy(false);
2664 * show Groovy console window (after close and reopen)
2666 ((Window) groovyConsole.getFrame()).setVisible(true);
2669 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2670 * and disable opening a second console
2672 enableExecuteGroovy(true);
2676 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2677 * binding when opened
2679 protected void addQuitHandler()
2681 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
2682 .put(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
2683 Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
2685 getRootPane().getActionMap().put("Quit", new AbstractAction()
2688 public void actionPerformed(ActionEvent e)
2696 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2699 * true if Groovy console is open
2701 public void enableExecuteGroovy(boolean enabled)
2704 * disable opening a second Groovy console
2705 * (or re-enable when the console is closed)
2707 groovyShell.setEnabled(!enabled);
2709 AlignFrame[] alignFrames = getAlignFrames();
2710 if (alignFrames != null)
2712 for (AlignFrame af : alignFrames)
2714 af.setGroovyEnabled(enabled);
2720 * Progress bars managed by the IProgressIndicator method.
2722 private Hashtable<Long, JPanel> progressBars;
2724 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2729 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2732 public void setProgressBar(String message, long id)
2734 if (progressBars == null)
2736 progressBars = new Hashtable<Long, JPanel>();
2737 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2740 if (progressBars.get(new Long(id)) != null)
2742 JPanel panel = progressBars.remove(new Long(id));
2743 if (progressBarHandlers.contains(new Long(id)))
2745 progressBarHandlers.remove(new Long(id));
2747 removeProgressPanel(panel);
2751 progressBars.put(new Long(id), addProgressPanel(message));
2758 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2759 * jalview.gui.IProgressIndicatorHandler)
2762 public void registerHandler(final long id,
2763 final IProgressIndicatorHandler handler)
2765 if (progressBarHandlers == null
2766 || !progressBars.containsKey(new Long(id)))
2768 throw new Error(MessageManager.getString(
2769 "error.call_setprogressbar_before_registering_handler"));
2771 progressBarHandlers.put(new Long(id), handler);
2772 final JPanel progressPanel = progressBars.get(new Long(id));
2773 if (handler.canCancel())
2775 JButton cancel = new JButton(
2776 MessageManager.getString("action.cancel"));
2777 final IProgressIndicator us = this;
2778 cancel.addActionListener(new ActionListener()
2782 public void actionPerformed(ActionEvent e)
2784 handler.cancelActivity(id);
2785 us.setProgressBar(MessageManager
2786 .formatMessage("label.cancelled_params", new Object[]
2787 { ((JLabel) progressPanel.getComponent(0)).getText() }),
2791 progressPanel.add(cancel, BorderLayout.EAST);
2797 * @return true if any progress bars are still active
2800 public boolean operationInProgress()
2802 if (progressBars != null && progressBars.size() > 0)
2810 * This will return the first AlignFrame holding the given viewport instance.
2811 * It will break if there are more than one AlignFrames viewing a particular
2815 * @return alignFrame for viewport
2817 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2819 if (desktop != null)
2821 AlignmentPanel[] aps = getAlignmentPanels(
2822 viewport.getSequenceSetId());
2823 for (int panel = 0; aps != null && panel < aps.length; panel++)
2825 if (aps[panel] != null && aps[panel].av == viewport)
2827 return aps[panel].alignFrame;
2834 public VamsasApplication getVamsasApplication()
2841 * flag set if jalview GUI is being operated programmatically
2843 private boolean inBatchMode = false;
2846 * check if jalview GUI is being operated programmatically
2848 * @return inBatchMode
2850 public boolean isInBatchMode()
2856 * set flag if jalview GUI is being operated programmatically
2858 * @param inBatchMode
2860 public void setInBatchMode(boolean inBatchMode)
2862 this.inBatchMode = inBatchMode;
2865 public void startServiceDiscovery()
2867 startServiceDiscovery(false);
2870 public void startServiceDiscovery(boolean blocking)
2872 boolean alive = true;
2873 Thread t0 = null, t1 = null, t2 = null;
2874 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2877 // todo: changesupport handlers need to be transferred
2878 if (discoverer == null)
2880 discoverer = new jalview.ws.jws1.Discoverer();
2881 // register PCS handler for desktop.
2882 discoverer.addPropertyChangeListener(changeSupport);
2884 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2885 // until we phase out completely
2886 (t0 = new Thread(discoverer)).start();
2889 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2891 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2892 .startDiscoverer(changeSupport);
2896 // TODO: do rest service discovery
2905 } catch (Exception e)
2908 alive = (t1 != null && t1.isAlive()) || (t2 != null && t2.isAlive())
2909 || (t3 != null && t3.isAlive())
2910 || (t0 != null && t0.isAlive());
2916 * called to check if the service discovery process completed successfully.
2920 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2922 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2924 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2925 .getErrorMessages();
2928 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2930 if (serviceChangedDialog == null)
2932 // only run if we aren't already displaying one of these.
2933 addDialogThread(serviceChangedDialog = new Runnable()
2940 * JalviewDialog jd =new JalviewDialog() {
2942 * @Override protected void cancelPressed() { // TODO
2943 * Auto-generated method stub
2945 * }@Override protected void okPressed() { // TODO
2946 * Auto-generated method stub
2948 * }@Override protected void raiseClosed() { // TODO
2949 * Auto-generated method stub
2951 * } }; jd.initDialogFrame(new
2952 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2953 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2954 * + " or mis-configured HTTP proxy settings.<br/>" +
2955 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2957 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2958 * ), true, true, "Web Service Configuration Problem", 450,
2961 * jd.waitForInput();
2963 JvOptionPane.showConfirmDialog(Desktop.desktop,
2964 new JLabel("<html><table width=\"450\"><tr><td>"
2965 + ermsg + "</td></tr></table>"
2966 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2967 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2968 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2969 + " Tools->Preferences dialog box to change them.</p></html>"),
2970 "Web Service Configuration Problem",
2971 JvOptionPane.DEFAULT_OPTION,
2972 JvOptionPane.ERROR_MESSAGE);
2973 serviceChangedDialog = null;
2982 "Errors reported by JABA discovery service. Check web services preferences.\n"
2989 private Runnable serviceChangedDialog = null;
2992 * start a thread to open a URL in the configured browser. Pops up a warning
2993 * dialog to the user if there is an exception when calling out to the browser
2998 public static void showUrl(final String url)
3000 showUrl(url, Desktop.instance);
3004 * Like showUrl but allows progress handler to be specified
3008 * (null) or object implementing IProgressIndicator
3010 public static void showUrl(final String url,
3011 final IProgressIndicator progress)
3013 new Thread(new Runnable()
3020 if (progress != null)
3022 progress.setProgressBar(MessageManager
3023 .formatMessage("status.opening_params", new Object[]
3024 { url }), this.hashCode());
3026 jalview.util.BrowserLauncher.openURL(url);
3027 } catch (Exception ex)
3029 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
3031 .getString("label.web_browser_not_found_unix"),
3032 MessageManager.getString("label.web_browser_not_found"),
3033 JvOptionPane.WARNING_MESSAGE);
3035 ex.printStackTrace();
3037 if (progress != null)
3039 progress.setProgressBar(null, this.hashCode());
3045 public static WsParamSetManager wsparamManager = null;
3047 public static ParamManager getUserParameterStore()
3049 if (wsparamManager == null)
3051 wsparamManager = new WsParamSetManager();
3053 return wsparamManager;
3057 * static hyperlink handler proxy method for use by Jalview's internal windows
3061 public static void hyperlinkUpdate(HyperlinkEvent e)
3063 if (e.getEventType() == EventType.ACTIVATED)
3068 url = e.getURL().toString();
3069 Desktop.showUrl(url);
3070 } catch (Exception x)
3074 if (Cache.log != null)
3076 Cache.log.error("Couldn't handle string " + url + " as a URL.");
3081 "Couldn't handle string " + url + " as a URL.");
3084 // ignore any exceptions due to dud links.
3091 * single thread that handles display of dialogs to user.
3093 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
3096 * flag indicating if dialogExecutor should try to acquire a permit
3098 private volatile boolean dialogPause = true;
3103 private java.util.concurrent.Semaphore block = new Semaphore(0);
3105 private static groovy.ui.Console groovyConsole;
3108 * add another dialog thread to the queue
3112 public void addDialogThread(final Runnable prompter)
3114 dialogExecutor.submit(new Runnable()
3124 } catch (InterruptedException x)
3129 if (instance == null)
3135 SwingUtilities.invokeAndWait(prompter);
3136 } catch (Exception q)
3138 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3144 public void startDialogQueue()
3146 // set the flag so we don't pause waiting for another permit and semaphore
3147 // the current task to begin
3148 dialogPause = false;
3153 protected void snapShotWindow_actionPerformed(ActionEvent e)
3157 ImageMaker im = new jalview.util.ImageMaker(
3158 this, ImageMaker.TYPE.EPS, "View of Desktop", getWidth(),
3159 getHeight(), of = new File("Jalview_snapshot"
3160 + System.currentTimeMillis() + ".eps"),
3161 "View of desktop", null, 0, false);
3164 paintAll(im.getGraphics());
3166 } catch (Exception q)
3168 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3172 Cache.log.info("Successfully written snapshot to file "
3173 + of.getAbsolutePath());
3177 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3178 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3179 * and location last time the view was expanded (if any). However it does not
3180 * remember the split pane divider location - this is set to match the
3181 * 'exploding' frame.
3185 public void explodeViews(SplitFrame sf)
3187 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3188 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3189 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3191 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3193 int viewCount = topPanels.size();
3200 * Processing in reverse order works, forwards order leaves the first panels
3201 * not visible. I don't know why!
3203 for (int i = viewCount - 1; i >= 0; i--)
3206 * Make new top and bottom frames. These take over the respective
3207 * AlignmentPanel objects, including their AlignmentViewports, so the
3208 * cdna/protein relationships between the viewports is carried over to the
3211 * explodedGeometry holds the (x, y) position of the previously exploded
3212 * SplitFrame, and the (width, height) of the AlignFrame component
3214 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3215 AlignFrame newTopFrame = new AlignFrame(topPanel);
3216 newTopFrame.setSize(oldTopFrame.getSize());
3217 newTopFrame.setVisible(true);
3218 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3219 .getExplodedGeometry();
3220 if (geometry != null)
3222 newTopFrame.setSize(geometry.getSize());
3225 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3226 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3227 newBottomFrame.setSize(oldBottomFrame.getSize());
3228 newBottomFrame.setVisible(true);
3229 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3230 .getExplodedGeometry();
3231 if (geometry != null)
3233 newBottomFrame.setSize(geometry.getSize());
3236 topPanel.av.setGatherViewsHere(false);
3237 bottomPanel.av.setGatherViewsHere(false);
3238 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3240 if (geometry != null)
3242 splitFrame.setLocation(geometry.getLocation());
3244 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3248 * Clear references to the panels (now relocated in the new SplitFrames)
3249 * before closing the old SplitFrame.
3252 bottomPanels.clear();
3257 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3258 * back into the given SplitFrame as additional views. Note that the gathered
3259 * frames may themselves have multiple views.
3263 public void gatherViews(GSplitFrame source)
3266 * special handling of explodedGeometry for a view within a SplitFrame: - it
3267 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3268 * height) of the AlignFrame component
3270 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3271 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3272 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3273 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3274 myBottomFrame.viewport
3275 .setExplodedGeometry(new Rectangle(source.getX(), source.getY(),
3276 myBottomFrame.getWidth(), myBottomFrame.getHeight()));
3277 myTopFrame.viewport.setGatherViewsHere(true);
3278 myBottomFrame.viewport.setGatherViewsHere(true);
3279 String topViewId = myTopFrame.viewport.getSequenceSetId();
3280 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3282 JInternalFrame[] frames = desktop.getAllFrames();
3283 for (JInternalFrame frame : frames)
3285 if (frame instanceof SplitFrame && frame != source)
3287 SplitFrame sf = (SplitFrame) frame;
3288 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3289 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3290 boolean gatherThis = false;
3291 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3293 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3294 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3295 if (topViewId.equals(topPanel.av.getSequenceSetId())
3296 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3299 topPanel.av.setGatherViewsHere(false);
3300 bottomPanel.av.setGatherViewsHere(false);
3301 topPanel.av.setExplodedGeometry(
3302 new Rectangle(sf.getLocation(), topFrame.getSize()));
3303 bottomPanel.av.setExplodedGeometry(
3304 new Rectangle(sf.getLocation(), bottomFrame.getSize()));
3305 myTopFrame.addAlignmentPanel(topPanel, false);
3306 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3312 topFrame.getAlignPanels().clear();
3313 bottomFrame.getAlignPanels().clear();
3320 * The dust settles...give focus to the tab we did this from.
3322 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3325 public static groovy.ui.Console getGroovyConsole()
3327 return groovyConsole;
3330 public static void transferFromDropTarget(List<String> files,
3331 List<DataSourceType> protocols, DropTargetDropEvent evt,
3332 Transferable t) throws Exception
3335 DataFlavor uriListFlavor = new DataFlavor(
3336 "text/uri-list;class=java.lang.String");
3337 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3339 // Works on Windows and MacOSX
3340 Cache.log.debug("Drop handled as javaFileListFlavor");
3341 for (Object file : (List) t
3342 .getTransferData(DataFlavor.javaFileListFlavor))
3344 files.add(((File) file).toString());
3345 protocols.add(DataSourceType.FILE);
3350 // Unix like behaviour
3351 boolean added = false;
3353 if (t.isDataFlavorSupported(uriListFlavor))
3355 Cache.log.debug("Drop handled as uriListFlavor");
3356 // This is used by Unix drag system
3357 data = (String) t.getTransferData(uriListFlavor);
3361 // fallback to text: workaround - on OSX where there's a JVM bug
3362 Cache.log.debug("standard URIListFlavor failed. Trying text");
3363 // try text fallback
3364 data = (String) t.getTransferData(
3365 new DataFlavor("text/plain;class=java.lang.String"));
3366 if (Cache.log.isDebugEnabled())
3368 Cache.log.debug("fallback returned " + data);
3371 while (protocols.size() < files.size())
3373 Cache.log.debug("Adding missing FILE protocol for "
3374 + files.get(protocols.size()));
3375 protocols.add(DataSourceType.FILE);
3377 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3378 data, "\r\n"); st.hasMoreTokens();)
3381 String s = st.nextToken();
3382 if (s.startsWith("#"))
3384 // the line is a comment (as per the RFC 2483)
3387 java.net.URI uri = new java.net.URI(s);
3388 if (uri.getScheme().toLowerCase().startsWith("http"))
3390 protocols.add(DataSourceType.URL);
3391 files.add(uri.toString());
3395 // otherwise preserve old behaviour: catch all for file objects
3396 java.io.File file = new java.io.File(uri);
3397 protocols.add(DataSourceType.FILE);
3398 files.add(file.toString());
3401 if (Cache.log.isDebugEnabled())
3403 if (data == null || !added)
3406 "Couldn't resolve drop data. Here are the supported flavors:");
3407 for (DataFlavor fl : t.getTransferDataFlavors())
3410 "Supported transfer dataflavor: " + fl.toString());
3411 Object df = t.getTransferData(fl);
3414 Cache.log.debug("Retrieves: " + df);
3418 Cache.log.debug("Retrieved nothing");
3427 * Sets the Preferences property for experimental features to True or False
3428 * depending on the state of the controlling menu item
3431 protected void showExperimental_actionPerformed(boolean selected)
3433 Cache.setProperty(EXPERIMENTAL_FEATURES, Boolean.toString(selected));