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);
276 public void endResizingFrame(JComponent f)
278 delegate.endResizingFrame(f);
283 public void iconifyFrame(JInternalFrame f)
285 delegate.iconifyFrame(f);
289 public void maximizeFrame(JInternalFrame f)
291 delegate.maximizeFrame(f);
295 public void minimizeFrame(JInternalFrame f)
297 delegate.minimizeFrame(f);
301 public void openFrame(JInternalFrame f)
303 delegate.openFrame(f);
307 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
314 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
318 public void setBoundsForFrame(JComponent f, int newX, int newY,
319 int newWidth, int newHeight)
321 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
324 // All other methods, simply delegate
329 * Creates a new Desktop object.
334 * A note to implementors. It is ESSENTIAL that any activities that might
335 * block are spawned off as threads rather than waited for during this
339 doVamsasClientCheck();
341 doConfigureStructurePrefs();
342 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
343 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
344 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
346 boolean showjconsole = jalview.bin.Cache.getDefault("SHOW_JAVA_CONSOLE",
348 desktop = new MyDesktopPane(selmemusage);
349 if (Platform.isAMac())
351 desktop.setDoubleBuffered(false);
353 showMemusage.setSelected(selmemusage);
354 desktop.setBackground(Color.white);
355 getContentPane().setLayout(new BorderLayout());
356 // alternate config - have scrollbars - see notes in JAL-153
357 // JScrollPane sp = new JScrollPane();
358 // sp.getViewport().setView(desktop);
359 // getContentPane().add(sp, BorderLayout.CENTER);
360 getContentPane().add(desktop, BorderLayout.CENTER);
361 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
363 // This line prevents Windows Look&Feel resizing all new windows to maximum
364 // if previous window was maximised
365 desktop.setDesktopManager(
366 new MyDesktopManager(new DefaultDesktopManager()));
368 Rectangle dims = getLastKnownDimensions("");
375 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
376 setBounds((screenSize.width - 900) / 2, (screenSize.height - 650) / 2,
379 jconsole = new Console(this, showjconsole);
380 // add essential build information
382 "Jalview Version: " + jalview.bin.Cache.getProperty("VERSION")
383 + "\n" + "Jalview Installation: "
384 + jalview.bin.Cache.getDefault("INSTALLATION",
386 + "\n" + "Build Date: "
387 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
388 + "\n" + "Java version: "
389 + System.getProperty("java.version") + "\n"
390 + System.getProperty("os.arch") + " "
391 + System.getProperty("os.name") + " "
392 + System.getProperty("os.version"));
394 showConsole(showjconsole);
396 showNews.setVisible(false);
398 experimentalFeatures.setSelected(showExperimental());
400 getIdentifiersOrgData();
404 this.addWindowListener(new WindowAdapter()
407 public void windowClosing(WindowEvent evt)
414 this.addMouseListener(ma = new MouseAdapter()
417 public void mousePressed(MouseEvent evt)
419 if (evt.isPopupTrigger()) // Mac
421 showPasteMenu(evt.getX(), evt.getY());
426 public void mouseReleased(MouseEvent evt)
428 if (evt.isPopupTrigger()) // Windows
430 showPasteMenu(evt.getX(), evt.getY());
434 desktop.addMouseListener(ma);
436 this.addFocusListener(new FocusListener()
440 public void focusLost(FocusEvent e)
442 // TODO Auto-generated method stub
447 public void focusGained(FocusEvent e)
449 Cache.log.debug("Relaying windows after focus gain");
450 // make sure that we sort windows properly after we gain focus
451 instance.relayerWindows();
454 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
455 // Spawn a thread that shows the splashscreen
456 SwingUtilities.invokeLater(new Runnable()
465 // Thread off a new instance of the file chooser - this reduces the time it
466 // takes to open it later on.
467 new Thread(new Runnable()
472 Cache.log.debug("Filechooser init thread started.");
473 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
474 JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"),
476 Cache.log.debug("Filechooser init thread finished.");
479 // Add the service change listener
480 changeSupport.addJalviewPropertyChangeListener("services",
481 new PropertyChangeListener()
485 public void propertyChange(PropertyChangeEvent evt)
487 Cache.log.debug("Firing service changed event for "
488 + evt.getNewValue());
489 JalviewServicesChanged(evt);
496 * Answers true if user preferences to enable experimental features is True
501 public boolean showExperimental()
503 String experimental = Cache.getDefault(EXPERIMENTAL_FEATURES,
504 Boolean.FALSE.toString());
505 return Boolean.valueOf(experimental).booleanValue();
508 public void doConfigureStructurePrefs()
510 // configure services
511 StructureSelectionManager ssm = StructureSelectionManager
512 .getStructureSelectionManager(this);
513 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
515 ssm.setAddTempFacAnnot(jalview.bin.Cache
516 .getDefault(Preferences.ADD_TEMPFACT_ANN, true));
517 ssm.setProcessSecondaryStructure(jalview.bin.Cache
518 .getDefault(Preferences.STRUCT_FROM_PDB, true));
519 ssm.setSecStructServices(
520 jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW, true));
524 ssm.setAddTempFacAnnot(false);
525 ssm.setProcessSecondaryStructure(false);
526 ssm.setSecStructServices(false);
530 public void checkForNews()
532 final Desktop me = this;
533 // Thread off the news reader, in case there are connection problems.
534 addDialogThread(new Runnable()
539 Cache.log.debug("Starting news thread.");
541 jvnews = new BlogReader(me);
542 showNews.setVisible(true);
543 Cache.log.debug("Completed news thread.");
548 public void getIdentifiersOrgData()
550 // Thread off the identifiers fetcher
551 addDialogThread(new Runnable()
556 Cache.log.debug("Downloading data from identifiers.org");
557 UrlDownloadClient client = new UrlDownloadClient();
560 client.download(IdOrgSettings.getUrl(),
561 IdOrgSettings.getDownloadLocation());
562 } catch (IOException e)
564 Cache.log.debug("Exception downloading identifiers.org data"
572 protected void showNews_actionPerformed(ActionEvent e)
574 showNews(showNews.isSelected());
577 void showNews(boolean visible)
580 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
581 showNews.setSelected(visible);
582 if (visible && !jvnews.isVisible())
584 new Thread(new Runnable()
589 long now = System.currentTimeMillis();
590 Desktop.instance.setProgressBar(
591 MessageManager.getString("status.refreshing_news"),
593 jvnews.refreshNews();
594 Desktop.instance.setProgressBar(null, now);
603 * recover the last known dimensions for a jalview window
606 * - empty string is desktop, all other windows have unique prefix
607 * @return null or last known dimensions scaled to current geometry (if last
608 * window geom was known)
610 Rectangle getLastKnownDimensions(String windowName)
612 // TODO: lock aspect ratio for scaling desktop Bug #0058199
613 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
614 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
615 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
616 String width = jalview.bin.Cache
617 .getProperty(windowName + "SCREEN_WIDTH");
618 String height = jalview.bin.Cache
619 .getProperty(windowName + "SCREEN_HEIGHT");
620 if ((x != null) && (y != null) && (width != null) && (height != null))
622 int ix = Integer.parseInt(x), iy = Integer.parseInt(y),
623 iw = Integer.parseInt(width), ih = Integer.parseInt(height);
624 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
626 // attempt #1 - try to cope with change in screen geometry - this
627 // version doesn't preserve original jv aspect ratio.
628 // take ratio of current screen size vs original screen size.
629 double sw = ((1f * screenSize.width) / (1f * Integer.parseInt(
630 jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH"))));
631 double sh = ((1f * screenSize.height) / (1f * Integer.parseInt(
632 jalview.bin.Cache.getProperty("SCREENGEOMETRY_HEIGHT"))));
633 // rescale the bounds depending upon the current screen geometry.
634 ix = (int) (ix * sw);
635 iw = (int) (iw * sw);
636 iy = (int) (iy * sh);
637 ih = (int) (ih * sh);
638 while (ix >= screenSize.width)
640 jalview.bin.Cache.log.debug(
641 "Window geometry location recall error: shifting horizontal to within screenbounds.");
642 ix -= screenSize.width;
644 while (iy >= screenSize.height)
646 jalview.bin.Cache.log.debug(
647 "Window geometry location recall error: shifting vertical to within screenbounds.");
648 iy -= screenSize.height;
650 jalview.bin.Cache.log.debug(
651 "Got last known dimensions for " + windowName + ": x:" + ix
652 + " y:" + iy + " width:" + iw + " height:" + ih);
654 // return dimensions for new instance
655 return new Rectangle(ix, iy, iw, ih);
660 private void doVamsasClientCheck()
662 if (jalview.bin.Cache.vamsasJarsPresent())
664 setupVamsasDisconnectedGui();
665 VamsasMenu.setVisible(true);
666 final Desktop us = this;
667 VamsasMenu.addMenuListener(new MenuListener()
669 // this listener remembers when the menu was first selected, and
670 // doesn't rebuild the session list until it has been cleared and
672 boolean refresh = true;
675 public void menuCanceled(MenuEvent e)
681 public void menuDeselected(MenuEvent e)
687 public void menuSelected(MenuEvent e)
691 us.buildVamsasStMenu();
696 vamsasStart.setVisible(true);
700 void showPasteMenu(int x, int y)
702 JPopupMenu popup = new JPopupMenu();
703 JMenuItem item = new JMenuItem(
704 MessageManager.getString("label.paste_new_window"));
705 item.addActionListener(new ActionListener()
708 public void actionPerformed(ActionEvent evt)
715 popup.show(this, x, y);
722 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
723 Transferable contents = c.getContents(this);
725 if (contents != null)
727 String file = (String) contents
728 .getTransferData(DataFlavor.stringFlavor);
730 FileFormatI format = new IdentifyFile().identify(file,
731 DataSourceType.PASTE);
733 new FileLoader().LoadFile(file, DataSourceType.PASTE, format);
736 } catch (Exception ex)
739 "Unable to paste alignment from system clipboard:\n" + ex);
744 * Adds and opens the given frame to the desktop
755 public static synchronized void addInternalFrame(
756 final JInternalFrame frame, String title, int w, int h)
758 addInternalFrame(frame, title, true, w, h, true, false);
762 * Add an internal frame to the Jalview desktop
769 * When true, display frame immediately, otherwise, caller must call
770 * setVisible themselves.
776 public static synchronized void addInternalFrame(
777 final JInternalFrame frame, String title, boolean makeVisible,
780 addInternalFrame(frame, title, makeVisible, w, h, true, false);
784 * Add an internal frame to the Jalview desktop and make it visible
797 public static synchronized void addInternalFrame(
798 final JInternalFrame frame, String title, int w, int h,
801 addInternalFrame(frame, title, true, w, h, resizable, false);
805 * Add an internal frame to the Jalview desktop
812 * When true, display frame immediately, otherwise, caller must call
813 * setVisible themselves.
820 * @param ignoreMinSize
821 * Do not set the default minimum size for frame
823 public static synchronized void addInternalFrame(
824 final JInternalFrame frame, String title, boolean makeVisible,
825 int w, int h, boolean resizable, boolean ignoreMinSize)
828 // TODO: allow callers to determine X and Y position of frame (eg. via
830 // TODO: consider fixing method to update entries in the window submenu with
831 // the current window title
833 frame.setTitle(title);
834 if (frame.getWidth() < 1 || frame.getHeight() < 1)
838 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
839 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
840 // IF JALVIEW IS RUNNING HEADLESS
841 // ///////////////////////////////////////////////
842 if (instance == null || (System.getProperty("java.awt.headless") != null
843 && System.getProperty("java.awt.headless").equals("true")))
852 frame.setMinimumSize(
853 new Dimension(DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT));
855 // Set default dimension for Alignment Frame window.
856 // The Alignment Frame window could be added from a number of places,
858 // I did this here in order not to miss out on any Alignment frame.
859 if (frame instanceof AlignFrame)
861 frame.setMinimumSize(new Dimension(ALIGN_FRAME_DEFAULT_MIN_WIDTH,
862 ALIGN_FRAME_DEFAULT_MIN_HEIGHT));
866 frame.setVisible(makeVisible);
867 frame.setClosable(true);
868 frame.setResizable(resizable);
869 frame.setMaximizable(resizable);
870 frame.setIconifiable(resizable);
871 if (Platform.isAMac())
873 frame.setIconifiable(false);
874 frame.setFrameIcon(null);
875 // frame.setDesktopIcon(null);
876 frame.setDoubleBuffered(false);
878 if (frame.getX() < 1 && frame.getY() < 1)
880 frame.setLocation(xOffset * openFrameCount,
881 yOffset * ((openFrameCount - 1) % 10) + yOffset);
885 * add an entry for the new frame in the Window menu
886 * (and remove it when the frame is closed)
888 final JMenuItem menuItem = new JMenuItem(title);
889 frame.addInternalFrameListener(new InternalFrameAdapter()
892 public void internalFrameActivated(InternalFrameEvent evt)
894 JInternalFrame itf = desktop.getSelectedFrame();
902 public void internalFrameClosed(InternalFrameEvent evt)
904 PaintRefresher.RemoveComponent(frame);
907 * defensive check to prevent frames being
908 * added half off the window
910 if (openFrameCount > 0)
916 * ensure no reference to alignFrame retained by menu item listener
918 if (menuItem.getActionListeners().length > 0)
920 menuItem.removeActionListener(menuItem.getActionListeners()[0]);
922 windowMenu.remove(menuItem);
923 JInternalFrame itf = desktop.getSelectedFrame();
927 if (itf instanceof AlignFrame)
929 Jalview.setCurrentAlignFrame((AlignFrame) itf);
936 menuItem.addActionListener(new ActionListener()
939 public void actionPerformed(ActionEvent e)
943 frame.setSelected(true);
944 frame.setIcon(false);
945 } catch (java.beans.PropertyVetoException ex)
954 windowMenu.add(menuItem);
959 frame.setSelected(true);
960 frame.requestFocus();
961 } catch (java.beans.PropertyVetoException ve)
963 } catch (java.lang.ClassCastException cex)
966 "Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
972 public void lostOwnership(Clipboard clipboard, Transferable contents)
976 Desktop.jalviewClipboard = null;
979 internalCopy = false;
983 public void dragEnter(DropTargetDragEvent evt)
988 public void dragExit(DropTargetEvent evt)
993 public void dragOver(DropTargetDragEvent evt)
998 public void dropActionChanged(DropTargetDragEvent evt)
1009 public void drop(DropTargetDropEvent evt)
1011 boolean success = true;
1012 // JAL-1552 - acceptDrop required before getTransferable call for
1013 // Java's Transferable for native dnd
1014 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
1015 Transferable t = evt.getTransferable();
1016 List<String> files = new ArrayList<>();
1017 List<DataSourceType> protocols = new ArrayList<>();
1021 Desktop.transferFromDropTarget(files, protocols, evt, t);
1022 } catch (Exception e)
1024 e.printStackTrace();
1032 for (int i = 0; i < files.size(); i++)
1034 String file = files.get(i).toString();
1035 DataSourceType protocol = (protocols == null)
1036 ? DataSourceType.FILE
1038 FileFormatI format = null;
1040 if (file.endsWith(".jar"))
1042 format = FileFormat.Jalview;
1047 format = new IdentifyFile().identify(file, protocol);
1050 new FileLoader().LoadFile(file, protocol, format);
1053 } catch (Exception ex)
1058 evt.dropComplete(success); // need this to ensure input focus is properly
1059 // transfered to any new windows created
1069 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
1071 String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
1072 JalviewFileChooser chooser = JalviewFileChooser
1073 .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat);
1075 chooser.setFileView(new JalviewFileView());
1076 chooser.setDialogTitle(
1077 MessageManager.getString("label.open_local_file"));
1078 chooser.setToolTipText(MessageManager.getString("action.open"));
1080 int value = chooser.showOpenDialog(this);
1082 if (value == JalviewFileChooser.APPROVE_OPTION)
1084 String choice = chooser.getSelectedFile().getPath();
1085 Cache.setProperty("LAST_DIRECTORY",
1086 chooser.getSelectedFile().getParent());
1088 FileFormatI format = chooser.getSelectedFormat();
1091 * Call IdentifyFile to verify the file contains what its extension implies.
1092 * Skip this step for dynamically added file formats, because
1093 * IdentifyFile does not know how to recognise them.
1095 if (FileFormats.getInstance().isIdentifiable(format))
1099 format = new IdentifyFile().identify(choice, DataSourceType.FILE);
1100 } catch (FileFormatException e)
1102 // format = null; //??
1106 if (viewport != null)
1108 new FileLoader().LoadFile(viewport, choice, DataSourceType.FILE,
1113 new FileLoader().LoadFile(choice, DataSourceType.FILE, format);
1125 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1127 // This construct allows us to have a wider textfield
1129 JLabel label = new JLabel(
1130 MessageManager.getString("label.input_file_url"));
1131 final JComboBox history = new JComboBox();
1133 JPanel panel = new JPanel(new GridLayout(2, 1));
1136 history.setPreferredSize(new Dimension(400, 20));
1137 history.setEditable(true);
1138 history.addItem("http://www.");
1140 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1144 if (historyItems != null)
1146 st = new StringTokenizer(historyItems, "\t");
1148 while (st.hasMoreTokens())
1150 history.addItem(st.nextElement());
1154 int reply = JvOptionPane.showInternalConfirmDialog(desktop, panel,
1155 MessageManager.getString("label.input_alignment_from_url"),
1156 JvOptionPane.OK_CANCEL_OPTION);
1158 if (reply != JvOptionPane.OK_OPTION)
1163 String url = history.getSelectedItem().toString();
1165 if (url.toLowerCase().endsWith(".jar"))
1167 if (viewport != null)
1169 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1170 FileFormat.Jalview);
1174 new FileLoader().LoadFile(url, DataSourceType.URL,
1175 FileFormat.Jalview);
1180 FileFormatI format = null;
1183 format = new IdentifyFile().identify(url, DataSourceType.URL);
1184 } catch (FileFormatException e)
1186 // TODO revise error handling, distinguish between
1187 // URL not found and response not valid
1192 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1193 MessageManager.formatMessage("label.couldnt_locate",
1196 MessageManager.getString("label.url_not_found"),
1197 JvOptionPane.WARNING_MESSAGE);
1202 if (viewport != null)
1204 new FileLoader().LoadFile(viewport, url, DataSourceType.URL,
1209 new FileLoader().LoadFile(url, DataSourceType.URL, format);
1215 * Opens the CutAndPaste window for the user to paste an alignment in to
1218 * - if not null, the pasted alignment is added to the current
1219 * alignment; if null, to a new alignment window
1222 public void inputTextboxMenuItem_actionPerformed(
1223 AlignmentViewPanel viewPanel)
1225 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1226 cap.setForInput(viewPanel);
1227 Desktop.addInternalFrame(cap,
1228 MessageManager.getString("label.cut_paste_alignmen_file"), true,
1238 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1239 jalview.bin.Cache.setProperty("SCREENGEOMETRY_WIDTH",
1241 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT",
1242 screen.height + "");
1243 storeLastKnownDimensions("", new Rectangle(getBounds().x, getBounds().y,
1244 getWidth(), getHeight()));
1246 if (jconsole != null)
1248 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1249 jconsole.stopConsole();
1253 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1256 if (dialogExecutor != null)
1258 dialogExecutor.shutdownNow();
1260 closeAll_actionPerformed(null);
1262 if (groovyConsole != null)
1264 // suppress a possible repeat prompt to save script
1265 groovyConsole.setDirty(false);
1266 groovyConsole.exit();
1271 private void storeLastKnownDimensions(String string, Rectangle jc)
1273 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1274 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1275 + " height:" + jc.height);
1277 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1278 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1279 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1280 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1290 public void aboutMenuItem_actionPerformed(ActionEvent e)
1292 // StringBuffer message = getAboutMessage(false);
1293 // JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1295 // message.toString(), "About Jalview", JvOptionPane.INFORMATION_MESSAGE);
1296 new Thread(new Runnable()
1301 new SplashScreen(true);
1306 public StringBuffer getAboutMessage(boolean shortv)
1308 StringBuffer message = new StringBuffer();
1309 message.append("<html>");
1312 message.append("<h1><strong>Version: "
1313 + jalview.bin.Cache.getProperty("VERSION")
1314 + "</strong></h1>");
1315 message.append("<strong>Last Updated: <em>"
1316 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1317 + "</em></strong>");
1323 message.append("<strong>Version "
1324 + jalview.bin.Cache.getProperty("VERSION")
1325 + "; last updated: "
1326 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1329 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1330 .equals("Checking"))
1332 message.append("<br>...Checking latest version...</br>");
1334 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1335 .equals(jalview.bin.Cache.getProperty("VERSION")))
1337 boolean red = false;
1338 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1339 .indexOf("automated build") == -1)
1342 // Displayed when code version and jnlp version do not match and code
1343 // version is not a development build
1344 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1347 message.append("<br>!! Version "
1348 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1350 + " is available for download from "
1351 + jalview.bin.Cache.getDefault("www.jalview.org",
1352 "http://www.jalview.org")
1356 message.append("</div>");
1359 message.append("<br>Authors: " + jalview.bin.Cache.getDefault(
1361 "The Jalview Authors (See AUTHORS file for current list)")
1362 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1363 + "<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"
1364 + "<br><br>If you use Jalview, please cite:"
1365 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1366 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1367 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1379 public void documentationMenuItem_actionPerformed(ActionEvent e)
1383 Help.showHelpWindow();
1384 } catch (Exception ex)
1390 public void closeAll_actionPerformed(ActionEvent e)
1392 // TODO show a progress bar while closing?
1393 JInternalFrame[] frames = desktop.getAllFrames();
1394 for (int i = 0; i < frames.length; i++)
1398 frames[i].setClosed(true);
1399 } catch (java.beans.PropertyVetoException ex)
1403 Jalview.setCurrentAlignFrame(null);
1404 System.out.println("ALL CLOSED");
1405 if (v_client != null)
1407 // TODO clear binding to vamsas document objects on close_all
1411 * reset state of singleton objects as appropriate (clear down session state
1412 * when all windows are closed)
1414 StructureSelectionManager ssm = StructureSelectionManager
1415 .getStructureSelectionManager(this);
1424 public void raiseRelated_actionPerformed(ActionEvent e)
1426 reorderAssociatedWindows(false, false);
1430 public void minimizeAssociated_actionPerformed(ActionEvent e)
1432 reorderAssociatedWindows(true, false);
1435 void closeAssociatedWindows()
1437 reorderAssociatedWindows(false, true);
1443 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1447 protected void garbageCollect_actionPerformed(ActionEvent e)
1449 // We simply collect the garbage
1450 jalview.bin.Cache.log.debug("Collecting garbage...");
1452 jalview.bin.Cache.log.debug("Finished garbage collection.");
1459 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1463 protected void showMemusage_actionPerformed(ActionEvent e)
1465 desktop.showMemoryUsage(showMemusage.isSelected());
1472 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1476 protected void showConsole_actionPerformed(ActionEvent e)
1478 showConsole(showConsole.isSelected());
1481 Console jconsole = null;
1484 * control whether the java console is visible or not
1488 void showConsole(boolean selected)
1490 showConsole.setSelected(selected);
1491 // TODO: decide if we should update properties file
1492 Cache.setProperty("SHOW_JAVA_CONSOLE",
1493 Boolean.valueOf(selected).toString());
1494 jconsole.setVisible(selected);
1497 void reorderAssociatedWindows(boolean minimize, boolean close)
1499 JInternalFrame[] frames = desktop.getAllFrames();
1500 if (frames == null || frames.length < 1)
1505 AlignmentViewport source = null, target = null;
1506 if (frames[0] instanceof AlignFrame)
1508 source = ((AlignFrame) frames[0]).getCurrentView();
1510 else if (frames[0] instanceof TreePanel)
1512 source = ((TreePanel) frames[0]).getViewPort();
1514 else if (frames[0] instanceof PCAPanel)
1516 source = ((PCAPanel) frames[0]).av;
1518 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1520 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1525 for (int i = 0; i < frames.length; i++)
1528 if (frames[i] == null)
1532 if (frames[i] instanceof AlignFrame)
1534 target = ((AlignFrame) frames[i]).getCurrentView();
1536 else if (frames[i] instanceof TreePanel)
1538 target = ((TreePanel) frames[i]).getViewPort();
1540 else if (frames[i] instanceof PCAPanel)
1542 target = ((PCAPanel) frames[i]).av;
1544 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1546 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1549 if (source == target)
1555 frames[i].setClosed(true);
1559 frames[i].setIcon(minimize);
1562 frames[i].toFront();
1566 } catch (java.beans.PropertyVetoException ex)
1581 protected void preferences_actionPerformed(ActionEvent e)
1593 public void saveState_actionPerformed(ActionEvent e)
1595 JalviewFileChooser chooser = new JalviewFileChooser("jvp",
1598 chooser.setFileView(new JalviewFileView());
1599 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1601 int value = chooser.showSaveDialog(this);
1603 if (value == JalviewFileChooser.APPROVE_OPTION)
1605 final Desktop me = this;
1606 final java.io.File choice = chooser.getSelectedFile();
1607 setProjectFile(choice);
1609 new Thread(new Runnable()
1614 // TODO: refactor to Jalview desktop session controller action.
1615 setProgressBar(MessageManager.formatMessage(
1616 "label.saving_jalview_project", new Object[]
1617 { choice.getName() }), choice.hashCode());
1618 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1619 choice.getParent());
1620 // TODO catch and handle errors for savestate
1621 // TODO prevent user from messing with the Desktop whilst we're saving
1624 new Jalview2XML().saveState(choice);
1625 } catch (OutOfMemoryError oom)
1628 "Whilst saving current state to " + choice.getName(),
1630 } catch (Exception ex)
1633 "Problems whilst trying to save to " + choice.getName(),
1635 JvOptionPane.showMessageDialog(me,
1636 MessageManager.formatMessage(
1637 "label.error_whilst_saving_current_state_to",
1639 { choice.getName() }),
1640 MessageManager.getString("label.couldnt_save_project"),
1641 JvOptionPane.WARNING_MESSAGE);
1643 setProgressBar(null, choice.hashCode());
1649 private void setProjectFile(File choice)
1651 this.projectFile = choice;
1654 public File getProjectFile()
1656 return this.projectFile;
1666 public void loadState_actionPerformed(ActionEvent e)
1668 JalviewFileChooser chooser = new JalviewFileChooser(
1669 Cache.getProperty("LAST_DIRECTORY"), new String[]
1672 { "Jalview Project", "Jalview Project (old)" },
1674 chooser.setFileView(new JalviewFileView());
1675 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1677 int value = chooser.showOpenDialog(this);
1679 if (value == JalviewFileChooser.APPROVE_OPTION)
1681 final File selectedFile = chooser.getSelectedFile();
1682 setProjectFile(selectedFile);
1683 final String choice = selectedFile.getAbsolutePath();
1684 Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
1685 new Thread(new Runnable()
1690 setProgressBar(MessageManager.formatMessage(
1691 "label.loading_jalview_project", new Object[]
1692 { choice }), choice.hashCode());
1695 new Jalview2XML().loadJalviewAlign(choice);
1696 } catch (OutOfMemoryError oom)
1698 new OOMWarning("Whilst loading project from " + choice, oom);
1699 } catch (Exception ex)
1702 "Problems whilst loading project from " + choice, ex);
1703 JvOptionPane.showMessageDialog(Desktop.desktop,
1704 MessageManager.formatMessage(
1705 "label.error_whilst_loading_project_from",
1708 MessageManager.getString("label.couldnt_load_project"),
1709 JvOptionPane.WARNING_MESSAGE);
1711 setProgressBar(null, choice.hashCode());
1718 public void inputSequence_actionPerformed(ActionEvent e)
1720 new SequenceFetcher(this);
1723 JPanel progressPanel;
1725 ArrayList<JPanel> fileLoadingPanels = new ArrayList<>();
1727 public void startLoading(final String fileName)
1729 if (fileLoadingCount == 0)
1731 fileLoadingPanels.add(addProgressPanel(MessageManager
1732 .formatMessage("label.loading_file", new Object[]
1738 private JPanel addProgressPanel(String string)
1740 if (progressPanel == null)
1742 progressPanel = new JPanel(new GridLayout(1, 1));
1743 totalProgressCount = 0;
1744 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1746 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1747 JProgressBar progressBar = new JProgressBar();
1748 progressBar.setIndeterminate(true);
1750 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1752 thisprogress.add(progressBar, BorderLayout.CENTER);
1753 progressPanel.add(thisprogress);
1754 ((GridLayout) progressPanel.getLayout()).setRows(
1755 ((GridLayout) progressPanel.getLayout()).getRows() + 1);
1756 ++totalProgressCount;
1757 instance.validate();
1758 return thisprogress;
1761 int totalProgressCount = 0;
1763 private void removeProgressPanel(JPanel progbar)
1765 if (progressPanel != null)
1767 synchronized (progressPanel)
1769 progressPanel.remove(progbar);
1770 GridLayout gl = (GridLayout) progressPanel.getLayout();
1771 gl.setRows(gl.getRows() - 1);
1772 if (--totalProgressCount < 1)
1774 this.getContentPane().remove(progressPanel);
1775 progressPanel = null;
1782 public void stopLoading()
1785 if (fileLoadingCount < 1)
1787 while (fileLoadingPanels.size() > 0)
1789 removeProgressPanel(fileLoadingPanels.remove(0));
1791 fileLoadingPanels.clear();
1792 fileLoadingCount = 0;
1797 public static int getViewCount(String alignmentId)
1799 AlignmentViewport[] aps = getViewports(alignmentId);
1800 return (aps == null) ? 0 : aps.length;
1805 * @param alignmentId
1806 * - if null, all sets are returned
1807 * @return all AlignmentPanels concerning the alignmentId sequence set
1809 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1811 if (Desktop.desktop == null)
1813 // no frames created and in headless mode
1814 // TODO: verify that frames are recoverable when in headless mode
1817 List<AlignmentPanel> aps = new ArrayList<>();
1818 AlignFrame[] frames = getAlignFrames();
1823 for (AlignFrame af : frames)
1825 for (AlignmentPanel ap : af.alignPanels)
1827 if (alignmentId == null
1828 || alignmentId.equals(ap.av.getSequenceSetId()))
1834 if (aps.size() == 0)
1838 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1843 * get all the viewports on an alignment.
1845 * @param sequenceSetId
1846 * unique alignment id (may be null - all viewports returned in that
1848 * @return all viewports on the alignment bound to sequenceSetId
1850 public static AlignmentViewport[] getViewports(String sequenceSetId)
1852 List<AlignmentViewport> viewp = new ArrayList<>();
1853 if (desktop != null)
1855 AlignFrame[] frames = Desktop.getAlignFrames();
1857 for (AlignFrame afr : frames)
1859 if (sequenceSetId == null || afr.getViewport().getSequenceSetId()
1860 .equals(sequenceSetId))
1862 if (afr.alignPanels != null)
1864 for (AlignmentPanel ap : afr.alignPanels)
1866 if (sequenceSetId == null
1867 || sequenceSetId.equals(ap.av.getSequenceSetId()))
1875 viewp.add(afr.getViewport());
1879 if (viewp.size() > 0)
1881 return viewp.toArray(new AlignmentViewport[viewp.size()]);
1888 * Explode the views in the given frame into separate AlignFrame
1892 public static void explodeViews(AlignFrame af)
1894 int size = af.alignPanels.size();
1900 for (int i = 0; i < size; i++)
1902 AlignmentPanel ap = af.alignPanels.get(i);
1903 AlignFrame newaf = new AlignFrame(ap);
1906 * Restore the view's last exploded frame geometry if known. Multiple
1907 * views from one exploded frame share and restore the same (frame)
1908 * position and size.
1910 Rectangle geometry = ap.av.getExplodedGeometry();
1911 if (geometry != null)
1913 newaf.setBounds(geometry);
1916 ap.av.setGatherViewsHere(false);
1918 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1919 AlignFrame.DEFAULT_HEIGHT);
1922 af.alignPanels.clear();
1923 af.closeMenuItem_actionPerformed(true);
1928 * Gather expanded views (separate AlignFrame's) with the same sequence set
1929 * identifier back in to this frame as additional views, and close the
1930 * expanded views. Note the expanded frames may themselves have multiple
1931 * views. We take the lot.
1935 public void gatherViews(AlignFrame source)
1937 source.viewport.setGatherViewsHere(true);
1938 source.viewport.setExplodedGeometry(source.getBounds());
1939 JInternalFrame[] frames = desktop.getAllFrames();
1940 String viewId = source.viewport.getSequenceSetId();
1942 for (int t = 0; t < frames.length; t++)
1944 if (frames[t] instanceof AlignFrame && frames[t] != source)
1946 AlignFrame af = (AlignFrame) frames[t];
1947 boolean gatherThis = false;
1948 for (int a = 0; a < af.alignPanels.size(); a++)
1950 AlignmentPanel ap = af.alignPanels.get(a);
1951 if (viewId.equals(ap.av.getSequenceSetId()))
1954 ap.av.setGatherViewsHere(false);
1955 ap.av.setExplodedGeometry(af.getBounds());
1956 source.addAlignmentPanel(ap, false);
1962 af.alignPanels.clear();
1963 af.closeMenuItem_actionPerformed(true);
1970 jalview.gui.VamsasApplication v_client = null;
1973 public void vamsasImport_actionPerformed(ActionEvent e)
1975 if (v_client == null)
1977 // Load and try to start a session.
1978 JalviewFileChooser chooser = new JalviewFileChooser(
1979 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1981 chooser.setFileView(new JalviewFileView());
1982 chooser.setDialogTitle(
1983 MessageManager.getString("label.open_saved_vamsas_session"));
1984 chooser.setToolTipText(MessageManager.getString(
1985 "label.select_vamsas_session_opened_as_new_vamsas_session"));
1987 int value = chooser.showOpenDialog(this);
1989 if (value == JalviewFileChooser.APPROVE_OPTION)
1991 String fle = chooser.getSelectedFile().toString();
1992 if (!vamsasImport(chooser.getSelectedFile()))
1994 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
1995 MessageManager.formatMessage(
1996 "label.couldnt_import_as_vamsas_session",
2000 .getString("label.vamsas_document_import_failed"),
2001 JvOptionPane.ERROR_MESSAGE);
2007 jalview.bin.Cache.log.error(
2008 "Implementation error - load session from a running session is not supported.");
2013 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2016 * @return true if import was a success and a session was started.
2018 public boolean vamsasImport(URL url)
2020 // TODO: create progress bar
2021 if (v_client != null)
2024 jalview.bin.Cache.log.error(
2025 "Implementation error - load session from a running session is not supported.");
2031 // copy the URL content to a temporary local file
2032 // TODO: be a bit cleverer here with nio (?!)
2033 File file = File.createTempFile("vdocfromurl", ".vdj");
2034 FileOutputStream fos = new FileOutputStream(file);
2035 BufferedInputStream bis = new BufferedInputStream(url.openStream());
2036 byte[] buffer = new byte[2048];
2038 while ((ln = bis.read(buffer)) > -1)
2040 fos.write(buffer, 0, ln);
2044 v_client = new jalview.gui.VamsasApplication(this, file,
2045 url.toExternalForm());
2046 } catch (Exception ex)
2048 jalview.bin.Cache.log.error(
2049 "Failed to create new vamsas session from contents of URL "
2054 setupVamsasConnectedGui();
2055 v_client.initial_update(); // TODO: thread ?
2056 return v_client.inSession();
2060 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
2063 * @return true if import was a success and a session was started.
2065 public boolean vamsasImport(File file)
2067 if (v_client != null)
2070 jalview.bin.Cache.log.error(
2071 "Implementation error - load session from a running session is not supported.");
2075 setProgressBar(MessageManager.formatMessage(
2076 "status.importing_vamsas_session_from", new Object[]
2077 { file.getName() }), file.hashCode());
2080 v_client = new jalview.gui.VamsasApplication(this, file, null);
2081 } catch (Exception ex)
2083 setProgressBar(MessageManager.formatMessage(
2084 "status.importing_vamsas_session_from", new Object[]
2085 { file.getName() }), file.hashCode());
2086 jalview.bin.Cache.log.error(
2087 "New vamsas session from existing session file failed:", ex);
2090 setupVamsasConnectedGui();
2091 v_client.initial_update(); // TODO: thread ?
2092 setProgressBar(MessageManager.formatMessage(
2093 "status.importing_vamsas_session_from", new Object[]
2094 { file.getName() }), file.hashCode());
2095 return v_client.inSession();
2098 public boolean joinVamsasSession(String mysesid)
2100 if (v_client != null)
2102 throw new Error(MessageManager
2103 .getString("error.try_join_vamsas_session_another"));
2105 if (mysesid == null)
2108 MessageManager.getString("error.invalid_vamsas_session_id"));
2110 v_client = new VamsasApplication(this, mysesid);
2111 setupVamsasConnectedGui();
2112 v_client.initial_update();
2113 return (v_client.inSession());
2117 public void vamsasStart_actionPerformed(ActionEvent e)
2119 if (v_client == null)
2122 // we just start a default session for moment.
2124 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
2125 * getProperty("LAST_DIRECTORY"));
2127 * chooser.setFileView(new JalviewFileView());
2128 * chooser.setDialogTitle("Load Vamsas file");
2129 * chooser.setToolTipText("Import");
2131 * int value = chooser.showOpenDialog(this);
2133 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
2134 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
2136 v_client = new VamsasApplication(this);
2137 setupVamsasConnectedGui();
2138 v_client.initial_update(); // TODO: thread ?
2142 // store current data in session.
2143 v_client.push_update(); // TODO: thread
2147 protected void setupVamsasConnectedGui()
2149 vamsasStart.setText(MessageManager.getString("label.session_update"));
2150 vamsasSave.setVisible(true);
2151 vamsasStop.setVisible(true);
2152 vamsasImport.setVisible(false); // Document import to existing session is
2153 // not possible for vamsas-client-1.0.
2156 protected void setupVamsasDisconnectedGui()
2158 vamsasSave.setVisible(false);
2159 vamsasStop.setVisible(false);
2160 vamsasImport.setVisible(true);
2162 .setText(MessageManager.getString("label.new_vamsas_session"));
2166 public void vamsasStop_actionPerformed(ActionEvent e)
2168 if (v_client != null)
2170 v_client.end_session();
2172 setupVamsasDisconnectedGui();
2176 protected void buildVamsasStMenu()
2178 if (v_client == null)
2180 String[] sess = null;
2183 sess = VamsasApplication.getSessionList();
2184 } catch (Exception e)
2186 jalview.bin.Cache.log.warn("Problem getting current sessions list.",
2192 jalview.bin.Cache.log.debug(
2193 "Got current sessions list: " + sess.length + " entries.");
2194 VamsasStMenu.removeAll();
2195 for (int i = 0; i < sess.length; i++)
2197 JMenuItem sessit = new JMenuItem();
2198 sessit.setText(sess[i]);
2199 sessit.setToolTipText(MessageManager
2200 .formatMessage("label.connect_to_session", new Object[]
2202 final Desktop dsktp = this;
2203 final String mysesid = sess[i];
2204 sessit.addActionListener(new ActionListener()
2208 public void actionPerformed(ActionEvent e)
2210 if (dsktp.v_client == null)
2212 Thread rthr = new Thread(new Runnable()
2218 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2219 dsktp.setupVamsasConnectedGui();
2220 dsktp.v_client.initial_update();
2228 VamsasStMenu.add(sessit);
2230 // don't show an empty menu.
2231 VamsasStMenu.setVisible(sess.length > 0);
2236 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2237 VamsasStMenu.removeAll();
2238 VamsasStMenu.setVisible(false);
2243 // Not interested in the content. Just hide ourselves.
2244 VamsasStMenu.setVisible(false);
2249 public void vamsasSave_actionPerformed(ActionEvent e)
2251 if (v_client != null)
2253 // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2254 JalviewFileChooser chooser = new JalviewFileChooser("vdj",
2257 chooser.setFileView(new JalviewFileView());
2258 chooser.setDialogTitle(MessageManager
2259 .getString("label.save_vamsas_document_archive"));
2261 int value = chooser.showSaveDialog(this);
2263 if (value == JalviewFileChooser.APPROVE_OPTION)
2265 java.io.File choice = chooser.getSelectedFile();
2266 JPanel progpanel = addProgressPanel(MessageManager
2267 .formatMessage("label.saving_vamsas_doc", new Object[]
2268 { choice.getName() }));
2269 Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2270 String warnmsg = null;
2271 String warnttl = null;
2274 v_client.vclient.storeDocument(choice);
2277 warnttl = "Serious Problem saving Vamsas Document";
2278 warnmsg = ex.toString();
2279 jalview.bin.Cache.log
2280 .error("Error Whilst saving document to " + choice, ex);
2282 } catch (Exception ex)
2284 warnttl = "Problem saving Vamsas Document.";
2285 warnmsg = ex.toString();
2286 jalview.bin.Cache.log.warn(
2287 "Exception Whilst saving document to " + choice, ex);
2290 removeProgressPanel(progpanel);
2291 if (warnmsg != null)
2293 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2295 warnmsg, warnttl, JvOptionPane.ERROR_MESSAGE);
2301 JPanel vamUpdate = null;
2304 * hide vamsas user gui bits when a vamsas document event is being handled.
2307 * true to hide gui, false to reveal gui
2309 public void setVamsasUpdate(boolean b)
2311 Cache.log.debug("Setting gui for Vamsas update "
2312 + (b ? "in progress" : "finished"));
2314 if (vamUpdate != null)
2316 this.removeProgressPanel(vamUpdate);
2320 vamUpdate = this.addProgressPanel(
2321 MessageManager.getString("label.updating_vamsas_session"));
2323 vamsasStart.setVisible(!b);
2324 vamsasStop.setVisible(!b);
2325 vamsasSave.setVisible(!b);
2328 public JInternalFrame[] getAllFrames()
2330 return desktop.getAllFrames();
2334 * Checks the given url to see if it gives a response indicating that the user
2335 * should be informed of a new questionnaire.
2339 public void checkForQuestionnaire(String url)
2341 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2342 // javax.swing.SwingUtilities.invokeLater(jvq);
2343 new Thread(jvq).start();
2346 public void checkURLLinks()
2348 // Thread off the URL link checker
2349 addDialogThread(new Runnable()
2354 if (Cache.getDefault("CHECKURLLINKS", true))
2356 // check what the actual links are - if it's just the default don't
2357 // bother with the warning
2358 List<String> links = Preferences.sequenceUrlLinks
2361 // only need to check links if there is one with a
2362 // SEQUENCE_ID which is not the default EMBL_EBI link
2363 ListIterator<String> li = links.listIterator();
2364 boolean check = false;
2365 List<JLabel> urls = new ArrayList<>();
2366 while (li.hasNext())
2368 String link = li.next();
2369 if (link.contains(SEQUENCE_ID)
2370 && !link.equals(UrlConstants.DEFAULT_STRING))
2373 int barPos = link.indexOf("|");
2374 String urlMsg = barPos == -1 ? link
2375 : link.substring(0, barPos) + ": "
2376 + link.substring(barPos + 1);
2377 urls.add(new JLabel(urlMsg));
2385 // ask user to check in case URL links use old style tokens
2386 // ($SEQUENCE_ID$ for sequence id _or_ accession id)
2387 JPanel msgPanel = new JPanel();
2388 msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
2389 msgPanel.add(Box.createVerticalGlue());
2390 JLabel msg = new JLabel(MessageManager
2391 .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
2392 JLabel msg2 = new JLabel(MessageManager
2393 .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
2395 for (JLabel url : urls)
2401 final JCheckBox jcb = new JCheckBox(
2402 MessageManager.getString("label.do_not_display_again"));
2403 jcb.addActionListener(new ActionListener()
2406 public void actionPerformed(ActionEvent e)
2408 // update Cache settings for "don't show this again"
2409 boolean showWarningAgain = !jcb.isSelected();
2410 Cache.setProperty("CHECKURLLINKS",
2411 Boolean.valueOf(showWarningAgain).toString());
2416 JvOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
2418 .getString("label.SEQUENCE_ID_no_longer_used"),
2419 JvOptionPane.WARNING_MESSAGE);
2426 * Proxy class for JDesktopPane which optionally displays the current memory
2427 * usage and highlights the desktop area with a red bar if free memory runs
2432 public class MyDesktopPane extends JDesktopPane implements Runnable
2435 private static final float ONE_MB = 1048576f;
2437 boolean showMemoryUsage = false;
2441 java.text.NumberFormat df;
2443 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2446 public MyDesktopPane(boolean showMemoryUsage)
2448 showMemoryUsage(showMemoryUsage);
2451 public void showMemoryUsage(boolean showMemory)
2453 this.showMemoryUsage = showMemory;
2456 Thread worker = new Thread(this);
2461 public boolean isShowMemoryUsage()
2463 return showMemoryUsage;
2469 df = java.text.NumberFormat.getNumberInstance();
2470 df.setMaximumFractionDigits(2);
2471 runtime = Runtime.getRuntime();
2473 while (showMemoryUsage)
2477 maxMemory = runtime.maxMemory() / ONE_MB;
2478 allocatedMemory = runtime.totalMemory() / ONE_MB;
2479 freeMemory = runtime.freeMemory() / ONE_MB;
2480 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2482 percentUsage = (totalFreeMemory / maxMemory) * 100;
2484 // if (percentUsage < 20)
2486 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2488 // instance.set.setBorder(border1);
2491 // sleep after showing usage
2493 } catch (Exception ex)
2495 ex.printStackTrace();
2501 public void paintComponent(Graphics g)
2503 if (showMemoryUsage && g != null && df != null)
2505 if (percentUsage < 20)
2507 g.setColor(Color.red);
2509 FontMetrics fm = g.getFontMetrics();
2512 g.drawString(MessageManager.formatMessage("label.memory_stats",
2514 { df.format(totalFreeMemory), df.format(maxMemory),
2515 df.format(percentUsage) }),
2516 10, getHeight() - fm.getHeight());
2523 * fixes stacking order after a modal dialog to ensure windows that should be
2524 * on top actually are
2526 public void relayerWindows()
2532 * Accessor method to quickly get all the AlignmentFrames loaded.
2534 * @return an array of AlignFrame, or null if none found
2536 public static AlignFrame[] getAlignFrames()
2538 if (Jalview.isHeadlessMode())
2540 // Desktop.desktop is null in headless mode
2541 return new AlignFrame[] { Jalview.currentAlignFrame };
2544 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2550 List<AlignFrame> avp = new ArrayList<>();
2552 for (int i = frames.length - 1; i > -1; i--)
2554 if (frames[i] instanceof AlignFrame)
2556 avp.add((AlignFrame) frames[i]);
2558 else if (frames[i] instanceof SplitFrame)
2561 * Also check for a split frame containing an AlignFrame
2563 GSplitFrame sf = (GSplitFrame) frames[i];
2564 if (sf.getTopFrame() instanceof AlignFrame)
2566 avp.add((AlignFrame) sf.getTopFrame());
2568 if (sf.getBottomFrame() instanceof AlignFrame)
2570 avp.add((AlignFrame) sf.getBottomFrame());
2574 if (avp.size() == 0)
2578 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2583 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2587 public GStructureViewer[] getJmols()
2589 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2595 List<GStructureViewer> avp = new ArrayList<>();
2597 for (int i = frames.length - 1; i > -1; i--)
2599 if (frames[i] instanceof AppJmol)
2601 GStructureViewer af = (GStructureViewer) frames[i];
2605 if (avp.size() == 0)
2609 GStructureViewer afs[] = avp.toArray(new GStructureViewer[avp.size()]);
2614 * Add Groovy Support to Jalview
2617 public void groovyShell_actionPerformed()
2621 openGroovyConsole();
2622 } catch (Exception ex)
2624 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2625 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
2627 MessageManager.getString("label.couldnt_create_groovy_shell"),
2628 MessageManager.getString("label.groovy_support_failed"),
2629 JvOptionPane.ERROR_MESSAGE);
2634 * Open the Groovy console
2636 void openGroovyConsole()
2638 if (groovyConsole == null)
2640 groovyConsole = new groovy.ui.Console();
2641 groovyConsole.setVariable("Jalview", this);
2642 groovyConsole.run();
2645 * We allow only one console at a time, so that AlignFrame menu option
2646 * 'Calculate | Run Groovy script' is unambiguous.
2647 * Disable 'Groovy Console', and enable 'Run script', when the console is
2648 * opened, and the reverse when it is closed
2650 Window window = (Window) groovyConsole.getFrame();
2651 window.addWindowListener(new WindowAdapter()
2654 public void windowClosed(WindowEvent e)
2657 * rebind CMD-Q from Groovy Console to Jalview Quit
2660 enableExecuteGroovy(false);
2666 * show Groovy console window (after close and reopen)
2668 ((Window) groovyConsole.getFrame()).setVisible(true);
2671 * if we got this far, enable 'Run Groovy' in AlignFrame menus
2672 * and disable opening a second console
2674 enableExecuteGroovy(true);
2678 * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
2679 * binding when opened
2681 protected void addQuitHandler()
2683 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
2684 .put(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
2685 Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
2687 getRootPane().getActionMap().put("Quit", new AbstractAction()
2690 public void actionPerformed(ActionEvent e)
2698 * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
2701 * true if Groovy console is open
2703 public void enableExecuteGroovy(boolean enabled)
2706 * disable opening a second Groovy console
2707 * (or re-enable when the console is closed)
2709 groovyShell.setEnabled(!enabled);
2711 AlignFrame[] alignFrames = getAlignFrames();
2712 if (alignFrames != null)
2714 for (AlignFrame af : alignFrames)
2716 af.setGroovyEnabled(enabled);
2722 * Progress bars managed by the IProgressIndicator method.
2724 private Hashtable<Long, JPanel> progressBars;
2726 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2731 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2734 public void setProgressBar(String message, long id)
2736 if (progressBars == null)
2738 progressBars = new Hashtable<>();
2739 progressBarHandlers = new Hashtable<>();
2742 if (progressBars.get(new Long(id)) != null)
2744 JPanel panel = progressBars.remove(new Long(id));
2745 if (progressBarHandlers.contains(new Long(id)))
2747 progressBarHandlers.remove(new Long(id));
2749 removeProgressPanel(panel);
2753 progressBars.put(new Long(id), addProgressPanel(message));
2760 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2761 * jalview.gui.IProgressIndicatorHandler)
2764 public void registerHandler(final long id,
2765 final IProgressIndicatorHandler handler)
2767 if (progressBarHandlers == null
2768 || !progressBars.containsKey(new Long(id)))
2770 throw new Error(MessageManager.getString(
2771 "error.call_setprogressbar_before_registering_handler"));
2773 progressBarHandlers.put(new Long(id), handler);
2774 final JPanel progressPanel = progressBars.get(new Long(id));
2775 if (handler.canCancel())
2777 JButton cancel = new JButton(
2778 MessageManager.getString("action.cancel"));
2779 final IProgressIndicator us = this;
2780 cancel.addActionListener(new ActionListener()
2784 public void actionPerformed(ActionEvent e)
2786 handler.cancelActivity(id);
2787 us.setProgressBar(MessageManager
2788 .formatMessage("label.cancelled_params", new Object[]
2789 { ((JLabel) progressPanel.getComponent(0)).getText() }),
2793 progressPanel.add(cancel, BorderLayout.EAST);
2799 * @return true if any progress bars are still active
2802 public boolean operationInProgress()
2804 if (progressBars != null && progressBars.size() > 0)
2812 * This will return the first AlignFrame holding the given viewport instance.
2813 * It will break if there are more than one AlignFrames viewing a particular
2817 * @return alignFrame for viewport
2819 public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
2821 if (desktop != null)
2823 AlignmentPanel[] aps = getAlignmentPanels(
2824 viewport.getSequenceSetId());
2825 for (int panel = 0; aps != null && panel < aps.length; panel++)
2827 if (aps[panel] != null && aps[panel].av == viewport)
2829 return aps[panel].alignFrame;
2836 public VamsasApplication getVamsasApplication()
2843 * flag set if jalview GUI is being operated programmatically
2845 private boolean inBatchMode = false;
2848 * check if jalview GUI is being operated programmatically
2850 * @return inBatchMode
2852 public boolean isInBatchMode()
2858 * set flag if jalview GUI is being operated programmatically
2860 * @param inBatchMode
2862 public void setInBatchMode(boolean inBatchMode)
2864 this.inBatchMode = inBatchMode;
2867 public void startServiceDiscovery()
2869 startServiceDiscovery(false);
2872 public void startServiceDiscovery(boolean blocking)
2874 boolean alive = true;
2875 Thread t0 = null, t1 = null, t2 = null;
2876 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2879 // todo: changesupport handlers need to be transferred
2880 if (discoverer == null)
2882 discoverer = new jalview.ws.jws1.Discoverer();
2883 // register PCS handler for desktop.
2884 discoverer.addPropertyChangeListener(changeSupport);
2886 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2887 // until we phase out completely
2888 (t0 = new Thread(discoverer)).start();
2891 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2893 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2894 .startDiscoverer(changeSupport);
2898 // TODO: do rest service discovery
2907 } catch (Exception e)
2910 alive = (t1 != null && t1.isAlive()) || (t2 != null && t2.isAlive())
2911 || (t3 != null && t3.isAlive())
2912 || (t0 != null && t0.isAlive());
2918 * called to check if the service discovery process completed successfully.
2922 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2924 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2926 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2927 .getErrorMessages();
2930 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2932 if (serviceChangedDialog == null)
2934 // only run if we aren't already displaying one of these.
2935 addDialogThread(serviceChangedDialog = new Runnable()
2942 * JalviewDialog jd =new JalviewDialog() {
2944 * @Override protected void cancelPressed() { // TODO
2945 * Auto-generated method stub
2947 * }@Override protected void okPressed() { // TODO
2948 * Auto-generated method stub
2950 * }@Override protected void raiseClosed() { // TODO
2951 * Auto-generated method stub
2953 * } }; jd.initDialogFrame(new
2954 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2955 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2956 * + " or mis-configured HTTP proxy settings.<br/>" +
2957 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2959 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2960 * ), true, true, "Web Service Configuration Problem", 450,
2963 * jd.waitForInput();
2965 JvOptionPane.showConfirmDialog(Desktop.desktop,
2966 new JLabel("<html><table width=\"450\"><tr><td>"
2967 + ermsg + "</td></tr></table>"
2968 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2969 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2970 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2971 + " Tools->Preferences dialog box to change them.</p></html>"),
2972 "Web Service Configuration Problem",
2973 JvOptionPane.DEFAULT_OPTION,
2974 JvOptionPane.ERROR_MESSAGE);
2975 serviceChangedDialog = null;
2984 "Errors reported by JABA discovery service. Check web services preferences.\n"
2991 private Runnable serviceChangedDialog = null;
2994 * start a thread to open a URL in the configured browser. Pops up a warning
2995 * dialog to the user if there is an exception when calling out to the browser
3000 public static void showUrl(final String url)
3002 showUrl(url, Desktop.instance);
3006 * Like showUrl but allows progress handler to be specified
3010 * (null) or object implementing IProgressIndicator
3012 public static void showUrl(final String url,
3013 final IProgressIndicator progress)
3015 new Thread(new Runnable()
3022 if (progress != null)
3024 progress.setProgressBar(MessageManager
3025 .formatMessage("status.opening_params", new Object[]
3026 { url }), this.hashCode());
3028 jalview.util.BrowserLauncher.openURL(url);
3029 } catch (Exception ex)
3031 JvOptionPane.showInternalMessageDialog(Desktop.desktop,
3033 .getString("label.web_browser_not_found_unix"),
3034 MessageManager.getString("label.web_browser_not_found"),
3035 JvOptionPane.WARNING_MESSAGE);
3037 ex.printStackTrace();
3039 if (progress != null)
3041 progress.setProgressBar(null, this.hashCode());
3047 public static WsParamSetManager wsparamManager = null;
3049 public static ParamManager getUserParameterStore()
3051 if (wsparamManager == null)
3053 wsparamManager = new WsParamSetManager();
3055 return wsparamManager;
3059 * static hyperlink handler proxy method for use by Jalview's internal windows
3063 public static void hyperlinkUpdate(HyperlinkEvent e)
3065 if (e.getEventType() == EventType.ACTIVATED)
3070 url = e.getURL().toString();
3071 Desktop.showUrl(url);
3072 } catch (Exception x)
3076 if (Cache.log != null)
3078 Cache.log.error("Couldn't handle string " + url + " as a URL.");
3083 "Couldn't handle string " + url + " as a URL.");
3086 // ignore any exceptions due to dud links.
3093 * single thread that handles display of dialogs to user.
3095 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
3098 * flag indicating if dialogExecutor should try to acquire a permit
3100 private volatile boolean dialogPause = true;
3105 private java.util.concurrent.Semaphore block = new Semaphore(0);
3107 private static groovy.ui.Console groovyConsole;
3110 * add another dialog thread to the queue
3114 public void addDialogThread(final Runnable prompter)
3116 dialogExecutor.submit(new Runnable()
3126 } catch (InterruptedException x)
3131 if (instance == null)
3137 SwingUtilities.invokeAndWait(prompter);
3138 } catch (Exception q)
3140 Cache.log.warn("Unexpected Exception in dialog thread.", q);
3146 public void startDialogQueue()
3148 // set the flag so we don't pause waiting for another permit and semaphore
3149 // the current task to begin
3150 dialogPause = false;
3155 protected void snapShotWindow_actionPerformed(ActionEvent e)
3159 ImageMaker im = new jalview.util.ImageMaker(
3160 this, ImageMaker.TYPE.EPS, "View of Desktop", getWidth(),
3161 getHeight(), of = new File("Jalview_snapshot"
3162 + System.currentTimeMillis() + ".eps"),
3163 "View of desktop", null, 0, false);
3166 paintAll(im.getGraphics());
3168 } catch (Exception q)
3170 Cache.log.error("Couldn't write snapshot to " + of.getAbsolutePath(),
3174 Cache.log.info("Successfully written snapshot to file "
3175 + of.getAbsolutePath());
3179 * Explode the views in the given SplitFrame into separate SplitFrame windows.
3180 * This respects (remembers) any previous 'exploded geometry' i.e. the size
3181 * and location last time the view was expanded (if any). However it does not
3182 * remember the split pane divider location - this is set to match the
3183 * 'exploding' frame.
3187 public void explodeViews(SplitFrame sf)
3189 AlignFrame oldTopFrame = (AlignFrame) sf.getTopFrame();
3190 AlignFrame oldBottomFrame = (AlignFrame) sf.getBottomFrame();
3191 List<? extends AlignmentViewPanel> topPanels = oldTopFrame
3193 List<? extends AlignmentViewPanel> bottomPanels = oldBottomFrame
3195 int viewCount = topPanels.size();
3202 * Processing in reverse order works, forwards order leaves the first panels
3203 * not visible. I don't know why!
3205 for (int i = viewCount - 1; i >= 0; i--)
3208 * Make new top and bottom frames. These take over the respective
3209 * AlignmentPanel objects, including their AlignmentViewports, so the
3210 * cdna/protein relationships between the viewports is carried over to the
3213 * explodedGeometry holds the (x, y) position of the previously exploded
3214 * SplitFrame, and the (width, height) of the AlignFrame component
3216 AlignmentPanel topPanel = (AlignmentPanel) topPanels.get(i);
3217 AlignFrame newTopFrame = new AlignFrame(topPanel);
3218 newTopFrame.setSize(oldTopFrame.getSize());
3219 newTopFrame.setVisible(true);
3220 Rectangle geometry = ((AlignViewport) topPanel.getAlignViewport())
3221 .getExplodedGeometry();
3222 if (geometry != null)
3224 newTopFrame.setSize(geometry.getSize());
3227 AlignmentPanel bottomPanel = (AlignmentPanel) bottomPanels.get(i);
3228 AlignFrame newBottomFrame = new AlignFrame(bottomPanel);
3229 newBottomFrame.setSize(oldBottomFrame.getSize());
3230 newBottomFrame.setVisible(true);
3231 geometry = ((AlignViewport) bottomPanel.getAlignViewport())
3232 .getExplodedGeometry();
3233 if (geometry != null)
3235 newBottomFrame.setSize(geometry.getSize());
3238 topPanel.av.setGatherViewsHere(false);
3239 bottomPanel.av.setGatherViewsHere(false);
3240 JInternalFrame splitFrame = new SplitFrame(newTopFrame,
3242 if (geometry != null)
3244 splitFrame.setLocation(geometry.getLocation());
3246 Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
3250 * Clear references to the panels (now relocated in the new SplitFrames)
3251 * before closing the old SplitFrame.
3254 bottomPanels.clear();
3259 * Gather expanded split frames, sharing the same pairs of sequence set ids,
3260 * back into the given SplitFrame as additional views. Note that the gathered
3261 * frames may themselves have multiple views.
3265 public void gatherViews(GSplitFrame source)
3268 * special handling of explodedGeometry for a view within a SplitFrame: - it
3269 * holds the (x, y) position of the enclosing SplitFrame, and the (width,
3270 * height) of the AlignFrame component
3272 AlignFrame myTopFrame = (AlignFrame) source.getTopFrame();
3273 AlignFrame myBottomFrame = (AlignFrame) source.getBottomFrame();
3274 myTopFrame.viewport.setExplodedGeometry(new Rectangle(source.getX(),
3275 source.getY(), myTopFrame.getWidth(), myTopFrame.getHeight()));
3276 myBottomFrame.viewport
3277 .setExplodedGeometry(new Rectangle(source.getX(), source.getY(),
3278 myBottomFrame.getWidth(), myBottomFrame.getHeight()));
3279 myTopFrame.viewport.setGatherViewsHere(true);
3280 myBottomFrame.viewport.setGatherViewsHere(true);
3281 String topViewId = myTopFrame.viewport.getSequenceSetId();
3282 String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
3284 JInternalFrame[] frames = desktop.getAllFrames();
3285 for (JInternalFrame frame : frames)
3287 if (frame instanceof SplitFrame && frame != source)
3289 SplitFrame sf = (SplitFrame) frame;
3290 AlignFrame topFrame = (AlignFrame) sf.getTopFrame();
3291 AlignFrame bottomFrame = (AlignFrame) sf.getBottomFrame();
3292 boolean gatherThis = false;
3293 for (int a = 0; a < topFrame.alignPanels.size(); a++)
3295 AlignmentPanel topPanel = topFrame.alignPanels.get(a);
3296 AlignmentPanel bottomPanel = bottomFrame.alignPanels.get(a);
3297 if (topViewId.equals(topPanel.av.getSequenceSetId())
3298 && bottomViewId.equals(bottomPanel.av.getSequenceSetId()))
3301 topPanel.av.setGatherViewsHere(false);
3302 bottomPanel.av.setGatherViewsHere(false);
3303 topPanel.av.setExplodedGeometry(
3304 new Rectangle(sf.getLocation(), topFrame.getSize()));
3305 bottomPanel.av.setExplodedGeometry(
3306 new Rectangle(sf.getLocation(), bottomFrame.getSize()));
3307 myTopFrame.addAlignmentPanel(topPanel, false);
3308 myBottomFrame.addAlignmentPanel(bottomPanel, false);
3314 topFrame.getAlignPanels().clear();
3315 bottomFrame.getAlignPanels().clear();
3322 * The dust settles...give focus to the tab we did this from.
3324 myTopFrame.setDisplayedView(myTopFrame.alignPanel);
3327 public static groovy.ui.Console getGroovyConsole()
3329 return groovyConsole;
3332 public static void transferFromDropTarget(List<String> files,
3333 List<DataSourceType> protocols, DropTargetDropEvent evt,
3334 Transferable t) throws Exception
3337 DataFlavor uriListFlavor = new DataFlavor(
3338 "text/uri-list;class=java.lang.String");
3339 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
3341 // Works on Windows and MacOSX
3342 Cache.log.debug("Drop handled as javaFileListFlavor");
3343 for (Object file : (List) t
3344 .getTransferData(DataFlavor.javaFileListFlavor))
3346 files.add(((File) file).toString());
3347 protocols.add(DataSourceType.FILE);
3352 // Unix like behaviour
3353 boolean added = false;
3355 if (t.isDataFlavorSupported(uriListFlavor))
3357 Cache.log.debug("Drop handled as uriListFlavor");
3358 // This is used by Unix drag system
3359 data = (String) t.getTransferData(uriListFlavor);
3363 // fallback to text: workaround - on OSX where there's a JVM bug
3364 Cache.log.debug("standard URIListFlavor failed. Trying text");
3365 // try text fallback
3366 data = (String) t.getTransferData(
3367 new DataFlavor("text/plain;class=java.lang.String"));
3368 if (Cache.log.isDebugEnabled())
3370 Cache.log.debug("fallback returned " + data);
3373 while (protocols.size() < files.size())
3375 Cache.log.debug("Adding missing FILE protocol for "
3376 + files.get(protocols.size()));
3377 protocols.add(DataSourceType.FILE);
3379 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
3380 data, "\r\n"); st.hasMoreTokens();)
3383 String s = st.nextToken();
3384 if (s.startsWith("#"))
3386 // the line is a comment (as per the RFC 2483)
3389 java.net.URI uri = new java.net.URI(s);
3390 if (uri.getScheme().toLowerCase().startsWith("http"))
3392 protocols.add(DataSourceType.URL);
3393 files.add(uri.toString());
3397 // otherwise preserve old behaviour: catch all for file objects
3398 java.io.File file = new java.io.File(uri);
3399 protocols.add(DataSourceType.FILE);
3400 files.add(file.toString());
3403 if (Cache.log.isDebugEnabled())
3405 if (data == null || !added)
3408 "Couldn't resolve drop data. Here are the supported flavors:");
3409 for (DataFlavor fl : t.getTransferDataFlavors())
3412 "Supported transfer dataflavor: " + fl.toString());
3413 Object df = t.getTransferData(fl);
3416 Cache.log.debug("Retrieves: " + df);
3420 Cache.log.debug("Retrieved nothing");
3429 * Sets the Preferences property for experimental features to True or False
3430 * depending on the state of the controlling menu item
3433 protected void showExperimental_actionPerformed(boolean selected)
3435 Cache.setProperty(EXPERIMENTAL_FEATURES, Boolean.toString(selected));