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.structure.StructureSelectionManager;
30 import jalview.util.ImageMaker;
31 import jalview.util.MessageManager;
32 import jalview.ws.params.ParamManager;
34 import java.awt.BorderLayout;
35 import java.awt.Color;
36 import java.awt.Dimension;
37 import java.awt.FontMetrics;
38 import java.awt.Graphics;
39 import java.awt.GridLayout;
40 import java.awt.Point;
41 import java.awt.Rectangle;
42 import java.awt.Toolkit;
43 import java.awt.datatransfer.Clipboard;
44 import java.awt.datatransfer.ClipboardOwner;
45 import java.awt.datatransfer.DataFlavor;
46 import java.awt.datatransfer.Transferable;
47 import java.awt.dnd.DnDConstants;
48 import java.awt.dnd.DropTargetDragEvent;
49 import java.awt.dnd.DropTargetDropEvent;
50 import java.awt.dnd.DropTargetEvent;
51 import java.awt.dnd.DropTargetListener;
52 import java.awt.event.ActionEvent;
53 import java.awt.event.ActionListener;
54 import java.awt.event.FocusEvent;
55 import java.awt.event.FocusListener;
56 import java.awt.event.MouseAdapter;
57 import java.awt.event.MouseEvent;
58 import java.awt.event.MouseListener;
59 import java.awt.event.WindowAdapter;
60 import java.awt.event.WindowEvent;
61 import java.beans.PropertyChangeEvent;
62 import java.beans.PropertyChangeListener;
63 import java.beans.PropertyVetoException;
64 import java.io.BufferedInputStream;
66 import java.io.FileOutputStream;
67 import java.lang.reflect.Constructor;
69 import java.util.ArrayList;
70 import java.util.Hashtable;
71 import java.util.StringTokenizer;
72 import java.util.Vector;
73 import java.util.concurrent.ExecutorService;
74 import java.util.concurrent.Executors;
75 import java.util.concurrent.Semaphore;
77 import javax.swing.DefaultDesktopManager;
78 import javax.swing.DesktopManager;
79 import javax.swing.JButton;
80 import javax.swing.JComboBox;
81 import javax.swing.JComponent;
82 import javax.swing.JDesktopPane;
83 import javax.swing.JFrame;
84 import javax.swing.JInternalFrame;
85 import javax.swing.JLabel;
86 import javax.swing.JMenuItem;
87 import javax.swing.JOptionPane;
88 import javax.swing.JPanel;
89 import javax.swing.JPopupMenu;
90 import javax.swing.JProgressBar;
91 import javax.swing.SwingUtilities;
92 import javax.swing.event.HyperlinkEvent;
93 import javax.swing.event.HyperlinkEvent.EventType;
94 import javax.swing.event.MenuEvent;
95 import javax.swing.event.MenuListener;
102 * @version $Revision: 1.155 $
104 public class Desktop extends jalview.jbgui.GDesktop implements
105 DropTargetListener, ClipboardOwner, IProgressIndicator,
106 jalview.api.StructureSelectionManagerProvider
109 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
112 * news reader - null if it was never started.
114 private BlogReader jvnews = null;
118 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
120 public void addJalviewPropertyChangeListener(
121 PropertyChangeListener listener)
123 changeSupport.addJalviewPropertyChangeListener(listener);
127 * @param propertyName
129 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
130 * java.beans.PropertyChangeListener)
132 public void addJalviewPropertyChangeListener(String propertyName,
133 PropertyChangeListener listener)
135 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
139 * @param propertyName
141 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
142 * java.beans.PropertyChangeListener)
144 public void removeJalviewPropertyChangeListener(String propertyName,
145 PropertyChangeListener listener)
147 changeSupport.removeJalviewPropertyChangeListener(propertyName,
151 /** Singleton Desktop instance */
152 public static Desktop instance;
154 public static MyDesktopPane desktop;
156 static int openFrameCount = 0;
158 static final int xOffset = 30;
160 static final int yOffset = 30;
162 public static jalview.ws.jws1.Discoverer discoverer;
164 public static Object[] jalviewClipboard;
166 public static boolean internalCopy = false;
168 static int fileLoadingCount = 0;
170 class MyDesktopManager implements DesktopManager
173 private DesktopManager delegate;
175 public MyDesktopManager(DesktopManager delegate)
177 this.delegate = delegate;
180 public void activateFrame(JInternalFrame f)
184 delegate.activateFrame(f);
185 } catch (NullPointerException npe)
187 Point p = getMousePosition();
188 instance.showPasteMenu(p.x, p.y);
192 public void beginDraggingFrame(JComponent f)
194 delegate.beginDraggingFrame(f);
197 public void beginResizingFrame(JComponent f, int direction)
199 delegate.beginResizingFrame(f, direction);
202 public void closeFrame(JInternalFrame f)
204 delegate.closeFrame(f);
207 public void deactivateFrame(JInternalFrame f)
209 delegate.deactivateFrame(f);
212 public void deiconifyFrame(JInternalFrame f)
214 delegate.deiconifyFrame(f);
217 public void dragFrame(JComponent f, int newX, int newY)
223 delegate.dragFrame(f, newX, newY);
226 public void endDraggingFrame(JComponent f)
228 delegate.endDraggingFrame(f);
231 public void endResizingFrame(JComponent f)
233 delegate.endResizingFrame(f);
236 public void iconifyFrame(JInternalFrame f)
238 delegate.iconifyFrame(f);
241 public void maximizeFrame(JInternalFrame f)
243 delegate.maximizeFrame(f);
246 public void minimizeFrame(JInternalFrame f)
248 delegate.minimizeFrame(f);
251 public void openFrame(JInternalFrame f)
253 delegate.openFrame(f);
256 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
259 Rectangle b = desktop.getBounds();
264 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
267 public void setBoundsForFrame(JComponent f, int newX, int newY,
268 int newWidth, int newHeight)
270 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
273 // All other methods, simply delegate
278 * Creates a new Desktop object.
283 * A note to implementors. It is ESSENTIAL that any activities that might
284 * block are spawned off as threads rather than waited for during this
288 doVamsasClientCheck();
290 doConfigureStructurePrefs();
291 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
292 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
293 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
295 boolean showjconsole = jalview.bin.Cache.getDefault(
296 "SHOW_JAVA_CONSOLE", false);
297 desktop = new MyDesktopPane(selmemusage);
298 showMemusage.setSelected(selmemusage);
299 desktop.setBackground(Color.white);
300 getContentPane().setLayout(new BorderLayout());
301 // alternate config - have scrollbars - see notes in JAL-153
302 // JScrollPane sp = new JScrollPane();
303 // sp.getViewport().setView(desktop);
304 // getContentPane().add(sp, BorderLayout.CENTER);
305 getContentPane().add(desktop, BorderLayout.CENTER);
306 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
308 // This line prevents Windows Look&Feel resizing all new windows to maximum
309 // if previous window was maximised
310 desktop.setDesktopManager(new MyDesktopManager(
311 new DefaultDesktopManager()));
313 Rectangle dims = getLastKnownDimensions("");
320 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
321 setBounds((screenSize.width - 900) / 2,
322 (screenSize.height - 650) / 2, 900, 650);
324 jconsole = new Console(this, showjconsole);
325 // add essential build information
326 jconsole.setHeader("Jalview Version: "
327 + jalview.bin.Cache.getProperty("VERSION") + "\n"
328 + "Jalview Installation: "
329 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
332 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
333 + "Java version: " + System.getProperty("java.version") + "\n"
334 + System.getProperty("os.arch") + " "
335 + System.getProperty("os.name") + " "
336 + System.getProperty("os.version"));
338 showConsole(showjconsole);
340 showNews.setVisible(false);
342 this.addWindowListener(new WindowAdapter()
344 public void windowClosing(WindowEvent evt)
351 this.addMouseListener(ma = new MouseAdapter()
353 public void mousePressed(MouseEvent evt)
355 if (SwingUtilities.isRightMouseButton(evt))
357 showPasteMenu(evt.getX(), evt.getY());
361 desktop.addMouseListener(ma);
363 this.addFocusListener(new FocusListener()
367 public void focusLost(FocusEvent e)
369 // TODO Auto-generated method stub
374 public void focusGained(FocusEvent e)
376 Cache.log.debug("Relaying windows after focus gain");
377 // make sure that we sort windows properly after we gain focus
378 instance.relayerWindows();
381 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
382 // Spawn a thread that shows the splashscreen
383 SwingUtilities.invokeLater(new Runnable()
392 // Thread off a new instance of the file chooser - this reduces the time it
393 // takes to open it later on.
394 new Thread(new Runnable()
398 Cache.log.debug("Filechooser init thread started.");
399 JalviewFileChooser chooser = new JalviewFileChooser(
400 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
401 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
402 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
403 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
404 Cache.log.debug("Filechooser init thread finished.");
407 // Add the service change listener
408 changeSupport.addJalviewPropertyChangeListener("services",
409 new PropertyChangeListener()
413 public void propertyChange(PropertyChangeEvent evt)
415 Cache.log.debug("Firing service changed event for "
416 + evt.getNewValue());
417 JalviewServicesChanged(evt);
423 public void doConfigureStructurePrefs()
425 // configure services
426 StructureSelectionManager ssm = StructureSelectionManager
427 .getStructureSelectionManager(this);
428 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
430 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
431 Preferences.ADD_TEMPFACT_ANN, true));
432 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(Preferences.STRUCT_FROM_PDB, true));
433 ssm.setSecStructServices(jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW,
438 ssm.setAddTempFacAnnot(false);
439 ssm.setProcessSecondaryStructure(false);
440 ssm.setSecStructServices(false);
444 public void checkForNews()
446 final Desktop me = this;
447 // Thread off the news reader, in case there are connection problems.
448 addDialogThread(new Runnable()
453 Cache.log.debug("Starting news thread.");
455 jvnews = new BlogReader(me);
456 showNews.setVisible(true);
457 Cache.log.debug("Completed news thread.");
462 protected void showNews_actionPerformed(ActionEvent e)
464 showNews(showNews.isSelected());
467 void showNews(boolean visible)
470 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
471 showNews.setSelected(visible);
472 if (visible && !jvnews.isVisible())
474 new Thread(new Runnable()
479 long instance = System.currentTimeMillis();
480 Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_news"), instance);
481 jvnews.refreshNews();
482 Desktop.instance.setProgressBar(null, instance);
491 * recover the last known dimensions for a jalview window
494 * - empty string is desktop, all other windows have unique prefix
495 * @return null or last known dimensions scaled to current geometry (if last
496 * window geom was known)
498 Rectangle getLastKnownDimensions(String windowName)
500 // TODO: lock aspect ratio for scaling desktop Bug #0058199
501 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
502 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
503 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
504 String width = jalview.bin.Cache.getProperty(windowName
506 String height = jalview.bin.Cache.getProperty(windowName
508 if ((x != null) && (y != null) && (width != null) && (height != null))
510 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
511 .parseInt(width), ih = Integer.parseInt(height);
512 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
514 // attempt #1 - try to cope with change in screen geometry - this
515 // version doesn't preserve original jv aspect ratio.
516 // take ratio of current screen size vs original screen size.
517 double sw = ((1f * screenSize.width) / (1f * Integer
518 .parseInt(jalview.bin.Cache
519 .getProperty("SCREENGEOMETRY_WIDTH"))));
520 double sh = ((1f * screenSize.height) / (1f * Integer
521 .parseInt(jalview.bin.Cache
522 .getProperty("SCREENGEOMETRY_HEIGHT"))));
523 // rescale the bounds depending upon the current screen geometry.
524 ix = (int) (ix * sw);
525 iw = (int) (iw * sw);
526 iy = (int) (iy * sh);
527 ih = (int) (ih * sh);
528 while (ix >= screenSize.width)
530 jalview.bin.Cache.log
531 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
532 ix -= screenSize.width;
534 while (iy >= screenSize.height)
536 jalview.bin.Cache.log
537 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
538 iy -= screenSize.height;
540 jalview.bin.Cache.log.debug("Got last known dimensions for "
541 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
544 // return dimensions for new instance
545 return new Rectangle(ix, iy, iw, ih);
550 private void doVamsasClientCheck()
552 if (jalview.bin.Cache.vamsasJarsPresent())
554 setupVamsasDisconnectedGui();
555 VamsasMenu.setVisible(true);
556 final Desktop us = this;
557 VamsasMenu.addMenuListener(new MenuListener()
559 // this listener remembers when the menu was first selected, and
560 // doesn't rebuild the session list until it has been cleared and
562 boolean refresh = true;
564 public void menuCanceled(MenuEvent e)
569 public void menuDeselected(MenuEvent e)
574 public void menuSelected(MenuEvent e)
578 us.buildVamsasStMenu();
583 vamsasStart.setVisible(true);
587 void showPasteMenu(int x, int y)
589 JPopupMenu popup = new JPopupMenu();
590 JMenuItem item = new JMenuItem(
591 MessageManager.getString("label.paste_new_window"));
592 item.addActionListener(new ActionListener()
594 public void actionPerformed(ActionEvent evt)
601 popup.show(this, x, y);
608 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
609 Transferable contents = c.getContents(this);
611 if (contents != null)
613 String file = (String) contents
614 .getTransferData(DataFlavor.stringFlavor);
616 String format = new IdentifyFile().Identify(file,
617 FormatAdapter.PASTE);
619 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
622 } catch (Exception ex)
625 .println("Unable to paste alignment from system clipboard:\n"
631 * Adds and opens the given frame to the desktop
642 public static synchronized void addInternalFrame(
643 final JInternalFrame frame, String title, int w, int h)
645 addInternalFrame(frame, title, w, h, true);
662 public static synchronized void addInternalFrame(
663 final JInternalFrame frame, String title, int w, int h,
667 // TODO: allow callers to determine X and Y position of frame (eg. via
669 // TODO: consider fixing method to update entries in the window submenu with
670 // the current window title
672 frame.setTitle(title);
673 if (frame.getWidth() < 1 || frame.getHeight() < 1)
677 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
678 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
679 // IF JALVIEW IS RUNNING HEADLESS
680 // ///////////////////////////////////////////////
682 || (System.getProperty("java.awt.headless") != null && System
683 .getProperty("java.awt.headless").equals("true")))
690 frame.setVisible(true);
691 frame.setClosable(true);
692 frame.setResizable(resizable);
693 frame.setMaximizable(resizable);
694 frame.setIconifiable(resizable);
695 frame.setFrameIcon(null);
697 if (frame.getX() < 1 && frame.getY() < 1)
699 frame.setLocation(xOffset * openFrameCount, yOffset
700 * ((openFrameCount - 1) % 10) + yOffset);
703 final JMenuItem menuItem = new JMenuItem(title);
704 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
706 public void internalFrameActivated(
707 javax.swing.event.InternalFrameEvent evt)
709 JInternalFrame itf = desktop.getSelectedFrame();
717 public void internalFrameClosed(
718 javax.swing.event.InternalFrameEvent evt)
720 PaintRefresher.RemoveComponent(frame);
722 windowMenu.remove(menuItem);
723 JInternalFrame itf = desktop.getSelectedFrame();
732 menuItem.addActionListener(new ActionListener()
734 public void actionPerformed(ActionEvent e)
738 frame.setSelected(true);
739 frame.setIcon(false);
740 } catch (java.beans.PropertyVetoException ex)
746 menuItem.addMouseListener(new MouseListener()
750 public void mouseReleased(MouseEvent e)
755 public void mousePressed(MouseEvent e)
760 public void mouseExited(MouseEvent e)
764 frame.setSelected(false);
765 } catch (PropertyVetoException e1)
771 public void mouseEntered(MouseEvent e)
775 frame.setSelected(true);
776 } catch (PropertyVetoException e1)
782 public void mouseClicked(MouseEvent e)
788 windowMenu.add(menuItem);
794 frame.setSelected(true);
795 frame.requestFocus();
796 } catch (java.beans.PropertyVetoException ve)
798 } catch (java.lang.ClassCastException cex)
801 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
806 public void lostOwnership(Clipboard clipboard, Transferable contents)
810 Desktop.jalviewClipboard = null;
813 internalCopy = false;
816 public void dragEnter(DropTargetDragEvent evt)
820 public void dragExit(DropTargetEvent evt)
824 public void dragOver(DropTargetDragEvent evt)
828 public void dropActionChanged(DropTargetDragEvent evt)
838 public void drop(DropTargetDropEvent evt)
840 boolean success = true;
841 Transferable t = evt.getTransferable();
842 java.util.List files = null;
843 java.util.List protocols = null;
847 DataFlavor uriListFlavor = new DataFlavor(
848 "text/uri-list;class=java.lang.String");
849 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
851 // Works on Windows and MacOSX
852 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
853 files = (java.util.List) t
854 .getTransferData(DataFlavor.javaFileListFlavor);
856 else if (t.isDataFlavorSupported(uriListFlavor))
858 // This is used by Unix drag system
859 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
860 String data = (String) t.getTransferData(uriListFlavor);
861 files = new java.util.ArrayList(1);
862 protocols = new java.util.ArrayList(1);
863 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
864 data, "\r\n"); st.hasMoreTokens();)
866 String s = st.nextToken();
867 if (s.startsWith("#"))
869 // the line is a comment (as per the RFC 2483)
872 java.net.URI uri = new java.net.URI(s);
873 if (uri.getScheme().toLowerCase().startsWith("http"))
875 protocols.add(FormatAdapter.URL);
876 files.add(uri.toString());
880 // otherwise preserve old behaviour: catch all for file objects
881 java.io.File file = new java.io.File(uri);
882 protocols.add(FormatAdapter.FILE);
883 files.add(file.toString());
887 } catch (Exception e)
896 for (int i = 0; i < files.size(); i++)
898 String file = files.get(i).toString();
899 String protocol = (protocols == null) ? FormatAdapter.FILE
900 : (String) protocols.get(i);
901 String format = null;
903 if (file.endsWith(".jar"))
910 format = new IdentifyFile().Identify(file, protocol);
913 new FileLoader().LoadFile(file, protocol, format);
916 } catch (Exception ex)
921 evt.dropComplete(success); // need this to ensure input focus is properly
922 // transfered to any new windows created
931 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
933 JalviewFileChooser chooser = new JalviewFileChooser(
934 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
935 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
936 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
937 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
939 chooser.setFileView(new JalviewFileView());
940 chooser.setDialogTitle(MessageManager
941 .getString("label.open_local_file"));
942 chooser.setToolTipText(MessageManager.getString("action.open"));
944 int value = chooser.showOpenDialog(this);
946 if (value == JalviewFileChooser.APPROVE_OPTION)
948 String choice = chooser.getSelectedFile().getPath();
949 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
950 .getSelectedFile().getParent());
952 String format = null;
953 if (chooser.getSelectedFormat() != null
954 && chooser.getSelectedFormat().equals("Jalview"))
960 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
963 if (viewport != null)
965 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
970 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
981 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
983 // This construct allows us to have a wider textfield
985 JLabel label = new JLabel(
986 MessageManager.getString("label.input_file_url"));
987 final JComboBox history = new JComboBox();
989 JPanel panel = new JPanel(new GridLayout(2, 1));
992 history.setPreferredSize(new Dimension(400, 20));
993 history.setEditable(true);
994 history.addItem("http://www.");
996 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1000 if (historyItems != null)
1002 st = new StringTokenizer(historyItems, "\t");
1004 while (st.hasMoreTokens())
1006 history.addItem(st.nextElement());
1010 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1011 MessageManager.getString("label.input_alignment_from_url"),
1012 JOptionPane.OK_CANCEL_OPTION);
1014 if (reply != JOptionPane.OK_OPTION)
1019 String url = history.getSelectedItem().toString();
1021 if (url.toLowerCase().endsWith(".jar"))
1023 if (viewport != null)
1025 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1030 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1035 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1037 if (format.equals("URL NOT FOUND"))
1039 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1040 MessageManager.formatMessage("label.couldnt_locate", new String[]{url}), MessageManager.getString("label.url_not_found"),
1041 JOptionPane.WARNING_MESSAGE);
1046 if (viewport != null)
1048 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1052 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1063 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1065 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1066 cap.setForInput(viewport);
1067 Desktop.addInternalFrame(cap,
1068 MessageManager.getString("label.cut_paste_alignmen_file"),
1077 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1079 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1080 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1082 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1083 getBounds().y, getWidth(), getHeight()));
1085 if (jconsole != null)
1087 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1088 jconsole.stopConsole();
1092 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1095 if (dialogExecutor != null)
1097 dialogExecutor.shutdownNow();
1103 private void storeLastKnownDimensions(String string, Rectangle jc)
1105 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1106 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1107 + " height:" + jc.height);
1109 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1110 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1111 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1112 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1121 public void aboutMenuItem_actionPerformed(ActionEvent e)
1123 // StringBuffer message = getAboutMessage(false);
1124 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1126 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1127 new Thread(new Runnable()
1131 new SplashScreen(true);
1136 public StringBuffer getAboutMessage(boolean shortv)
1138 StringBuffer message = new StringBuffer();
1139 message.append("<html>");
1142 message.append("<h1><strong>Version: "
1143 + jalview.bin.Cache.getProperty("VERSION")
1144 + "</strong></h1>");
1145 message.append("<strong>Last Updated: <em>"
1146 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1147 + "</em></strong>");
1153 message.append("<strong>Version "
1154 + jalview.bin.Cache.getProperty("VERSION")
1155 + "; last updated: "
1156 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1159 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1162 message.append("<br>...Checking latest version...</br>");
1164 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1165 .equals(jalview.bin.Cache.getProperty("VERSION")))
1167 boolean red = false;
1168 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1169 .indexOf("automated build") == -1)
1172 // Displayed when code version and jnlp version do not match and code
1173 // version is not a development build
1174 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1177 message.append("<br>!! Version "
1178 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1180 + " is available for download from "
1181 + jalview.bin.Cache.getDefault("www.jalview.org",
1182 "http://www.jalview.org") + " !!");
1185 message.append("</div>");
1188 message.append("<br>Authors: "
1192 "The Jalview Authors (See AUTHORS file for current list)")
1193 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1194 + "<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"
1195 + "<br><br>If you use Jalview, please cite:"
1196 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1197 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1198 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1209 public void documentationMenuItem_actionPerformed(ActionEvent e)
1213 Help.showHelpWindow();
1214 } catch (Exception ex)
1219 public void closeAll_actionPerformed(ActionEvent e)
1221 JInternalFrame[] frames = desktop.getAllFrames();
1222 for (int i = 0; i < frames.length; i++)
1226 frames[i].setClosed(true);
1227 } catch (java.beans.PropertyVetoException ex)
1231 System.out.println("ALL CLOSED");
1232 if (v_client != null)
1234 // TODO clear binding to vamsas document objects on close_all
1239 public void raiseRelated_actionPerformed(ActionEvent e)
1241 reorderAssociatedWindows(false, false);
1244 public void minimizeAssociated_actionPerformed(ActionEvent e)
1246 reorderAssociatedWindows(true, false);
1249 void closeAssociatedWindows()
1251 reorderAssociatedWindows(false, true);
1257 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1260 protected void garbageCollect_actionPerformed(ActionEvent e)
1262 // We simply collect the garbage
1263 jalview.bin.Cache.log.debug("Collecting garbage...");
1265 jalview.bin.Cache.log.debug("Finished garbage collection.");
1272 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1275 protected void showMemusage_actionPerformed(ActionEvent e)
1277 desktop.showMemoryUsage(showMemusage.isSelected());
1284 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1287 protected void showConsole_actionPerformed(ActionEvent e)
1289 showConsole(showConsole.isSelected());
1292 Console jconsole = null;
1295 * control whether the java console is visible or not
1299 void showConsole(boolean selected)
1301 showConsole.setSelected(selected);
1302 // TODO: decide if we should update properties file
1303 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1305 jconsole.setVisible(selected);
1308 void reorderAssociatedWindows(boolean minimize, boolean close)
1310 JInternalFrame[] frames = desktop.getAllFrames();
1311 if (frames == null || frames.length < 1)
1316 AlignViewport source = null, target = null;
1317 if (frames[0] instanceof AlignFrame)
1319 source = ((AlignFrame) frames[0]).getCurrentView();
1321 else if (frames[0] instanceof TreePanel)
1323 source = ((TreePanel) frames[0]).getViewPort();
1325 else if (frames[0] instanceof PCAPanel)
1327 source = ((PCAPanel) frames[0]).av;
1329 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1331 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1336 for (int i = 0; i < frames.length; i++)
1339 if (frames[i] == null)
1343 if (frames[i] instanceof AlignFrame)
1345 target = ((AlignFrame) frames[i]).getCurrentView();
1347 else if (frames[i] instanceof TreePanel)
1349 target = ((TreePanel) frames[i]).getViewPort();
1351 else if (frames[i] instanceof PCAPanel)
1353 target = ((PCAPanel) frames[i]).av;
1355 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1357 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1360 if (source == target)
1366 frames[i].setClosed(true);
1370 frames[i].setIcon(minimize);
1373 frames[i].toFront();
1377 } catch (java.beans.PropertyVetoException ex)
1391 protected void preferences_actionPerformed(ActionEvent e)
1402 public void saveState_actionPerformed(ActionEvent e)
1404 JalviewFileChooser chooser = new JalviewFileChooser(
1405 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1406 { "jvp" }, new String[]
1407 { "Jalview Project" }, "Jalview Project");
1409 chooser.setFileView(new JalviewFileView());
1410 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1412 int value = chooser.showSaveDialog(this);
1414 if (value == JalviewFileChooser.APPROVE_OPTION)
1416 final Desktop me = this;
1417 final java.io.File choice = chooser.getSelectedFile();
1418 new Thread(new Runnable()
1423 setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new String[]{choice.getName()}),
1425 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1426 choice.getParent());
1427 // TODO catch and handle errors for savestate
1428 // TODO prevent user from messing with the Desktop whilst we're saving
1431 new Jalview2XML().SaveState(choice);
1432 } catch (OutOfMemoryError oom)
1434 new OOMWarning("Whilst saving current state to "
1435 + choice.getName(), oom);
1436 } catch (Exception ex)
1439 "Problems whilst trying to save to " + choice.getName(),
1441 JOptionPane.showMessageDialog(
1443 MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new String[]{ choice.getName()}),
1444 MessageManager.getString("label.couldnt_save_project"),
1445 JOptionPane.WARNING_MESSAGE);
1447 setProgressBar(null, choice.hashCode());
1459 public void loadState_actionPerformed(ActionEvent e)
1461 JalviewFileChooser chooser = new JalviewFileChooser(
1462 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1463 { "jvp", "jar" }, new String[]
1464 { "Jalview Project", "Jalview Project (old)" },
1466 chooser.setFileView(new JalviewFileView());
1467 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1469 int value = chooser.showOpenDialog(this);
1471 if (value == JalviewFileChooser.APPROVE_OPTION)
1473 final String choice = chooser.getSelectedFile().getAbsolutePath();
1474 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1475 .getSelectedFile().getParent());
1476 new Thread(new Runnable()
1480 setProgressBar(MessageManager.formatMessage("label.loading_jalview_project", new String[]{choice}),
1484 new Jalview2XML().LoadJalviewAlign(choice);
1485 } catch (OutOfMemoryError oom)
1487 new OOMWarning("Whilst loading project from " + choice, oom);
1488 } catch (Exception ex)
1490 Cache.log.error("Problems whilst loading project from "
1492 JOptionPane.showMessageDialog(Desktop.desktop,
1493 MessageManager.formatMessage("label.error_whilst_loading_project_from", new String[]{choice}),
1494 MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE);
1496 setProgressBar(null, choice.hashCode());
1502 public void inputSequence_actionPerformed(ActionEvent e)
1504 new SequenceFetcher(this);
1507 JPanel progressPanel;
1509 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1511 public void startLoading(final String fileName)
1513 if (fileLoadingCount == 0)
1515 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage("label.loading_file", new String[]{fileName})));
1520 private JPanel addProgressPanel(String string)
1522 if (progressPanel == null)
1524 progressPanel = new JPanel(new GridLayout(1, 1));
1525 totalProgressCount = 0;
1526 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1528 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1529 JProgressBar progressBar = new JProgressBar();
1530 progressBar.setIndeterminate(true);
1532 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1534 thisprogress.add(progressBar, BorderLayout.CENTER);
1535 progressPanel.add(thisprogress);
1536 ((GridLayout) progressPanel.getLayout())
1537 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1538 ++totalProgressCount;
1539 instance.validate();
1540 return thisprogress;
1543 int totalProgressCount = 0;
1545 private void removeProgressPanel(JPanel progbar)
1547 if (progressPanel != null)
1549 synchronized (progressPanel)
1551 progressPanel.remove(progbar);
1552 GridLayout gl = (GridLayout) progressPanel.getLayout();
1553 gl.setRows(gl.getRows() - 1);
1554 if (--totalProgressCount < 1)
1556 this.getContentPane().remove(progressPanel);
1557 progressPanel = null;
1564 public void stopLoading()
1567 if (fileLoadingCount < 1)
1569 while (fileLoadingPanels.size() > 0)
1571 removeProgressPanel(fileLoadingPanels.remove(0));
1573 fileLoadingPanels.clear();
1574 fileLoadingCount = 0;
1579 public static int getViewCount(String alignmentId)
1581 AlignViewport[] aps = getViewports(alignmentId);
1582 return (aps == null) ? 0 : aps.length;
1587 * @param alignmentId
1588 * @return all AlignmentPanels concerning the alignmentId sequence set
1590 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1593 if (Desktop.desktop == null)
1595 // no frames created and in headless mode
1596 // TODO: verify that frames are recoverable when in headless mode
1599 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1600 ArrayList aps = new ArrayList();
1601 for (int t = 0; t < frames.length; t++)
1603 if (frames[t] instanceof AlignFrame)
1605 AlignFrame af = (AlignFrame) frames[t];
1606 for (int a = 0; a < af.alignPanels.size(); a++)
1608 if (alignmentId.equals(((AlignmentPanel) af.alignPanels
1609 .elementAt(a)).av.getSequenceSetId()))
1611 aps.add(af.alignPanels.elementAt(a));
1616 if (aps.size() == 0)
1620 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1621 for (int t = 0; t < vap.length; t++)
1623 vap[t] = (AlignmentPanel) aps.get(t);
1629 * get all the viewports on an alignment.
1631 * @param sequenceSetId
1632 * unique alignment id
1633 * @return all viewports on the alignment bound to sequenceSetId
1635 public static AlignViewport[] getViewports(String sequenceSetId)
1637 Vector viewp = new Vector();
1638 if (desktop != null)
1640 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1642 for (int t = 0; t < frames.length; t++)
1644 if (frames[t] instanceof AlignFrame)
1646 AlignFrame afr = ((AlignFrame) frames[t]);
1647 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1649 if (afr.alignPanels != null)
1651 for (int a = 0; a < afr.alignPanels.size(); a++)
1653 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1654 .elementAt(a)).av.getSequenceSetId()))
1656 viewp.addElement(((AlignmentPanel) afr.alignPanels
1663 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1668 if (viewp.size() > 0)
1670 AlignViewport[] vp = new AlignViewport[viewp.size()];
1678 public void explodeViews(AlignFrame af)
1680 int size = af.alignPanels.size();
1686 for (int i = 0; i < size; i++)
1688 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1689 AlignFrame newaf = new AlignFrame(ap);
1690 if (ap.av.explodedPosition != null
1691 && !ap.av.explodedPosition.equals(af.getBounds()))
1693 newaf.setBounds(ap.av.explodedPosition);
1696 ap.av.gatherViewsHere = false;
1698 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1699 AlignFrame.DEFAULT_HEIGHT);
1702 af.alignPanels.clear();
1703 af.closeMenuItem_actionPerformed(true);
1707 public void gatherViews(AlignFrame source)
1709 source.viewport.gatherViewsHere = true;
1710 source.viewport.explodedPosition = source.getBounds();
1711 JInternalFrame[] frames = desktop.getAllFrames();
1712 String viewId = source.viewport.getSequenceSetId();
1714 for (int t = 0; t < frames.length; t++)
1716 if (frames[t] instanceof AlignFrame && frames[t] != source)
1718 AlignFrame af = (AlignFrame) frames[t];
1719 boolean gatherThis = false;
1720 for (int a = 0; a < af.alignPanels.size(); a++)
1722 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1723 if (viewId.equals(ap.av.getSequenceSetId()))
1726 ap.av.gatherViewsHere = false;
1727 ap.av.explodedPosition = af.getBounds();
1728 source.addAlignmentPanel(ap, false);
1734 af.alignPanels.clear();
1735 af.closeMenuItem_actionPerformed(true);
1742 jalview.gui.VamsasApplication v_client = null;
1744 public void vamsasImport_actionPerformed(ActionEvent e)
1746 if (v_client == null)
1748 // Load and try to start a session.
1749 JalviewFileChooser chooser = new JalviewFileChooser(
1750 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1752 chooser.setFileView(new JalviewFileView());
1753 chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
1754 chooser.setToolTipText(MessageManager
1755 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1757 int value = chooser.showOpenDialog(this);
1759 if (value == JalviewFileChooser.APPROVE_OPTION)
1761 String fle = chooser.getSelectedFile().toString();
1762 if (!vamsasImport(chooser.getSelectedFile()))
1765 .showInternalMessageDialog(
1767 MessageManager.formatMessage(
1768 "label.couldnt_import_as_vamsas_session",
1772 .getString("label.vamsas_document_import_failed"),
1773 JOptionPane.ERROR_MESSAGE);
1779 jalview.bin.Cache.log
1780 .error("Implementation error - load session from a running session is not supported.");
1785 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1788 * @return true if import was a success and a session was started.
1790 public boolean vamsasImport(URL url)
1792 // TODO: create progress bar
1793 if (v_client != null)
1796 jalview.bin.Cache.log
1797 .error("Implementation error - load session from a running session is not supported.");
1803 // copy the URL content to a temporary local file
1804 // TODO: be a bit cleverer here with nio (?!)
1805 File file = File.createTempFile("vdocfromurl", ".vdj");
1806 FileOutputStream fos = new FileOutputStream(file);
1807 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1808 byte[] buffer = new byte[2048];
1810 while ((ln = bis.read(buffer)) > -1)
1812 fos.write(buffer, 0, ln);
1816 v_client = new jalview.gui.VamsasApplication(this, file,
1817 url.toExternalForm());
1818 } catch (Exception ex)
1820 jalview.bin.Cache.log.error(
1821 "Failed to create new vamsas session from contents of URL "
1825 setupVamsasConnectedGui();
1826 v_client.initial_update(); // TODO: thread ?
1827 return v_client.inSession();
1831 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1834 * @return true if import was a success and a session was started.
1836 public boolean vamsasImport(File file)
1838 if (v_client != null)
1841 jalview.bin.Cache.log
1842 .error("Implementation error - load session from a running session is not supported.");
1846 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1850 v_client = new jalview.gui.VamsasApplication(this, file, null);
1851 } catch (Exception ex)
1853 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1855 jalview.bin.Cache.log.error(
1856 "New vamsas session from existing session file failed:", ex);
1859 setupVamsasConnectedGui();
1860 v_client.initial_update(); // TODO: thread ?
1861 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1863 return v_client.inSession();
1866 public boolean joinVamsasSession(String mysesid)
1868 if (v_client != null)
1870 throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
1872 if (mysesid == null)
1874 throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
1876 v_client = new VamsasApplication(this, mysesid);
1877 setupVamsasConnectedGui();
1878 v_client.initial_update();
1879 return (v_client.inSession());
1882 public void vamsasStart_actionPerformed(ActionEvent e)
1884 if (v_client == null)
1887 // we just start a default session for moment.
1889 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1890 * getProperty("LAST_DIRECTORY"));
1892 * chooser.setFileView(new JalviewFileView());
1893 * chooser.setDialogTitle("Load Vamsas file");
1894 * chooser.setToolTipText("Import");
1896 * int value = chooser.showOpenDialog(this);
1898 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1899 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1901 v_client = new VamsasApplication(this);
1902 setupVamsasConnectedGui();
1903 v_client.initial_update(); // TODO: thread ?
1907 // store current data in session.
1908 v_client.push_update(); // TODO: thread
1912 protected void setupVamsasConnectedGui()
1914 vamsasStart.setText(MessageManager.getString("label.session_update"));
1915 vamsasSave.setVisible(true);
1916 vamsasStop.setVisible(true);
1917 vamsasImport.setVisible(false); // Document import to existing session is
1918 // not possible for vamsas-client-1.0.
1921 protected void setupVamsasDisconnectedGui()
1923 vamsasSave.setVisible(false);
1924 vamsasStop.setVisible(false);
1925 vamsasImport.setVisible(true);
1926 vamsasStart.setText(MessageManager
1927 .getString("label.new_vamsas_session"));
1930 public void vamsasStop_actionPerformed(ActionEvent e)
1932 if (v_client != null)
1934 v_client.end_session();
1936 setupVamsasDisconnectedGui();
1940 protected void buildVamsasStMenu()
1942 if (v_client == null)
1944 String[] sess = null;
1947 sess = VamsasApplication.getSessionList();
1948 } catch (Exception e)
1950 jalview.bin.Cache.log.warn(
1951 "Problem getting current sessions list.", e);
1956 jalview.bin.Cache.log.debug("Got current sessions list: "
1957 + sess.length + " entries.");
1958 VamsasStMenu.removeAll();
1959 for (int i = 0; i < sess.length; i++)
1961 JMenuItem sessit = new JMenuItem();
1962 sessit.setText(sess[i]);
1963 sessit.setToolTipText(MessageManager.formatMessage(
1964 "label.connect_to_session", new String[]
1966 final Desktop dsktp = this;
1967 final String mysesid = sess[i];
1968 sessit.addActionListener(new ActionListener()
1971 public void actionPerformed(ActionEvent e)
1973 if (dsktp.v_client == null)
1975 Thread rthr = new Thread(new Runnable()
1980 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1981 dsktp.setupVamsasConnectedGui();
1982 dsktp.v_client.initial_update();
1990 VamsasStMenu.add(sessit);
1992 // don't show an empty menu.
1993 VamsasStMenu.setVisible(sess.length > 0);
1998 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1999 VamsasStMenu.removeAll();
2000 VamsasStMenu.setVisible(false);
2005 // Not interested in the content. Just hide ourselves.
2006 VamsasStMenu.setVisible(false);
2010 public void vamsasSave_actionPerformed(ActionEvent e)
2012 if (v_client != null)
2014 JalviewFileChooser chooser = new JalviewFileChooser(
2015 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2016 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2018 { "Vamsas Document" }, "Vamsas Document");
2020 chooser.setFileView(new JalviewFileView());
2021 chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
2023 int value = chooser.showSaveDialog(this);
2025 if (value == JalviewFileChooser.APPROVE_OPTION)
2027 java.io.File choice = chooser.getSelectedFile();
2028 JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new String[]{choice.getName()}));
2029 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2030 String warnmsg = null;
2031 String warnttl = null;
2034 v_client.vclient.storeDocument(choice);
2037 warnttl = "Serious Problem saving Vamsas Document";
2038 warnmsg = ex.toString();
2039 jalview.bin.Cache.log.error("Error Whilst saving document to "
2042 } catch (Exception ex)
2044 warnttl = "Problem saving Vamsas Document.";
2045 warnmsg = ex.toString();
2046 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2050 removeProgressPanel(progpanel);
2051 if (warnmsg != null)
2053 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2055 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2061 JPanel vamUpdate = null;
2064 * hide vamsas user gui bits when a vamsas document event is being handled.
2067 * true to hide gui, false to reveal gui
2069 public void setVamsasUpdate(boolean b)
2071 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2072 + (b ? "in progress" : "finished"));
2074 if (vamUpdate != null)
2076 this.removeProgressPanel(vamUpdate);
2080 vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
2082 vamsasStart.setVisible(!b);
2083 vamsasStop.setVisible(!b);
2084 vamsasSave.setVisible(!b);
2087 public JInternalFrame[] getAllFrames()
2089 return desktop.getAllFrames();
2093 * Checks the given url to see if it gives a response indicating that the user
2094 * should be informed of a new questionnaire.
2098 public void checkForQuestionnaire(String url)
2100 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2101 // javax.swing.SwingUtilities.invokeLater(jvq);
2102 new Thread(jvq).start();
2106 * Proxy class for JDesktopPane which optionally displays the current memory
2107 * usage and highlights the desktop area with a red bar if free memory runs
2112 public class MyDesktopPane extends JDesktopPane implements Runnable
2115 boolean showMemoryUsage = false;
2119 java.text.NumberFormat df;
2121 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2124 public MyDesktopPane(boolean showMemoryUsage)
2126 showMemoryUsage(showMemoryUsage);
2129 public void showMemoryUsage(boolean showMemoryUsage)
2131 this.showMemoryUsage = showMemoryUsage;
2132 if (showMemoryUsage)
2134 Thread worker = new Thread(this);
2139 public boolean isShowMemoryUsage()
2141 return showMemoryUsage;
2146 df = java.text.NumberFormat.getNumberInstance();
2147 df.setMaximumFractionDigits(2);
2148 runtime = Runtime.getRuntime();
2150 while (showMemoryUsage)
2154 maxMemory = runtime.maxMemory() / 1048576f;
2155 allocatedMemory = runtime.totalMemory() / 1048576f;
2156 freeMemory = runtime.freeMemory() / 1048576f;
2157 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2159 percentUsage = (totalFreeMemory / maxMemory) * 100;
2161 // if (percentUsage < 20)
2163 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2165 // instance.set.setBorder(border1);
2168 // sleep after showing usage
2170 } catch (Exception ex)
2172 ex.printStackTrace();
2177 public void paintComponent(Graphics g)
2179 if (showMemoryUsage && g != null && df != null)
2181 if (percentUsage < 20)
2183 g.setColor(Color.red);
2185 FontMetrics fm = g.getFontMetrics();
2188 g.drawString(MessageManager.formatMessage(
2189 "label.memory_stats",
2191 { df.format(totalFreeMemory), df.format(maxMemory),
2192 df.format(percentUsage) }), 10,
2193 getHeight() - fm.getHeight());
2200 * fixes stacking order after a modal dialog to ensure windows that should be
2201 * on top actually are
2203 public void relayerWindows()
2208 protected JMenuItem groovyShell;
2210 public void doGroovyCheck()
2212 if (jalview.bin.Cache.groovyJarsPresent())
2214 groovyShell = new JMenuItem();
2215 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2216 groovyShell.addActionListener(new ActionListener()
2218 public void actionPerformed(ActionEvent e)
2220 groovyShell_actionPerformed(e);
2223 toolsMenu.add(groovyShell);
2224 groovyShell.setVisible(true);
2229 * Accessor method to quickly get all the AlignmentFrames loaded.
2231 public static AlignFrame[] getAlignframes()
2233 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2239 Vector avp = new Vector();
2243 for (int i = frames.length - 1; i > -1; i--)
2245 if (frames[i] instanceof AlignFrame)
2247 AlignFrame af = (AlignFrame) frames[i];
2251 } catch (Exception ex)
2253 ex.printStackTrace();
2255 if (avp.size() == 0)
2259 AlignFrame afs[] = new AlignFrame[avp.size()];
2260 for (int i = 0, j = avp.size(); i < j; i++)
2262 afs[i] = (AlignFrame) avp.elementAt(i);
2268 public AppJmol[] getJmols()
2270 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2276 Vector avp = new Vector();
2280 for (int i = frames.length - 1; i > -1; i--)
2282 if (frames[i] instanceof AppJmol)
2284 AppJmol af = (AppJmol) frames[i];
2288 } catch (Exception ex)
2290 ex.printStackTrace();
2292 if (avp.size() == 0)
2296 AppJmol afs[] = new AppJmol[avp.size()];
2297 for (int i = 0, j = avp.size(); i < j; i++)
2299 afs[i] = (AppJmol) avp.elementAt(i);
2306 * Add Groovy Support to Jalview
2308 public void groovyShell_actionPerformed(ActionEvent e)
2310 // use reflection to avoid creating compilation dependency.
2311 if (!jalview.bin.Cache.groovyJarsPresent())
2313 throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
2317 Class gcClass = Desktop.class.getClassLoader().loadClass(
2318 "groovy.ui.Console");
2319 Constructor gccons = gcClass.getConstructor(null);
2320 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2322 { String.class, Object.class });
2323 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2324 Object gc = gccons.newInstance(null);
2325 setvar.invoke(gc, new Object[]
2326 { "Jalview", this });
2327 run.invoke(gc, null);
2328 } catch (Exception ex)
2330 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2332 .showInternalMessageDialog(
2335 MessageManager.getString("label.couldnt_create_groovy_shell"),
2336 MessageManager.getString("label.groovy_support_failed"),
2337 JOptionPane.ERROR_MESSAGE);
2342 * Progress bars managed by the IProgressIndicator method.
2344 private Hashtable<Long, JPanel> progressBars;
2346 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2351 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2353 public void setProgressBar(String message, long id)
2355 if (progressBars == null)
2357 progressBars = new Hashtable<Long, JPanel>();
2358 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2361 if (progressBars.get(new Long(id)) != null)
2363 JPanel progressPanel = progressBars.remove(new Long(id));
2364 if (progressBarHandlers.contains(new Long(id)))
2366 progressBarHandlers.remove(new Long(id));
2368 removeProgressPanel(progressPanel);
2372 progressBars.put(new Long(id), addProgressPanel(message));
2379 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2380 * jalview.gui.IProgressIndicatorHandler)
2382 public void registerHandler(final long id,
2383 final IProgressIndicatorHandler handler)
2385 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2387 throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
2389 progressBarHandlers.put(new Long(id), handler);
2390 final JPanel progressPanel = progressBars.get(new Long(id));
2391 if (handler.canCancel())
2393 JButton cancel = new JButton(
2394 MessageManager.getString("action.cancel"));
2395 final IProgressIndicator us = this;
2396 cancel.addActionListener(new ActionListener()
2399 public void actionPerformed(ActionEvent e)
2401 handler.cancelActivity(id);
2402 us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
2405 progressPanel.add(cancel, BorderLayout.EAST);
2411 * @return true if any progress bars are still active
2414 public boolean operationInProgress()
2416 if (progressBars != null && progressBars.size() > 0)
2424 * This will return the first AlignFrame viewing AlignViewport av. It will
2425 * break if there are more than one AlignFrames viewing a particular av. This
2428 * @return alignFrame for av
2430 public static AlignFrame getAlignFrameFor(AlignViewport av)
2432 if (desktop != null)
2434 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2435 for (int panel = 0; aps != null && panel < aps.length; panel++)
2437 if (aps[panel] != null && aps[panel].av == av)
2439 return aps[panel].alignFrame;
2446 public VamsasApplication getVamsasApplication()
2453 * flag set if jalview GUI is being operated programmatically
2455 private boolean inBatchMode = false;
2458 * check if jalview GUI is being operated programmatically
2460 * @return inBatchMode
2462 public boolean isInBatchMode()
2468 * set flag if jalview GUI is being operated programmatically
2470 * @param inBatchMode
2472 public void setInBatchMode(boolean inBatchMode)
2474 this.inBatchMode = inBatchMode;
2477 public void startServiceDiscovery()
2479 startServiceDiscovery(false);
2482 public void startServiceDiscovery(boolean blocking)
2484 boolean alive = true;
2485 Thread t0 = null, t1 = null, t2 = null;
2486 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2489 // todo: changesupport handlers need to be transferred
2490 if (discoverer == null)
2492 discoverer = new jalview.ws.jws1.Discoverer();
2493 // register PCS handler for desktop.
2494 discoverer.addPropertyChangeListener(changeSupport);
2496 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2497 // until we phase out completely
2498 (t0 = new Thread(discoverer)).start();
2501 // ENFIN services are EOLed as of Jalview 2.8.1 release
2506 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2508 // EnfinEnvision web service menu entries are rebuild every time the
2509 // menu is shown, so no changeSupport events are needed.
2510 jalview.ws.EnfinEnvision2OneWay.getInstance();
2511 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2514 } catch (Exception e)
2517 .info("Exception when trying to launch Envision2 workflow discovery.",
2519 Cache.log.info(e.getStackTrace());
2523 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2525 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2527 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2529 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2535 // TODO: do rest service discovery
2544 } catch (Exception e)
2547 alive = (t1 != null && t1.isAlive())
2548 || (t2 != null && t2.isAlive())
2549 || (t3 != null && t3.isAlive())
2550 || (t0 != null && t0.isAlive());
2556 * called to check if the service discovery process completed successfully.
2560 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2562 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2564 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2565 .getErrorMessages();
2568 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2570 if (serviceChangedDialog == null)
2572 // only run if we aren't already displaying one of these.
2573 addDialogThread(serviceChangedDialog = new Runnable()
2579 * JalviewDialog jd =new JalviewDialog() {
2581 * @Override protected void cancelPressed() { // TODO
2582 * Auto-generated method stub
2584 * }@Override protected void okPressed() { // TODO
2585 * Auto-generated method stub
2587 * }@Override protected void raiseClosed() { // TODO
2588 * Auto-generated method stub
2590 * } }; jd.initDialogFrame(new
2591 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2592 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2593 * + " or mis-configured HTTP proxy settings.<br/>" +
2594 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2596 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2597 * ), true, true, "Web Service Configuration Problem", 450,
2600 * jd.waitForInput();
2606 "<html><table width=\"450\"><tr><td>"
2608 + "</td></tr></table>"
2609 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2610 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2611 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2612 + " Tools->Preferences dialog box to change them.</p></html>"),
2613 "Web Service Configuration Problem",
2614 JOptionPane.DEFAULT_OPTION,
2615 JOptionPane.ERROR_MESSAGE);
2616 serviceChangedDialog = null;
2625 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2632 private Runnable serviceChangedDialog = null;
2635 * start a thread to open a URL in the configured browser. Pops up a warning
2636 * dialog to the user if there is an exception when calling out to the browser
2641 public static void showUrl(final String url)
2643 showUrl(url, Desktop.instance);
2647 * Like showUrl but allows progress handler to be specified
2651 * (null) or object implementing IProgressIndicator
2653 public static void showUrl(final String url,
2654 final IProgressIndicator progress)
2656 new Thread(new Runnable()
2662 if (progress != null)
2664 progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new String[]{url}), this.hashCode());
2666 jalview.util.BrowserLauncher.openURL(url);
2667 } catch (Exception ex)
2670 .showInternalMessageDialog(
2672 MessageManager.getString("label.web_browser_not_found_unix"),
2673 MessageManager.getString("label.web_browser_not_found"),
2674 JOptionPane.WARNING_MESSAGE);
2676 ex.printStackTrace();
2678 if (progress != null)
2680 progress.setProgressBar(null, this.hashCode());
2686 public static WsParamSetManager wsparamManager = null;
2688 public static ParamManager getUserParameterStore()
2690 if (wsparamManager == null)
2692 wsparamManager = new WsParamSetManager();
2694 return wsparamManager;
2698 * static hyperlink handler proxy method for use by Jalview's internal windows
2702 public static void hyperlinkUpdate(HyperlinkEvent e)
2704 if (e.getEventType() == EventType.ACTIVATED)
2709 url = e.getURL().toString();
2710 Desktop.showUrl(url);
2711 } catch (Exception x)
2715 if (Cache.log != null)
2717 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2721 System.err.println("Couldn't handle string " + url
2725 // ignore any exceptions due to dud links.
2732 * single thread that handles display of dialogs to user.
2734 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2737 * flag indicating if dialogExecutor should try to acquire a permit
2739 private volatile boolean dialogPause = true;
2744 private java.util.concurrent.Semaphore block = new Semaphore(0);
2747 * add another dialog thread to the queue
2751 public void addDialogThread(final Runnable prompter)
2753 dialogExecutor.submit(new Runnable()
2762 } catch (InterruptedException x)
2767 if (instance == null)
2773 SwingUtilities.invokeAndWait(prompter);
2774 } catch (Exception q)
2776 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2782 public void startDialogQueue()
2784 // set the flag so we don't pause waiting for another permit and semaphore
2785 // the current task to begin
2786 dialogPause = false;
2790 protected void snapShotWindow_actionPerformed(ActionEvent e)
2794 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2795 "View of Desktop", getWidth(), getHeight(), of = new File(
2796 "Jalview_snapshot" + System.currentTimeMillis()
2797 + ".eps"), "View of desktop");
2799 paintAll(im.getGraphics());
2801 } catch (Exception q)
2803 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2806 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());