2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.bin.Cache;
24 import jalview.io.FileLoader;
25 import jalview.io.FormatAdapter;
26 import jalview.io.IdentifyFile;
27 import jalview.io.JalviewFileChooser;
28 import jalview.io.JalviewFileView;
29 import jalview.jbgui.GStructureViewer;
30 import jalview.structure.StructureSelectionManager;
31 import jalview.util.ImageMaker;
32 import jalview.util.MessageManager;
33 import jalview.ws.params.ParamManager;
35 import java.awt.BorderLayout;
36 import java.awt.Color;
37 import java.awt.Dimension;
38 import java.awt.FontMetrics;
39 import java.awt.Graphics;
40 import java.awt.GridLayout;
41 import java.awt.Point;
42 import java.awt.Rectangle;
43 import java.awt.Toolkit;
44 import java.awt.datatransfer.Clipboard;
45 import java.awt.datatransfer.ClipboardOwner;
46 import java.awt.datatransfer.DataFlavor;
47 import java.awt.datatransfer.Transferable;
48 import java.awt.dnd.DnDConstants;
49 import java.awt.dnd.DropTargetDragEvent;
50 import java.awt.dnd.DropTargetDropEvent;
51 import java.awt.dnd.DropTargetEvent;
52 import java.awt.dnd.DropTargetListener;
53 import java.awt.event.ActionEvent;
54 import java.awt.event.ActionListener;
55 import java.awt.event.FocusEvent;
56 import java.awt.event.FocusListener;
57 import java.awt.event.MouseAdapter;
58 import java.awt.event.MouseEvent;
59 import java.awt.event.MouseListener;
60 import java.awt.event.WindowAdapter;
61 import java.awt.event.WindowEvent;
62 import java.beans.PropertyChangeEvent;
63 import java.beans.PropertyChangeListener;
64 import java.beans.PropertyVetoException;
65 import java.io.BufferedInputStream;
67 import java.io.FileOutputStream;
68 import java.lang.reflect.Constructor;
70 import java.util.ArrayList;
71 import java.util.Hashtable;
72 import java.util.StringTokenizer;
73 import java.util.Vector;
74 import java.util.concurrent.ExecutorService;
75 import java.util.concurrent.Executors;
76 import java.util.concurrent.Semaphore;
78 import javax.swing.DefaultDesktopManager;
79 import javax.swing.DesktopManager;
80 import javax.swing.JButton;
81 import javax.swing.JComboBox;
82 import javax.swing.JComponent;
83 import javax.swing.JDesktopPane;
84 import javax.swing.JFrame;
85 import javax.swing.JInternalFrame;
86 import javax.swing.JLabel;
87 import javax.swing.JMenuItem;
88 import javax.swing.JOptionPane;
89 import javax.swing.JPanel;
90 import javax.swing.JPopupMenu;
91 import javax.swing.JProgressBar;
92 import javax.swing.SwingUtilities;
93 import javax.swing.event.HyperlinkEvent;
94 import javax.swing.event.HyperlinkEvent.EventType;
95 import javax.swing.event.MenuEvent;
96 import javax.swing.event.MenuListener;
103 * @version $Revision: 1.155 $
105 public class Desktop extends jalview.jbgui.GDesktop implements
106 DropTargetListener, ClipboardOwner, IProgressIndicator,
107 jalview.api.StructureSelectionManagerProvider
110 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
113 * news reader - null if it was never started.
115 private BlogReader jvnews = null;
117 private File projectFile;
121 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
123 public void addJalviewPropertyChangeListener(
124 PropertyChangeListener listener)
126 changeSupport.addJalviewPropertyChangeListener(listener);
130 * @param propertyName
132 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
133 * java.beans.PropertyChangeListener)
135 public void addJalviewPropertyChangeListener(String propertyName,
136 PropertyChangeListener listener)
138 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
142 * @param propertyName
144 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
145 * java.beans.PropertyChangeListener)
147 public void removeJalviewPropertyChangeListener(String propertyName,
148 PropertyChangeListener listener)
150 changeSupport.removeJalviewPropertyChangeListener(propertyName,
154 /** Singleton Desktop instance */
155 public static Desktop instance;
157 public static MyDesktopPane desktop;
159 static int openFrameCount = 0;
161 static final int xOffset = 30;
163 static final int yOffset = 30;
165 public static jalview.ws.jws1.Discoverer discoverer;
167 public static Object[] jalviewClipboard;
169 public static boolean internalCopy = false;
171 static int fileLoadingCount = 0;
173 class MyDesktopManager implements DesktopManager
176 private DesktopManager delegate;
178 public MyDesktopManager(DesktopManager delegate)
180 this.delegate = delegate;
183 public void activateFrame(JInternalFrame f)
187 delegate.activateFrame(f);
188 } catch (NullPointerException npe)
190 Point p = getMousePosition();
191 instance.showPasteMenu(p.x, p.y);
195 public void beginDraggingFrame(JComponent f)
197 delegate.beginDraggingFrame(f);
200 public void beginResizingFrame(JComponent f, int direction)
202 delegate.beginResizingFrame(f, direction);
205 public void closeFrame(JInternalFrame f)
207 delegate.closeFrame(f);
210 public void deactivateFrame(JInternalFrame f)
212 delegate.deactivateFrame(f);
215 public void deiconifyFrame(JInternalFrame f)
217 delegate.deiconifyFrame(f);
220 public void dragFrame(JComponent f, int newX, int newY)
226 delegate.dragFrame(f, newX, newY);
229 public void endDraggingFrame(JComponent f)
231 delegate.endDraggingFrame(f);
234 public void endResizingFrame(JComponent f)
236 delegate.endResizingFrame(f);
239 public void iconifyFrame(JInternalFrame f)
241 delegate.iconifyFrame(f);
244 public void maximizeFrame(JInternalFrame f)
246 delegate.maximizeFrame(f);
249 public void minimizeFrame(JInternalFrame f)
251 delegate.minimizeFrame(f);
254 public void openFrame(JInternalFrame f)
256 delegate.openFrame(f);
259 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
262 Rectangle b = desktop.getBounds();
267 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
270 public void setBoundsForFrame(JComponent f, int newX, int newY,
271 int newWidth, int newHeight)
273 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
276 // All other methods, simply delegate
281 * Creates a new Desktop object.
286 * A note to implementors. It is ESSENTIAL that any activities that might
287 * block are spawned off as threads rather than waited for during this
291 doVamsasClientCheck();
293 doConfigureStructurePrefs();
294 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
295 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
296 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
298 boolean showjconsole = jalview.bin.Cache.getDefault(
299 "SHOW_JAVA_CONSOLE", false);
300 desktop = new MyDesktopPane(selmemusage);
301 showMemusage.setSelected(selmemusage);
302 desktop.setBackground(Color.white);
303 getContentPane().setLayout(new BorderLayout());
304 // alternate config - have scrollbars - see notes in JAL-153
305 // JScrollPane sp = new JScrollPane();
306 // sp.getViewport().setView(desktop);
307 // getContentPane().add(sp, BorderLayout.CENTER);
308 getContentPane().add(desktop, BorderLayout.CENTER);
309 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
311 // This line prevents Windows Look&Feel resizing all new windows to maximum
312 // if previous window was maximised
313 desktop.setDesktopManager(new MyDesktopManager(
314 new DefaultDesktopManager()));
316 Rectangle dims = getLastKnownDimensions("");
323 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
324 setBounds((screenSize.width - 900) / 2,
325 (screenSize.height - 650) / 2, 900, 650);
327 jconsole = new Console(this, showjconsole);
328 // add essential build information
329 jconsole.setHeader("Jalview Version: "
330 + jalview.bin.Cache.getProperty("VERSION") + "\n"
331 + "Jalview Installation: "
332 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
335 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
336 + "Java version: " + System.getProperty("java.version") + "\n"
337 + System.getProperty("os.arch") + " "
338 + System.getProperty("os.name") + " "
339 + System.getProperty("os.version"));
341 showConsole(showjconsole);
343 showNews.setVisible(false);
345 this.addWindowListener(new WindowAdapter()
347 public void windowClosing(WindowEvent evt)
354 this.addMouseListener(ma = new MouseAdapter()
356 public void mousePressed(MouseEvent evt)
358 if (SwingUtilities.isRightMouseButton(evt))
360 showPasteMenu(evt.getX(), evt.getY());
364 desktop.addMouseListener(ma);
366 this.addFocusListener(new FocusListener()
370 public void focusLost(FocusEvent e)
372 // TODO Auto-generated method stub
377 public void focusGained(FocusEvent e)
379 Cache.log.debug("Relaying windows after focus gain");
380 // make sure that we sort windows properly after we gain focus
381 instance.relayerWindows();
384 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
385 // Spawn a thread that shows the splashscreen
386 SwingUtilities.invokeLater(new Runnable()
395 // Thread off a new instance of the file chooser - this reduces the time it
396 // takes to open it later on.
397 new Thread(new Runnable()
401 Cache.log.debug("Filechooser init thread started.");
402 JalviewFileChooser chooser = new JalviewFileChooser(
403 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
404 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
405 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
406 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
407 Cache.log.debug("Filechooser init thread finished.");
410 // Add the service change listener
411 changeSupport.addJalviewPropertyChangeListener("services",
412 new PropertyChangeListener()
416 public void propertyChange(PropertyChangeEvent evt)
418 Cache.log.debug("Firing service changed event for "
419 + evt.getNewValue());
420 JalviewServicesChanged(evt);
426 public void doConfigureStructurePrefs()
428 // configure services
429 StructureSelectionManager ssm = StructureSelectionManager
430 .getStructureSelectionManager(this);
431 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
433 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
434 Preferences.ADD_TEMPFACT_ANN, true));
435 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(Preferences.STRUCT_FROM_PDB, true));
436 ssm.setSecStructServices(jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW,
441 ssm.setAddTempFacAnnot(false);
442 ssm.setProcessSecondaryStructure(false);
443 ssm.setSecStructServices(false);
447 public void checkForNews()
449 final Desktop me = this;
450 // Thread off the news reader, in case there are connection problems.
451 addDialogThread(new Runnable()
456 Cache.log.debug("Starting news thread.");
458 jvnews = new BlogReader(me);
459 showNews.setVisible(true);
460 Cache.log.debug("Completed news thread.");
465 protected void showNews_actionPerformed(ActionEvent e)
467 showNews(showNews.isSelected());
470 void showNews(boolean visible)
473 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
474 showNews.setSelected(visible);
475 if (visible && !jvnews.isVisible())
477 new Thread(new Runnable()
482 long instance = System.currentTimeMillis();
483 Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_news"), instance);
484 jvnews.refreshNews();
485 Desktop.instance.setProgressBar(null, instance);
494 * recover the last known dimensions for a jalview window
497 * - empty string is desktop, all other windows have unique prefix
498 * @return null or last known dimensions scaled to current geometry (if last
499 * window geom was known)
501 Rectangle getLastKnownDimensions(String windowName)
503 // TODO: lock aspect ratio for scaling desktop Bug #0058199
504 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
505 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
506 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
507 String width = jalview.bin.Cache.getProperty(windowName
509 String height = jalview.bin.Cache.getProperty(windowName
511 if ((x != null) && (y != null) && (width != null) && (height != null))
513 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
514 .parseInt(width), ih = Integer.parseInt(height);
515 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
517 // attempt #1 - try to cope with change in screen geometry - this
518 // version doesn't preserve original jv aspect ratio.
519 // take ratio of current screen size vs original screen size.
520 double sw = ((1f * screenSize.width) / (1f * Integer
521 .parseInt(jalview.bin.Cache
522 .getProperty("SCREENGEOMETRY_WIDTH"))));
523 double sh = ((1f * screenSize.height) / (1f * Integer
524 .parseInt(jalview.bin.Cache
525 .getProperty("SCREENGEOMETRY_HEIGHT"))));
526 // rescale the bounds depending upon the current screen geometry.
527 ix = (int) (ix * sw);
528 iw = (int) (iw * sw);
529 iy = (int) (iy * sh);
530 ih = (int) (ih * sh);
531 while (ix >= screenSize.width)
533 jalview.bin.Cache.log
534 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
535 ix -= screenSize.width;
537 while (iy >= screenSize.height)
539 jalview.bin.Cache.log
540 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
541 iy -= screenSize.height;
543 jalview.bin.Cache.log.debug("Got last known dimensions for "
544 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
547 // return dimensions for new instance
548 return new Rectangle(ix, iy, iw, ih);
553 private void doVamsasClientCheck()
555 if (jalview.bin.Cache.vamsasJarsPresent())
557 setupVamsasDisconnectedGui();
558 VamsasMenu.setVisible(true);
559 final Desktop us = this;
560 VamsasMenu.addMenuListener(new MenuListener()
562 // this listener remembers when the menu was first selected, and
563 // doesn't rebuild the session list until it has been cleared and
565 boolean refresh = true;
567 public void menuCanceled(MenuEvent e)
572 public void menuDeselected(MenuEvent e)
577 public void menuSelected(MenuEvent e)
581 us.buildVamsasStMenu();
586 vamsasStart.setVisible(true);
590 void showPasteMenu(int x, int y)
592 JPopupMenu popup = new JPopupMenu();
593 JMenuItem item = new JMenuItem(
594 MessageManager.getString("label.paste_new_window"));
595 item.addActionListener(new ActionListener()
597 public void actionPerformed(ActionEvent evt)
604 popup.show(this, x, y);
611 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
612 Transferable contents = c.getContents(this);
614 if (contents != null)
616 String file = (String) contents
617 .getTransferData(DataFlavor.stringFlavor);
619 String format = new IdentifyFile().Identify(file,
620 FormatAdapter.PASTE);
622 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
625 } catch (Exception ex)
628 .println("Unable to paste alignment from system clipboard:\n"
634 * Adds and opens the given frame to the desktop
645 public static synchronized void addInternalFrame(
646 final JInternalFrame frame, String title, int w, int h)
648 addInternalFrame(frame, title, true, w, h, true);
653 * Add an internal frame to the Jalview desktop
660 * When true, display frame immediately, otherwise, caller must call
661 * setVisible themselves.
667 public static synchronized void addInternalFrame(
668 final JInternalFrame frame, String title, boolean makeVisible,
671 addInternalFrame(frame, title, makeVisible, w, h, true);
675 * Add an internal frame to the Jalview desktop and make it visible
688 public static synchronized void addInternalFrame(
689 final JInternalFrame frame, String title, int w, int h,
692 addInternalFrame(frame, title, true, w, h, resizable);
696 * Add an internal frame to the Jalview desktop
703 * When true, display frame immediately, otherwise, caller must call
704 * setVisible themselves.
712 public static synchronized void addInternalFrame(
713 final JInternalFrame frame, String title, boolean makeVisible,
714 int w, int h, boolean resizable)
717 // TODO: allow callers to determine X and Y position of frame (eg. via
719 // TODO: consider fixing method to update entries in the window submenu with
720 // the current window title
722 frame.setTitle(title);
723 if (frame.getWidth() < 1 || frame.getHeight() < 1)
727 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
728 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
729 // IF JALVIEW IS RUNNING HEADLESS
730 // ///////////////////////////////////////////////
732 || (System.getProperty("java.awt.headless") != null && System
733 .getProperty("java.awt.headless").equals("true")))
740 frame.setVisible(makeVisible);
741 frame.setClosable(true);
742 frame.setResizable(resizable);
743 frame.setMaximizable(resizable);
744 frame.setIconifiable(resizable);
745 frame.setFrameIcon(null);
747 if (frame.getX() < 1 && frame.getY() < 1)
749 frame.setLocation(xOffset * openFrameCount, yOffset
750 * ((openFrameCount - 1) % 10) + yOffset);
753 final JMenuItem menuItem = new JMenuItem(title);
754 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
756 public void internalFrameActivated(
757 javax.swing.event.InternalFrameEvent evt)
759 JInternalFrame itf = desktop.getSelectedFrame();
767 public void internalFrameClosed(
768 javax.swing.event.InternalFrameEvent evt)
770 PaintRefresher.RemoveComponent(frame);
772 windowMenu.remove(menuItem);
773 JInternalFrame itf = desktop.getSelectedFrame();
782 menuItem.addActionListener(new ActionListener()
784 public void actionPerformed(ActionEvent e)
788 frame.setSelected(true);
789 frame.setIcon(false);
790 } catch (java.beans.PropertyVetoException ex)
796 menuItem.addMouseListener(new MouseListener()
800 public void mouseReleased(MouseEvent e)
805 public void mousePressed(MouseEvent e)
810 public void mouseExited(MouseEvent e)
814 frame.setSelected(false);
815 } catch (PropertyVetoException e1)
821 public void mouseEntered(MouseEvent e)
825 frame.setSelected(true);
826 } catch (PropertyVetoException e1)
832 public void mouseClicked(MouseEvent e)
838 windowMenu.add(menuItem);
844 frame.setSelected(true);
845 frame.requestFocus();
846 } catch (java.beans.PropertyVetoException ve)
848 } catch (java.lang.ClassCastException cex)
851 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
856 public void lostOwnership(Clipboard clipboard, Transferable contents)
860 Desktop.jalviewClipboard = null;
863 internalCopy = false;
866 public void dragEnter(DropTargetDragEvent evt)
870 public void dragExit(DropTargetEvent evt)
874 public void dragOver(DropTargetDragEvent evt)
878 public void dropActionChanged(DropTargetDragEvent evt)
888 public void drop(DropTargetDropEvent evt)
890 boolean success = true;
891 Transferable t = evt.getTransferable();
892 java.util.List files = null;
893 java.util.List protocols = null;
897 DataFlavor uriListFlavor = new DataFlavor(
898 "text/uri-list;class=java.lang.String");
899 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
901 // Works on Windows and MacOSX
902 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
903 files = (java.util.List) t
904 .getTransferData(DataFlavor.javaFileListFlavor);
906 else if (t.isDataFlavorSupported(uriListFlavor))
908 // This is used by Unix drag system
909 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
910 String data = (String) t.getTransferData(uriListFlavor);
911 files = new java.util.ArrayList(1);
912 protocols = new java.util.ArrayList(1);
913 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
914 data, "\r\n"); st.hasMoreTokens();)
916 String s = st.nextToken();
917 if (s.startsWith("#"))
919 // the line is a comment (as per the RFC 2483)
922 java.net.URI uri = new java.net.URI(s);
923 if (uri.getScheme().toLowerCase().startsWith("http"))
925 protocols.add(FormatAdapter.URL);
926 files.add(uri.toString());
930 // otherwise preserve old behaviour: catch all for file objects
931 java.io.File file = new java.io.File(uri);
932 protocols.add(FormatAdapter.FILE);
933 files.add(file.toString());
937 } catch (Exception e)
946 for (int i = 0; i < files.size(); i++)
948 String file = files.get(i).toString();
949 String protocol = (protocols == null) ? FormatAdapter.FILE
950 : (String) protocols.get(i);
951 String format = null;
953 if (file.endsWith(".jar"))
960 format = new IdentifyFile().Identify(file, protocol);
963 new FileLoader().LoadFile(file, protocol, format);
966 } catch (Exception ex)
971 evt.dropComplete(success); // need this to ensure input focus is properly
972 // transfered to any new windows created
981 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
983 JalviewFileChooser chooser = new JalviewFileChooser(
984 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
985 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
986 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
987 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
989 chooser.setFileView(new JalviewFileView());
990 chooser.setDialogTitle(MessageManager
991 .getString("label.open_local_file"));
992 chooser.setToolTipText(MessageManager.getString("action.open"));
994 int value = chooser.showOpenDialog(this);
996 if (value == JalviewFileChooser.APPROVE_OPTION)
998 String choice = chooser.getSelectedFile().getPath();
999 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1000 .getSelectedFile().getParent());
1002 String format = null;
1003 if (chooser.getSelectedFormat() != null
1004 && chooser.getSelectedFormat().equals("Jalview"))
1010 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1013 if (viewport != null)
1015 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1020 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1031 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1033 // This construct allows us to have a wider textfield
1035 JLabel label = new JLabel(
1036 MessageManager.getString("label.input_file_url"));
1037 final JComboBox history = new JComboBox();
1039 JPanel panel = new JPanel(new GridLayout(2, 1));
1042 history.setPreferredSize(new Dimension(400, 20));
1043 history.setEditable(true);
1044 history.addItem("http://www.");
1046 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1050 if (historyItems != null)
1052 st = new StringTokenizer(historyItems, "\t");
1054 while (st.hasMoreTokens())
1056 history.addItem(st.nextElement());
1060 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1061 MessageManager.getString("label.input_alignment_from_url"),
1062 JOptionPane.OK_CANCEL_OPTION);
1064 if (reply != JOptionPane.OK_OPTION)
1069 String url = history.getSelectedItem().toString();
1071 if (url.toLowerCase().endsWith(".jar"))
1073 if (viewport != null)
1075 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1080 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1085 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1087 if (format.equals("URL NOT FOUND"))
1089 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1090 MessageManager.formatMessage("label.couldnt_locate", new String[]{url}), MessageManager.getString("label.url_not_found"),
1091 JOptionPane.WARNING_MESSAGE);
1096 if (viewport != null)
1098 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1102 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1113 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1115 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1116 cap.setForInput(viewport);
1117 Desktop.addInternalFrame(cap,
1118 MessageManager.getString("label.cut_paste_alignmen_file"),
1127 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1129 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1130 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1132 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1133 getBounds().y, getWidth(), getHeight()));
1135 if (jconsole != null)
1137 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1138 jconsole.stopConsole();
1142 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1145 if (dialogExecutor != null)
1147 dialogExecutor.shutdownNow();
1153 private void storeLastKnownDimensions(String string, Rectangle jc)
1155 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1156 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1157 + " height:" + jc.height);
1159 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1160 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1161 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1162 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1171 public void aboutMenuItem_actionPerformed(ActionEvent e)
1173 // StringBuffer message = getAboutMessage(false);
1174 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1176 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1177 new Thread(new Runnable()
1181 new SplashScreen(true);
1186 public StringBuffer getAboutMessage(boolean shortv)
1188 StringBuffer message = new StringBuffer();
1189 message.append("<html>");
1192 message.append("<h1><strong>Version: "
1193 + jalview.bin.Cache.getProperty("VERSION")
1194 + "</strong></h1>");
1195 message.append("<strong>Last Updated: <em>"
1196 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1197 + "</em></strong>");
1203 message.append("<strong>Version "
1204 + jalview.bin.Cache.getProperty("VERSION")
1205 + "; last updated: "
1206 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1209 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1212 message.append("<br>...Checking latest version...</br>");
1214 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1215 .equals(jalview.bin.Cache.getProperty("VERSION")))
1217 boolean red = false;
1218 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1219 .indexOf("automated build") == -1)
1222 // Displayed when code version and jnlp version do not match and code
1223 // version is not a development build
1224 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1227 message.append("<br>!! Version "
1228 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1230 + " is available for download from "
1231 + jalview.bin.Cache.getDefault("www.jalview.org",
1232 "http://www.jalview.org") + " !!");
1235 message.append("</div>");
1238 message.append("<br>Authors: "
1242 "The Jalview Authors (See AUTHORS file for current list)")
1243 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1244 + "<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"
1245 + "<br><br>If you use Jalview, please cite:"
1246 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1247 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1248 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1259 public void documentationMenuItem_actionPerformed(ActionEvent e)
1263 Help.showHelpWindow();
1264 } catch (Exception ex)
1269 public void closeAll_actionPerformed(ActionEvent e)
1271 JInternalFrame[] frames = desktop.getAllFrames();
1272 for (int i = 0; i < frames.length; i++)
1276 frames[i].setClosed(true);
1277 } catch (java.beans.PropertyVetoException ex)
1281 System.out.println("ALL CLOSED");
1282 if (v_client != null)
1284 // TODO clear binding to vamsas document objects on close_all
1289 public void raiseRelated_actionPerformed(ActionEvent e)
1291 reorderAssociatedWindows(false, false);
1294 public void minimizeAssociated_actionPerformed(ActionEvent e)
1296 reorderAssociatedWindows(true, false);
1299 void closeAssociatedWindows()
1301 reorderAssociatedWindows(false, true);
1307 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1310 protected void garbageCollect_actionPerformed(ActionEvent e)
1312 // We simply collect the garbage
1313 jalview.bin.Cache.log.debug("Collecting garbage...");
1315 jalview.bin.Cache.log.debug("Finished garbage collection.");
1322 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1325 protected void showMemusage_actionPerformed(ActionEvent e)
1327 desktop.showMemoryUsage(showMemusage.isSelected());
1334 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1337 protected void showConsole_actionPerformed(ActionEvent e)
1339 showConsole(showConsole.isSelected());
1342 Console jconsole = null;
1345 * control whether the java console is visible or not
1349 void showConsole(boolean selected)
1351 showConsole.setSelected(selected);
1352 // TODO: decide if we should update properties file
1353 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1355 jconsole.setVisible(selected);
1358 void reorderAssociatedWindows(boolean minimize, boolean close)
1360 JInternalFrame[] frames = desktop.getAllFrames();
1361 if (frames == null || frames.length < 1)
1366 AlignViewport source = null, target = null;
1367 if (frames[0] instanceof AlignFrame)
1369 source = ((AlignFrame) frames[0]).getCurrentView();
1371 else if (frames[0] instanceof TreePanel)
1373 source = ((TreePanel) frames[0]).getViewPort();
1375 else if (frames[0] instanceof PCAPanel)
1377 source = ((PCAPanel) frames[0]).av;
1379 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1381 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1386 for (int i = 0; i < frames.length; i++)
1389 if (frames[i] == null)
1393 if (frames[i] instanceof AlignFrame)
1395 target = ((AlignFrame) frames[i]).getCurrentView();
1397 else if (frames[i] instanceof TreePanel)
1399 target = ((TreePanel) frames[i]).getViewPort();
1401 else if (frames[i] instanceof PCAPanel)
1403 target = ((PCAPanel) frames[i]).av;
1405 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1407 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1410 if (source == target)
1416 frames[i].setClosed(true);
1420 frames[i].setIcon(minimize);
1423 frames[i].toFront();
1427 } catch (java.beans.PropertyVetoException ex)
1441 protected void preferences_actionPerformed(ActionEvent e)
1452 public void saveState_actionPerformed(ActionEvent e)
1454 JalviewFileChooser chooser = new JalviewFileChooser(
1455 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1456 { "jvp" }, new String[]
1457 { "Jalview Project" }, "Jalview Project");
1459 chooser.setFileView(new JalviewFileView());
1460 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1462 int value = chooser.showSaveDialog(this);
1464 if (value == JalviewFileChooser.APPROVE_OPTION)
1466 final Desktop me = this;
1467 final java.io.File choice = chooser.getSelectedFile();
1468 setProjectFile(choice);
1470 new Thread(new Runnable()
1475 setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new String[]{choice.getName()}),
1477 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1478 choice.getParent());
1479 // TODO catch and handle errors for savestate
1480 // TODO prevent user from messing with the Desktop whilst we're saving
1483 new Jalview2XML().saveState(choice);
1484 } catch (OutOfMemoryError oom)
1486 new OOMWarning("Whilst saving current state to "
1487 + choice.getName(), oom);
1488 } catch (Exception ex)
1491 "Problems whilst trying to save to " + choice.getName(),
1493 JOptionPane.showMessageDialog(
1495 MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new String[]{ choice.getName()}),
1496 MessageManager.getString("label.couldnt_save_project"),
1497 JOptionPane.WARNING_MESSAGE);
1499 setProgressBar(null, choice.hashCode());
1505 private void setProjectFile(File choice)
1507 this.projectFile = choice;
1510 public File getProjectFile()
1512 return this.projectFile;
1521 public void loadState_actionPerformed(ActionEvent e)
1523 JalviewFileChooser chooser = new JalviewFileChooser(
1524 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1525 { "jvp", "jar" }, new String[]
1526 { "Jalview Project", "Jalview Project (old)" },
1528 chooser.setFileView(new JalviewFileView());
1529 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1531 int value = chooser.showOpenDialog(this);
1533 if (value == JalviewFileChooser.APPROVE_OPTION)
1535 final File selectedFile = chooser.getSelectedFile();
1536 setProjectFile(selectedFile);
1537 final String choice = selectedFile.getAbsolutePath();
1538 jalview.bin.Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent());
1539 new Thread(new Runnable()
1543 setProgressBar(MessageManager.formatMessage("label.loading_jalview_project", new String[]{choice}),
1547 new Jalview2XML().loadJalviewAlign(choice);
1548 } catch (OutOfMemoryError oom)
1550 new OOMWarning("Whilst loading project from " + choice, oom);
1551 } catch (Exception ex)
1553 Cache.log.error("Problems whilst loading project from "
1555 JOptionPane.showMessageDialog(Desktop.desktop,
1556 MessageManager.formatMessage("label.error_whilst_loading_project_from", new String[]{choice}),
1557 MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE);
1559 setProgressBar(null, choice.hashCode());
1565 public void inputSequence_actionPerformed(ActionEvent e)
1567 new SequenceFetcher(this);
1570 JPanel progressPanel;
1572 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1574 public void startLoading(final String fileName)
1576 if (fileLoadingCount == 0)
1578 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage("label.loading_file", new String[]{fileName})));
1583 private JPanel addProgressPanel(String string)
1585 if (progressPanel == null)
1587 progressPanel = new JPanel(new GridLayout(1, 1));
1588 totalProgressCount = 0;
1589 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1591 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1592 JProgressBar progressBar = new JProgressBar();
1593 progressBar.setIndeterminate(true);
1595 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1597 thisprogress.add(progressBar, BorderLayout.CENTER);
1598 progressPanel.add(thisprogress);
1599 ((GridLayout) progressPanel.getLayout())
1600 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1601 ++totalProgressCount;
1602 instance.validate();
1603 return thisprogress;
1606 int totalProgressCount = 0;
1608 private void removeProgressPanel(JPanel progbar)
1610 if (progressPanel != null)
1612 synchronized (progressPanel)
1614 progressPanel.remove(progbar);
1615 GridLayout gl = (GridLayout) progressPanel.getLayout();
1616 gl.setRows(gl.getRows() - 1);
1617 if (--totalProgressCount < 1)
1619 this.getContentPane().remove(progressPanel);
1620 progressPanel = null;
1627 public void stopLoading()
1630 if (fileLoadingCount < 1)
1632 while (fileLoadingPanels.size() > 0)
1634 removeProgressPanel(fileLoadingPanels.remove(0));
1636 fileLoadingPanels.clear();
1637 fileLoadingCount = 0;
1642 public static int getViewCount(String alignmentId)
1644 AlignViewport[] aps = getViewports(alignmentId);
1645 return (aps == null) ? 0 : aps.length;
1650 * @param alignmentId
1651 * @return all AlignmentPanels concerning the alignmentId sequence set
1653 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1656 if (Desktop.desktop == null)
1658 // no frames created and in headless mode
1659 // TODO: verify that frames are recoverable when in headless mode
1662 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1663 ArrayList aps = new ArrayList();
1664 for (int t = 0; t < frames.length; t++)
1666 if (frames[t] instanceof AlignFrame)
1668 AlignFrame af = (AlignFrame) frames[t];
1669 for (int a = 0; a < af.alignPanels.size(); a++)
1671 if (alignmentId.equals(((AlignmentPanel) af.alignPanels
1672 .elementAt(a)).av.getSequenceSetId()))
1674 aps.add(af.alignPanels.elementAt(a));
1679 if (aps.size() == 0)
1683 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1684 for (int t = 0; t < vap.length; t++)
1686 vap[t] = (AlignmentPanel) aps.get(t);
1692 * get all the viewports on an alignment.
1694 * @param sequenceSetId
1695 * unique alignment id
1696 * @return all viewports on the alignment bound to sequenceSetId
1698 public static AlignViewport[] getViewports(String sequenceSetId)
1700 Vector viewp = new Vector();
1701 if (desktop != null)
1703 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1705 for (int t = 0; t < frames.length; t++)
1707 if (frames[t] instanceof AlignFrame)
1709 AlignFrame afr = ((AlignFrame) frames[t]);
1710 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1712 if (afr.alignPanels != null)
1714 for (int a = 0; a < afr.alignPanels.size(); a++)
1716 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1717 .elementAt(a)).av.getSequenceSetId()))
1719 viewp.addElement(((AlignmentPanel) afr.alignPanels
1726 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1731 if (viewp.size() > 0)
1733 AlignViewport[] vp = new AlignViewport[viewp.size()];
1741 public void explodeViews(AlignFrame af)
1743 int size = af.alignPanels.size();
1749 for (int i = 0; i < size; i++)
1751 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1752 AlignFrame newaf = new AlignFrame(ap);
1753 if (ap.av.explodedPosition != null
1754 && !ap.av.explodedPosition.equals(af.getBounds()))
1756 newaf.setBounds(ap.av.explodedPosition);
1759 ap.av.gatherViewsHere = false;
1761 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1762 AlignFrame.DEFAULT_HEIGHT);
1765 af.alignPanels.clear();
1766 af.closeMenuItem_actionPerformed(true);
1770 public void gatherViews(AlignFrame source)
1772 source.viewport.gatherViewsHere = true;
1773 source.viewport.explodedPosition = source.getBounds();
1774 JInternalFrame[] frames = desktop.getAllFrames();
1775 String viewId = source.viewport.getSequenceSetId();
1777 for (int t = 0; t < frames.length; t++)
1779 if (frames[t] instanceof AlignFrame && frames[t] != source)
1781 AlignFrame af = (AlignFrame) frames[t];
1782 boolean gatherThis = false;
1783 for (int a = 0; a < af.alignPanels.size(); a++)
1785 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1786 if (viewId.equals(ap.av.getSequenceSetId()))
1789 ap.av.gatherViewsHere = false;
1790 ap.av.explodedPosition = af.getBounds();
1791 source.addAlignmentPanel(ap, false);
1797 af.alignPanels.clear();
1798 af.closeMenuItem_actionPerformed(true);
1805 jalview.gui.VamsasApplication v_client = null;
1807 public void vamsasImport_actionPerformed(ActionEvent e)
1809 if (v_client == null)
1811 // Load and try to start a session.
1812 JalviewFileChooser chooser = new JalviewFileChooser(
1813 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1815 chooser.setFileView(new JalviewFileView());
1816 chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
1817 chooser.setToolTipText(MessageManager
1818 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1820 int value = chooser.showOpenDialog(this);
1822 if (value == JalviewFileChooser.APPROVE_OPTION)
1824 String fle = chooser.getSelectedFile().toString();
1825 if (!vamsasImport(chooser.getSelectedFile()))
1828 .showInternalMessageDialog(
1830 MessageManager.formatMessage(
1831 "label.couldnt_import_as_vamsas_session",
1835 .getString("label.vamsas_document_import_failed"),
1836 JOptionPane.ERROR_MESSAGE);
1842 jalview.bin.Cache.log
1843 .error("Implementation error - load session from a running session is not supported.");
1848 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1851 * @return true if import was a success and a session was started.
1853 public boolean vamsasImport(URL url)
1855 // TODO: create progress bar
1856 if (v_client != null)
1859 jalview.bin.Cache.log
1860 .error("Implementation error - load session from a running session is not supported.");
1866 // copy the URL content to a temporary local file
1867 // TODO: be a bit cleverer here with nio (?!)
1868 File file = File.createTempFile("vdocfromurl", ".vdj");
1869 FileOutputStream fos = new FileOutputStream(file);
1870 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1871 byte[] buffer = new byte[2048];
1873 while ((ln = bis.read(buffer)) > -1)
1875 fos.write(buffer, 0, ln);
1879 v_client = new jalview.gui.VamsasApplication(this, file,
1880 url.toExternalForm());
1881 } catch (Exception ex)
1883 jalview.bin.Cache.log.error(
1884 "Failed to create new vamsas session from contents of URL "
1888 setupVamsasConnectedGui();
1889 v_client.initial_update(); // TODO: thread ?
1890 return v_client.inSession();
1894 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1897 * @return true if import was a success and a session was started.
1899 public boolean vamsasImport(File file)
1901 if (v_client != null)
1904 jalview.bin.Cache.log
1905 .error("Implementation error - load session from a running session is not supported.");
1909 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1913 v_client = new jalview.gui.VamsasApplication(this, file, null);
1914 } catch (Exception ex)
1916 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1918 jalview.bin.Cache.log.error(
1919 "New vamsas session from existing session file failed:", ex);
1922 setupVamsasConnectedGui();
1923 v_client.initial_update(); // TODO: thread ?
1924 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1926 return v_client.inSession();
1929 public boolean joinVamsasSession(String mysesid)
1931 if (v_client != null)
1933 throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
1935 if (mysesid == null)
1937 throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
1939 v_client = new VamsasApplication(this, mysesid);
1940 setupVamsasConnectedGui();
1941 v_client.initial_update();
1942 return (v_client.inSession());
1945 public void vamsasStart_actionPerformed(ActionEvent e)
1947 if (v_client == null)
1950 // we just start a default session for moment.
1952 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1953 * getProperty("LAST_DIRECTORY"));
1955 * chooser.setFileView(new JalviewFileView());
1956 * chooser.setDialogTitle("Load Vamsas file");
1957 * chooser.setToolTipText("Import");
1959 * int value = chooser.showOpenDialog(this);
1961 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1962 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1964 v_client = new VamsasApplication(this);
1965 setupVamsasConnectedGui();
1966 v_client.initial_update(); // TODO: thread ?
1970 // store current data in session.
1971 v_client.push_update(); // TODO: thread
1975 protected void setupVamsasConnectedGui()
1977 vamsasStart.setText(MessageManager.getString("label.session_update"));
1978 vamsasSave.setVisible(true);
1979 vamsasStop.setVisible(true);
1980 vamsasImport.setVisible(false); // Document import to existing session is
1981 // not possible for vamsas-client-1.0.
1984 protected void setupVamsasDisconnectedGui()
1986 vamsasSave.setVisible(false);
1987 vamsasStop.setVisible(false);
1988 vamsasImport.setVisible(true);
1989 vamsasStart.setText(MessageManager
1990 .getString("label.new_vamsas_session"));
1993 public void vamsasStop_actionPerformed(ActionEvent e)
1995 if (v_client != null)
1997 v_client.end_session();
1999 setupVamsasDisconnectedGui();
2003 protected void buildVamsasStMenu()
2005 if (v_client == null)
2007 String[] sess = null;
2010 sess = VamsasApplication.getSessionList();
2011 } catch (Exception e)
2013 jalview.bin.Cache.log.warn(
2014 "Problem getting current sessions list.", e);
2019 jalview.bin.Cache.log.debug("Got current sessions list: "
2020 + sess.length + " entries.");
2021 VamsasStMenu.removeAll();
2022 for (int i = 0; i < sess.length; i++)
2024 JMenuItem sessit = new JMenuItem();
2025 sessit.setText(sess[i]);
2026 sessit.setToolTipText(MessageManager.formatMessage(
2027 "label.connect_to_session", new String[]
2029 final Desktop dsktp = this;
2030 final String mysesid = sess[i];
2031 sessit.addActionListener(new ActionListener()
2034 public void actionPerformed(ActionEvent e)
2036 if (dsktp.v_client == null)
2038 Thread rthr = new Thread(new Runnable()
2043 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2044 dsktp.setupVamsasConnectedGui();
2045 dsktp.v_client.initial_update();
2053 VamsasStMenu.add(sessit);
2055 // don't show an empty menu.
2056 VamsasStMenu.setVisible(sess.length > 0);
2061 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2062 VamsasStMenu.removeAll();
2063 VamsasStMenu.setVisible(false);
2068 // Not interested in the content. Just hide ourselves.
2069 VamsasStMenu.setVisible(false);
2073 public void vamsasSave_actionPerformed(ActionEvent e)
2075 if (v_client != null)
2077 JalviewFileChooser chooser = new JalviewFileChooser(
2078 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2079 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2081 { "Vamsas Document" }, "Vamsas Document");
2083 chooser.setFileView(new JalviewFileView());
2084 chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
2086 int value = chooser.showSaveDialog(this);
2088 if (value == JalviewFileChooser.APPROVE_OPTION)
2090 java.io.File choice = chooser.getSelectedFile();
2091 JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new String[]{choice.getName()}));
2092 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2093 String warnmsg = null;
2094 String warnttl = null;
2097 v_client.vclient.storeDocument(choice);
2100 warnttl = "Serious Problem saving Vamsas Document";
2101 warnmsg = ex.toString();
2102 jalview.bin.Cache.log.error("Error Whilst saving document to "
2105 } catch (Exception ex)
2107 warnttl = "Problem saving Vamsas Document.";
2108 warnmsg = ex.toString();
2109 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2113 removeProgressPanel(progpanel);
2114 if (warnmsg != null)
2116 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2118 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2124 JPanel vamUpdate = null;
2127 * hide vamsas user gui bits when a vamsas document event is being handled.
2130 * true to hide gui, false to reveal gui
2132 public void setVamsasUpdate(boolean b)
2134 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2135 + (b ? "in progress" : "finished"));
2137 if (vamUpdate != null)
2139 this.removeProgressPanel(vamUpdate);
2143 vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
2145 vamsasStart.setVisible(!b);
2146 vamsasStop.setVisible(!b);
2147 vamsasSave.setVisible(!b);
2150 public JInternalFrame[] getAllFrames()
2152 return desktop.getAllFrames();
2156 * Checks the given url to see if it gives a response indicating that the user
2157 * should be informed of a new questionnaire.
2161 public void checkForQuestionnaire(String url)
2163 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2164 // javax.swing.SwingUtilities.invokeLater(jvq);
2165 new Thread(jvq).start();
2169 * Proxy class for JDesktopPane which optionally displays the current memory
2170 * usage and highlights the desktop area with a red bar if free memory runs
2175 public class MyDesktopPane extends JDesktopPane implements Runnable
2178 boolean showMemoryUsage = false;
2182 java.text.NumberFormat df;
2184 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2187 public MyDesktopPane(boolean showMemoryUsage)
2189 showMemoryUsage(showMemoryUsage);
2192 public void showMemoryUsage(boolean showMemoryUsage)
2194 this.showMemoryUsage = showMemoryUsage;
2195 if (showMemoryUsage)
2197 Thread worker = new Thread(this);
2202 public boolean isShowMemoryUsage()
2204 return showMemoryUsage;
2209 df = java.text.NumberFormat.getNumberInstance();
2210 df.setMaximumFractionDigits(2);
2211 runtime = Runtime.getRuntime();
2213 while (showMemoryUsage)
2217 maxMemory = runtime.maxMemory() / 1048576f;
2218 allocatedMemory = runtime.totalMemory() / 1048576f;
2219 freeMemory = runtime.freeMemory() / 1048576f;
2220 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2222 percentUsage = (totalFreeMemory / maxMemory) * 100;
2224 // if (percentUsage < 20)
2226 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2228 // instance.set.setBorder(border1);
2231 // sleep after showing usage
2233 } catch (Exception ex)
2235 ex.printStackTrace();
2240 public void paintComponent(Graphics g)
2242 if (showMemoryUsage && g != null && df != null)
2244 if (percentUsage < 20)
2246 g.setColor(Color.red);
2248 FontMetrics fm = g.getFontMetrics();
2251 g.drawString(MessageManager.formatMessage(
2252 "label.memory_stats",
2254 { df.format(totalFreeMemory), df.format(maxMemory),
2255 df.format(percentUsage) }), 10,
2256 getHeight() - fm.getHeight());
2263 * fixes stacking order after a modal dialog to ensure windows that should be
2264 * on top actually are
2266 public void relayerWindows()
2271 protected JMenuItem groovyShell;
2273 public void doGroovyCheck()
2275 if (jalview.bin.Cache.groovyJarsPresent())
2277 groovyShell = new JMenuItem();
2278 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2279 groovyShell.addActionListener(new ActionListener()
2281 public void actionPerformed(ActionEvent e)
2283 groovyShell_actionPerformed(e);
2286 toolsMenu.add(groovyShell);
2287 groovyShell.setVisible(true);
2292 * Accessor method to quickly get all the AlignmentFrames loaded.
2294 public static AlignFrame[] getAlignframes()
2296 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2302 Vector avp = new Vector();
2306 for (int i = frames.length - 1; i > -1; i--)
2308 if (frames[i] instanceof AlignFrame)
2310 AlignFrame af = (AlignFrame) frames[i];
2314 } catch (Exception ex)
2316 ex.printStackTrace();
2318 if (avp.size() == 0)
2322 AlignFrame afs[] = new AlignFrame[avp.size()];
2323 for (int i = 0, j = avp.size(); i < j; i++)
2325 afs[i] = (AlignFrame) avp.elementAt(i);
2331 public GStructureViewer[] getJmols()
2333 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2339 Vector avp = new Vector();
2343 for (int i = frames.length - 1; i > -1; i--)
2345 if (frames[i] instanceof AppJmol)
2347 GStructureViewer af = (GStructureViewer) frames[i];
2351 } catch (Exception ex)
2353 ex.printStackTrace();
2355 if (avp.size() == 0)
2359 GStructureViewer afs[] = new GStructureViewer[avp.size()];
2360 for (int i = 0, j = avp.size(); i < j; i++)
2362 afs[i] = (GStructureViewer) avp.elementAt(i);
2369 * Add Groovy Support to Jalview
2371 public void groovyShell_actionPerformed(ActionEvent e)
2373 // use reflection to avoid creating compilation dependency.
2374 if (!jalview.bin.Cache.groovyJarsPresent())
2376 throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
2380 Class gcClass = Desktop.class.getClassLoader().loadClass(
2381 "groovy.ui.Console");
2382 Constructor gccons = gcClass.getConstructor(null);
2383 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2385 { String.class, Object.class });
2386 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2387 Object gc = gccons.newInstance(null);
2388 setvar.invoke(gc, new Object[]
2389 { "Jalview", this });
2390 run.invoke(gc, null);
2391 } catch (Exception ex)
2393 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2395 .showInternalMessageDialog(
2398 MessageManager.getString("label.couldnt_create_groovy_shell"),
2399 MessageManager.getString("label.groovy_support_failed"),
2400 JOptionPane.ERROR_MESSAGE);
2405 * Progress bars managed by the IProgressIndicator method.
2407 private Hashtable<Long, JPanel> progressBars;
2409 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2414 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2416 public void setProgressBar(String message, long id)
2418 if (progressBars == null)
2420 progressBars = new Hashtable<Long, JPanel>();
2421 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2424 if (progressBars.get(new Long(id)) != null)
2426 JPanel progressPanel = progressBars.remove(new Long(id));
2427 if (progressBarHandlers.contains(new Long(id)))
2429 progressBarHandlers.remove(new Long(id));
2431 removeProgressPanel(progressPanel);
2435 progressBars.put(new Long(id), addProgressPanel(message));
2442 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2443 * jalview.gui.IProgressIndicatorHandler)
2445 public void registerHandler(final long id,
2446 final IProgressIndicatorHandler handler)
2448 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2450 throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
2452 progressBarHandlers.put(new Long(id), handler);
2453 final JPanel progressPanel = progressBars.get(new Long(id));
2454 if (handler.canCancel())
2456 JButton cancel = new JButton(
2457 MessageManager.getString("action.cancel"));
2458 final IProgressIndicator us = this;
2459 cancel.addActionListener(new ActionListener()
2462 public void actionPerformed(ActionEvent e)
2464 handler.cancelActivity(id);
2465 us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
2468 progressPanel.add(cancel, BorderLayout.EAST);
2474 * @return true if any progress bars are still active
2477 public boolean operationInProgress()
2479 if (progressBars != null && progressBars.size() > 0)
2487 * This will return the first AlignFrame viewing AlignViewport av. It will
2488 * break if there are more than one AlignFrames viewing a particular av. This
2491 * @return alignFrame for av
2493 public static AlignFrame getAlignFrameFor(AlignViewport av)
2495 if (desktop != null)
2497 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2498 for (int panel = 0; aps != null && panel < aps.length; panel++)
2500 if (aps[panel] != null && aps[panel].av == av)
2502 return aps[panel].alignFrame;
2509 public VamsasApplication getVamsasApplication()
2516 * flag set if jalview GUI is being operated programmatically
2518 private boolean inBatchMode = false;
2521 * check if jalview GUI is being operated programmatically
2523 * @return inBatchMode
2525 public boolean isInBatchMode()
2531 * set flag if jalview GUI is being operated programmatically
2533 * @param inBatchMode
2535 public void setInBatchMode(boolean inBatchMode)
2537 this.inBatchMode = inBatchMode;
2540 public void startServiceDiscovery()
2542 startServiceDiscovery(false);
2545 public void startServiceDiscovery(boolean blocking)
2547 boolean alive = true;
2548 Thread t0 = null, t1 = null, t2 = null;
2549 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2552 // todo: changesupport handlers need to be transferred
2553 if (discoverer == null)
2555 discoverer = new jalview.ws.jws1.Discoverer();
2556 // register PCS handler for desktop.
2557 discoverer.addPropertyChangeListener(changeSupport);
2559 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2560 // until we phase out completely
2561 (t0 = new Thread(discoverer)).start();
2564 // ENFIN services are EOLed as of Jalview 2.8.1 release
2569 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2571 // EnfinEnvision web service menu entries are rebuild every time the
2572 // menu is shown, so no changeSupport events are needed.
2573 jalview.ws.EnfinEnvision2OneWay.getInstance();
2574 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2577 } catch (Exception e)
2580 .info("Exception when trying to launch Envision2 workflow discovery.",
2582 Cache.log.info(e.getStackTrace());
2586 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2588 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2590 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2592 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2598 // TODO: do rest service discovery
2607 } catch (Exception e)
2610 alive = (t1 != null && t1.isAlive())
2611 || (t2 != null && t2.isAlive())
2612 || (t3 != null && t3.isAlive())
2613 || (t0 != null && t0.isAlive());
2619 * called to check if the service discovery process completed successfully.
2623 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2625 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2627 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2628 .getErrorMessages();
2631 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2633 if (serviceChangedDialog == null)
2635 // only run if we aren't already displaying one of these.
2636 addDialogThread(serviceChangedDialog = new Runnable()
2642 * JalviewDialog jd =new JalviewDialog() {
2644 * @Override protected void cancelPressed() { // TODO
2645 * Auto-generated method stub
2647 * }@Override protected void okPressed() { // TODO
2648 * Auto-generated method stub
2650 * }@Override protected void raiseClosed() { // TODO
2651 * Auto-generated method stub
2653 * } }; jd.initDialogFrame(new
2654 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2655 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2656 * + " or mis-configured HTTP proxy settings.<br/>" +
2657 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2659 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2660 * ), true, true, "Web Service Configuration Problem", 450,
2663 * jd.waitForInput();
2669 "<html><table width=\"450\"><tr><td>"
2671 + "</td></tr></table>"
2672 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2673 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2674 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2675 + " Tools->Preferences dialog box to change them.</p></html>"),
2676 "Web Service Configuration Problem",
2677 JOptionPane.DEFAULT_OPTION,
2678 JOptionPane.ERROR_MESSAGE);
2679 serviceChangedDialog = null;
2688 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2695 private Runnable serviceChangedDialog = null;
2698 * start a thread to open a URL in the configured browser. Pops up a warning
2699 * dialog to the user if there is an exception when calling out to the browser
2704 public static void showUrl(final String url)
2706 showUrl(url, Desktop.instance);
2710 * Like showUrl but allows progress handler to be specified
2714 * (null) or object implementing IProgressIndicator
2716 public static void showUrl(final String url,
2717 final IProgressIndicator progress)
2719 new Thread(new Runnable()
2725 if (progress != null)
2727 progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new String[]{url}), this.hashCode());
2729 jalview.util.BrowserLauncher.openURL(url);
2730 } catch (Exception ex)
2733 .showInternalMessageDialog(
2735 MessageManager.getString("label.web_browser_not_found_unix"),
2736 MessageManager.getString("label.web_browser_not_found"),
2737 JOptionPane.WARNING_MESSAGE);
2739 ex.printStackTrace();
2741 if (progress != null)
2743 progress.setProgressBar(null, this.hashCode());
2749 public static WsParamSetManager wsparamManager = null;
2751 public static ParamManager getUserParameterStore()
2753 if (wsparamManager == null)
2755 wsparamManager = new WsParamSetManager();
2757 return wsparamManager;
2761 * static hyperlink handler proxy method for use by Jalview's internal windows
2765 public static void hyperlinkUpdate(HyperlinkEvent e)
2767 if (e.getEventType() == EventType.ACTIVATED)
2772 url = e.getURL().toString();
2773 Desktop.showUrl(url);
2774 } catch (Exception x)
2778 if (Cache.log != null)
2780 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2784 System.err.println("Couldn't handle string " + url
2788 // ignore any exceptions due to dud links.
2795 * single thread that handles display of dialogs to user.
2797 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2800 * flag indicating if dialogExecutor should try to acquire a permit
2802 private volatile boolean dialogPause = true;
2807 private java.util.concurrent.Semaphore block = new Semaphore(0);
2810 * add another dialog thread to the queue
2814 public void addDialogThread(final Runnable prompter)
2816 dialogExecutor.submit(new Runnable()
2825 } catch (InterruptedException x)
2830 if (instance == null)
2836 SwingUtilities.invokeAndWait(prompter);
2837 } catch (Exception q)
2839 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2845 public void startDialogQueue()
2847 // set the flag so we don't pause waiting for another permit and semaphore
2848 // the current task to begin
2849 dialogPause = false;
2853 protected void snapShotWindow_actionPerformed(ActionEvent e)
2857 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2858 "View of Desktop", getWidth(), getHeight(), of = new File(
2859 "Jalview_snapshot" + System.currentTimeMillis()
2860 + ".eps"), "View of desktop");
2862 paintAll(im.getGraphics());
2864 } catch (Exception q)
2866 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2869 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());