2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
20 import jalview.bin.Cache;
21 import jalview.io.FileLoader;
22 import jalview.io.FormatAdapter;
23 import jalview.io.IdentifyFile;
24 import jalview.io.JalviewFileChooser;
25 import jalview.io.JalviewFileView;
26 import jalview.ws.params.ParamManager;
28 import java.awt.BorderLayout;
29 import java.awt.Color;
30 import java.awt.Dimension;
31 import java.awt.FontMetrics;
32 import java.awt.Graphics;
33 import java.awt.GridLayout;
34 import java.awt.Point;
35 import java.awt.Rectangle;
36 import java.awt.Toolkit;
37 import java.awt.datatransfer.Clipboard;
38 import java.awt.datatransfer.ClipboardOwner;
39 import java.awt.datatransfer.DataFlavor;
40 import java.awt.datatransfer.Transferable;
41 import java.awt.dnd.DnDConstants;
42 import java.awt.dnd.DropTargetDragEvent;
43 import java.awt.dnd.DropTargetDropEvent;
44 import java.awt.dnd.DropTargetEvent;
45 import java.awt.dnd.DropTargetListener;
46 import java.awt.event.ActionEvent;
47 import java.awt.event.ActionListener;
48 import java.awt.event.FocusEvent;
49 import java.awt.event.FocusListener;
50 import java.awt.event.MouseAdapter;
51 import java.awt.event.MouseEvent;
52 import java.awt.event.MouseListener;
53 import java.awt.event.WindowAdapter;
54 import java.awt.event.WindowEvent;
55 import java.beans.PropertyChangeEvent;
56 import java.beans.PropertyChangeListener;
57 import java.beans.PropertyVetoException;
58 import java.io.BufferedInputStream;
60 import java.io.FileOutputStream;
61 import java.lang.reflect.Constructor;
63 import java.util.ArrayList;
64 import java.util.Hashtable;
65 import java.util.StringTokenizer;
66 import java.util.Vector;
68 import javax.swing.DefaultDesktopManager;
69 import javax.swing.DesktopManager;
70 import javax.swing.JButton;
71 import javax.swing.JComboBox;
72 import javax.swing.JComponent;
73 import javax.swing.JDesktopPane;
74 import javax.swing.JFrame;
75 import javax.swing.JInternalFrame;
76 import javax.swing.JLabel;
77 import javax.swing.JMenuItem;
78 import javax.swing.JOptionPane;
79 import javax.swing.JPanel;
80 import javax.swing.JPopupMenu;
81 import javax.swing.JProgressBar;
82 import javax.swing.SwingUtilities;
83 import javax.swing.event.MenuEvent;
84 import javax.swing.event.MenuListener;
91 * @version $Revision: 1.155 $
93 public class Desktop extends jalview.jbgui.GDesktop implements
94 DropTargetListener, ClipboardOwner, IProgressIndicator, jalview.api.StructureSelectionManagerProvider
97 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
100 * news reader - null if it was never started.
102 private BlogReader jvnews=null;
106 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
108 public void addJalviewPropertyChangeListener(
109 PropertyChangeListener listener)
111 changeSupport.addJalviewPropertyChangeListener(listener);
115 * @param propertyName
117 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
118 * java.beans.PropertyChangeListener)
120 public void addJalviewPropertyChangeListener(String propertyName,
121 PropertyChangeListener listener)
123 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
127 * @param propertyName
129 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
130 * java.beans.PropertyChangeListener)
132 public void removeJalviewPropertyChangeListener(String propertyName,
133 PropertyChangeListener listener)
135 changeSupport.removeJalviewPropertyChangeListener(propertyName,
139 /** Singleton Desktop instance */
140 public static Desktop instance;
142 public static MyDesktopPane desktop;
144 static int openFrameCount = 0;
146 static final int xOffset = 30;
148 static final int yOffset = 30;
150 public static jalview.ws.jws1.Discoverer discoverer;
152 public static Object[] jalviewClipboard;
154 public static boolean internalCopy = false;
156 static int fileLoadingCount = 0;
158 class MyDesktopManager implements DesktopManager
161 private DesktopManager delegate;
163 public MyDesktopManager(DesktopManager delegate)
165 this.delegate = delegate;
168 public void activateFrame(JInternalFrame f)
172 delegate.activateFrame(f);
173 } catch (NullPointerException npe)
175 Point p = getMousePosition();
176 instance.showPasteMenu(p.x, p.y);
180 public void beginDraggingFrame(JComponent f)
182 delegate.beginDraggingFrame(f);
185 public void beginResizingFrame(JComponent f, int direction)
187 delegate.beginResizingFrame(f, direction);
190 public void closeFrame(JInternalFrame f)
192 delegate.closeFrame(f);
195 public void deactivateFrame(JInternalFrame f)
197 delegate.deactivateFrame(f);
200 public void deiconifyFrame(JInternalFrame f)
202 delegate.deiconifyFrame(f);
205 public void dragFrame(JComponent f, int newX, int newY)
207 delegate.dragFrame(f, newX, newY);
210 public void endDraggingFrame(JComponent f)
212 delegate.endDraggingFrame(f);
215 public void endResizingFrame(JComponent f)
217 delegate.endResizingFrame(f);
220 public void iconifyFrame(JInternalFrame f)
222 delegate.iconifyFrame(f);
225 public void maximizeFrame(JInternalFrame f)
227 delegate.maximizeFrame(f);
230 public void minimizeFrame(JInternalFrame f)
232 delegate.minimizeFrame(f);
235 public void openFrame(JInternalFrame f)
237 delegate.openFrame(f);
240 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
243 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
246 public void setBoundsForFrame(JComponent f, int newX, int newY,
247 int newWidth, int newHeight)
249 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
252 // All other methods, simply delegate
257 * Creates a new Desktop object.
262 * A note to implementors. It is ESSENTIAL that any activities that might
263 * block are spawned off as threads rather than waited for during this
267 doVamsasClientCheck();
270 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
271 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
272 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
274 boolean showjconsole = jalview.bin.Cache.getDefault(
275 "SHOW_JAVA_CONSOLE", false);
276 desktop = new MyDesktopPane(selmemusage);
277 showMemusage.setSelected(selmemusage);
278 desktop.setBackground(Color.white);
279 getContentPane().setLayout(new BorderLayout());
280 // alternate config - have scrollbars - see notes in JAL-153
281 //JScrollPane sp = new JScrollPane();
282 //sp.getViewport().setView(desktop);
283 //getContentPane().add(sp, BorderLayout.CENTER);
284 getContentPane().add(desktop, BorderLayout.CENTER);
285 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
287 // This line prevents Windows Look&Feel resizing all new windows to maximum
288 // if previous window was maximised
289 desktop.setDesktopManager(new MyDesktopManager(
290 new DefaultDesktopManager()));
291 Rectangle dims = getLastKnownDimensions("");
298 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
299 setBounds((int) (screenSize.width - 900) / 2,
300 (int) (screenSize.height - 650) / 2, 900, 650);
302 jconsole = new Console(this, showjconsole);
303 // add essential build information
304 jconsole.setHeader("Jalview Desktop "
305 + jalview.bin.Cache.getProperty("VERSION") + "\n"
307 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
308 + "Java version: " + System.getProperty("java.version") + "\n"
309 + System.getProperty("os.arch") + " "
310 + System.getProperty("os.name") + " "
311 + System.getProperty("os.version"));
313 showConsole(showjconsole);
315 showNews.setVisible(false);
316 final Desktop me = this;
317 // Thread off the news reader, in case there are connection problems.
318 new Thread( new Runnable() {
322 Cache.log.debug("Starting news thread.");
324 jvnews = new BlogReader(me);
325 showNews.setVisible(true);
326 Cache.log.debug("Completed news thread.");
330 this.addWindowListener(new WindowAdapter()
332 public void windowClosing(WindowEvent evt)
339 this.addMouseListener(ma=new MouseAdapter()
341 public void mousePressed(MouseEvent evt)
343 if (SwingUtilities.isRightMouseButton(evt))
345 showPasteMenu(evt.getX(), evt.getY());
349 desktop.addMouseListener(ma);
351 this.addFocusListener(new FocusListener()
355 public void focusLost(FocusEvent e)
357 // TODO Auto-generated method stub
362 public void focusGained(FocusEvent e)
364 Cache.log.debug("Relaying windows after focus gain");
365 // make sure that we sort windows properly after we gain focus
366 instance.relayerWindows();
369 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
370 // Spawn a thread that shows the splashscreen
371 SwingUtilities.invokeLater(new Runnable()
380 // Thread off a new instance of the file chooser - this reduces the time it
381 // takes to open it later on.
382 new Thread(new Runnable()
386 Cache.log.debug("Filechooser init thread started.");
387 JalviewFileChooser chooser = new JalviewFileChooser(
388 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
389 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
390 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
391 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
392 Cache.log.debug("Filechooser init thread finished.");
395 // Add the service change listener
396 changeSupport.addJalviewPropertyChangeListener("services",
397 new PropertyChangeListener()
401 public void propertyChange(PropertyChangeEvent evt)
403 Cache.log.debug("Firing service changed event for "
404 + evt.getNewValue());
405 JalviewServicesChanged(evt);
411 protected void showNews_actionPerformed(ActionEvent e)
413 showNews(showNews.isSelected());
415 void showNews(boolean visible)
418 Cache.log.debug((visible?"Showing":"Hiding")+" news.");
419 showNews.setSelected(visible);
420 if (visible && !jvnews.isVisible())
422 new Thread(new Runnable() {
426 long instance=System.currentTimeMillis();
427 Desktop.instance.setProgressBar("Refreshing news", instance);
428 jvnews.refreshNews();
429 Desktop.instance.setProgressBar(null, instance);
438 * recover the last known dimensions for a jalview window
441 * - empty string is desktop, all other windows have unique prefix
442 * @return null or last known dimensions scaled to current geometry (if last
443 * window geom was known)
445 Rectangle getLastKnownDimensions(String windowName)
447 // TODO: lock aspect ratio for scaling desktop Bug #0058199
448 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
449 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
450 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
451 String width = jalview.bin.Cache.getProperty(windowName
453 String height = jalview.bin.Cache.getProperty(windowName
455 if ((x != null) && (y != null) && (width != null) && (height != null))
457 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
458 .parseInt(width), ih = Integer.parseInt(height);
459 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
461 // attempt #1 - try to cope with change in screen geometry - this
462 // version doesn't preserve original jv aspect ratio.
463 // take ratio of current screen size vs original screen size.
464 double sw = ((1f * screenSize.width) / (1f * Integer
465 .parseInt(jalview.bin.Cache
466 .getProperty("SCREENGEOMETRY_WIDTH"))));
467 double sh = ((1f * screenSize.height) / (1f * Integer
468 .parseInt(jalview.bin.Cache
469 .getProperty("SCREENGEOMETRY_HEIGHT"))));
470 // rescale the bounds depending upon the current screen geometry.
471 ix = (int) (ix * sw);
472 iw = (int) (iw * sw);
473 iy = (int) (iy * sh);
474 ih = (int) (ih * sh);
475 while (ix >= screenSize.width)
477 jalview.bin.Cache.log
478 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
479 ix -= screenSize.width;
481 while (iy >= screenSize.height)
483 jalview.bin.Cache.log
484 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
485 iy -= screenSize.height;
487 jalview.bin.Cache.log.debug("Got last known dimensions for "
488 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
491 // return dimensions for new instance
492 return new Rectangle(ix, iy, iw, ih);
497 private void doVamsasClientCheck()
499 if (jalview.bin.Cache.vamsasJarsPresent())
501 setupVamsasDisconnectedGui();
502 VamsasMenu.setVisible(true);
503 final Desktop us = this;
504 VamsasMenu.addMenuListener(new MenuListener()
506 // this listener remembers when the menu was first selected, and
507 // doesn't rebuild the session list until it has been cleared and
509 boolean refresh = true;
511 public void menuCanceled(MenuEvent e)
516 public void menuDeselected(MenuEvent e)
521 public void menuSelected(MenuEvent e)
525 us.buildVamsasStMenu();
530 vamsasStart.setVisible(true);
534 void showPasteMenu(int x, int y)
536 JPopupMenu popup = new JPopupMenu();
537 JMenuItem item = new JMenuItem("Paste To New Window");
538 item.addActionListener(new ActionListener()
540 public void actionPerformed(ActionEvent evt)
547 popup.show(this, x, y);
554 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
555 Transferable contents = c.getContents(this);
557 if (contents != null)
559 String file = (String) contents
560 .getTransferData(DataFlavor.stringFlavor);
562 String format = new IdentifyFile().Identify(file,
563 FormatAdapter.PASTE);
565 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
568 } catch (Exception ex)
571 .println("Unable to paste alignment from system clipboard:\n"
577 * Adds and opens the given frame to the desktop
588 public static synchronized void addInternalFrame(
589 final JInternalFrame frame, String title, int w, int h)
591 addInternalFrame(frame, title, w, h, true);
608 public static synchronized void addInternalFrame(
609 final JInternalFrame frame, String title, int w, int h,
613 // TODO: allow callers to determine X and Y position of frame (eg. via
615 // TODO: consider fixing method to update entries in the window submenu with
616 // the current window title
618 frame.setTitle(title);
619 if (frame.getWidth() < 1 || frame.getHeight() < 1)
623 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
624 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
625 // IF JALVIEW IS RUNNING HEADLESS
626 // ///////////////////////////////////////////////
627 if (System.getProperty("java.awt.headless") != null
628 && System.getProperty("java.awt.headless").equals("true"))
635 frame.setVisible(true);
636 frame.setClosable(true);
637 frame.setResizable(resizable);
638 frame.setMaximizable(resizable);
639 frame.setIconifiable(resizable);
640 frame.setFrameIcon(null);
642 if (frame.getX() < 1 && frame.getY() < 1)
644 frame.setLocation(xOffset * openFrameCount, yOffset
645 * ((openFrameCount - 1) % 10) + yOffset);
648 final JMenuItem menuItem = new JMenuItem(title);
649 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
651 public void internalFrameActivated(
652 javax.swing.event.InternalFrameEvent evt)
654 JInternalFrame itf = desktop.getSelectedFrame();
662 public void internalFrameClosed(
663 javax.swing.event.InternalFrameEvent evt)
665 PaintRefresher.RemoveComponent(frame);
667 windowMenu.remove(menuItem);
668 JInternalFrame itf = desktop.getSelectedFrame();
677 menuItem.addActionListener(new ActionListener()
679 public void actionPerformed(ActionEvent e)
683 frame.setSelected(true);
684 frame.setIcon(false);
685 } catch (java.beans.PropertyVetoException ex)
691 menuItem.addMouseListener(new MouseListener()
695 public void mouseReleased(MouseEvent e)
700 public void mousePressed(MouseEvent e)
705 public void mouseExited(MouseEvent e)
709 frame.setSelected(false);
710 } catch (PropertyVetoException e1)
716 public void mouseEntered(MouseEvent e)
720 frame.setSelected(true);
721 } catch (PropertyVetoException e1)
727 public void mouseClicked(MouseEvent e)
733 windowMenu.add(menuItem);
739 frame.setSelected(true);
740 frame.requestFocus();
741 } catch (java.beans.PropertyVetoException ve)
744 catch (java.lang.ClassCastException cex)
746 Cache.log.warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",cex);
750 public void lostOwnership(Clipboard clipboard, Transferable contents)
754 Desktop.jalviewClipboard = null;
757 internalCopy = false;
760 public void dragEnter(DropTargetDragEvent evt)
764 public void dragExit(DropTargetEvent evt)
768 public void dragOver(DropTargetDragEvent evt)
772 public void dropActionChanged(DropTargetDragEvent evt)
782 public void drop(DropTargetDropEvent evt)
784 Transferable t = evt.getTransferable();
785 java.util.List files = null;
786 java.util.List protocols = null;
790 DataFlavor uriListFlavor = new DataFlavor(
791 "text/uri-list;class=java.lang.String");
792 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
794 // Works on Windows and MacOSX
795 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
796 files = (java.util.List) t
797 .getTransferData(DataFlavor.javaFileListFlavor);
799 else if (t.isDataFlavorSupported(uriListFlavor))
801 // This is used by Unix drag system
802 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
803 String data = (String) t.getTransferData(uriListFlavor);
804 files = new java.util.ArrayList(1);
805 protocols = new java.util.ArrayList(1);
806 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
807 data, "\r\n"); st.hasMoreTokens();)
809 String s = st.nextToken();
810 if (s.startsWith("#"))
812 // the line is a comment (as per the RFC 2483)
815 java.net.URI uri = new java.net.URI(s);
816 if (uri.getScheme().toLowerCase().startsWith("http"))
818 protocols.add(FormatAdapter.URL);
819 files.add(uri.toString());
823 // otherwise preserve old behaviour: catch all for file objects
824 java.io.File file = new java.io.File(uri);
825 protocols.add(FormatAdapter.FILE);
826 files.add(file.toString());
830 } catch (Exception e)
838 for (int i = 0; i < files.size(); i++)
840 String file = files.get(i).toString();
841 String protocol = (protocols == null) ? FormatAdapter.FILE
842 : (String) protocols.get(i);
843 String format = null;
845 if (file.endsWith(".jar"))
852 format = new IdentifyFile().Identify(file, protocol);
855 new FileLoader().LoadFile(file, protocol, format);
858 } catch (Exception ex)
870 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
872 JalviewFileChooser chooser = new JalviewFileChooser(
873 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
874 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
875 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
876 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
878 chooser.setFileView(new JalviewFileView());
879 chooser.setDialogTitle("Open local file");
880 chooser.setToolTipText("Open");
882 int value = chooser.showOpenDialog(this);
884 if (value == JalviewFileChooser.APPROVE_OPTION)
886 String choice = chooser.getSelectedFile().getPath();
887 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
888 .getSelectedFile().getParent());
890 String format = null;
891 if (chooser.getSelectedFormat().equals("Jalview"))
897 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
900 if (viewport != null)
902 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
907 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
918 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
920 // This construct allows us to have a wider textfield
922 JLabel label = new JLabel("Enter URL of Input File");
923 final JComboBox history = new JComboBox();
925 JPanel panel = new JPanel(new GridLayout(2, 1));
928 history.setPreferredSize(new Dimension(400, 20));
929 history.setEditable(true);
930 history.addItem("http://www.");
932 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
936 if (historyItems != null)
938 st = new StringTokenizer(historyItems, "\t");
940 while (st.hasMoreTokens())
942 history.addItem(st.nextElement());
946 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
947 "Input Alignment From URL", JOptionPane.OK_CANCEL_OPTION);
949 if (reply != JOptionPane.OK_OPTION)
954 String url = history.getSelectedItem().toString();
956 if (url.toLowerCase().endsWith(".jar"))
958 if (viewport != null)
960 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
965 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
970 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
972 if (format.equals("URL NOT FOUND"))
974 JOptionPane.showInternalMessageDialog(Desktop.desktop,
975 "Couldn't locate " + url, "URL not found",
976 JOptionPane.WARNING_MESSAGE);
981 if (viewport != null)
983 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
987 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
998 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1000 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1001 cap.setForInput(viewport);
1002 Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
1010 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1012 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1013 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1015 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1016 getBounds().y, getWidth(), getHeight()));
1018 if (jconsole != null)
1020 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1021 jconsole.stopConsole();
1025 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1032 private void storeLastKnownDimensions(String string, Rectangle jc)
1034 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1035 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1036 + " height:" + jc.height);
1038 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1039 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1040 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1041 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1050 public void aboutMenuItem_actionPerformed(ActionEvent e)
1052 StringBuffer message = getAboutMessage(false);
1053 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1055 message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1057 public StringBuffer getAboutMessage(boolean shortv)
1059 StringBuffer message=new StringBuffer();
1060 message.append("<html>");
1063 message.append("<h1><strong>Jalview "
1064 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1><br>");
1065 message.append("<strong>Last Updated: <em>"+jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")+"</em></strong>");
1069 message.append("<strong>Jalview version "
1070 + jalview.bin.Cache.getProperty("VERSION") + "; last updated: "
1071 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1074 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1077 message.append("<br>...Checking latest version...</br>");
1079 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1080 .equals(jalview.bin.Cache.getProperty("VERSION")))
1083 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1084 .indexOf("automated build") == -1)
1087 // Displayed when code version and jnlp version do not match and code
1088 // version is not a development build
1089 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1092 message.append("<br>!! Jalview version "
1093 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1095 + " is available for download from "+jalview.bin.Cache.getDefault("www.jalview.org","http://www.jalview.org")+" !!");
1097 message.append("</div>");
1100 message.append("<br>Authors: "+jalview.bin.Cache.getDefault("AUTHORNAMES","Jim Procter, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton")
1101 + "<br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1102 + "<br>For help, see the FAQ at www.jalview.org and/or join the jalview-discuss@jalview.org mailing list"
1103 + "<br>If you use Jalview, please cite:"
1104 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1105 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1106 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1117 public void documentationMenuItem_actionPerformed(ActionEvent e)
1121 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
1122 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
1123 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
1125 javax.help.HelpBroker hb = hs.createHelpBroker();
1126 hb.setCurrentID("home");
1127 hb.setDisplayed(true);
1128 } catch (Exception ex)
1133 public void closeAll_actionPerformed(ActionEvent e)
1135 JInternalFrame[] frames = desktop.getAllFrames();
1136 for (int i = 0; i < frames.length; i++)
1140 frames[i].setClosed(true);
1141 } catch (java.beans.PropertyVetoException ex)
1145 System.out.println("ALL CLOSED");
1146 if (v_client != null)
1148 // TODO clear binding to vamsas document objects on close_all
1153 public void raiseRelated_actionPerformed(ActionEvent e)
1155 reorderAssociatedWindows(false, false);
1158 public void minimizeAssociated_actionPerformed(ActionEvent e)
1160 reorderAssociatedWindows(true, false);
1163 void closeAssociatedWindows()
1165 reorderAssociatedWindows(false, true);
1171 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1174 protected void garbageCollect_actionPerformed(ActionEvent e)
1176 // We simply collect the garbage
1177 jalview.bin.Cache.log.debug("Collecting garbage...");
1179 jalview.bin.Cache.log.debug("Finished garbage collection.");
1186 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1189 protected void showMemusage_actionPerformed(ActionEvent e)
1191 desktop.showMemoryUsage(showMemusage.isSelected());
1198 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1201 protected void showConsole_actionPerformed(ActionEvent e)
1203 showConsole(showConsole.isSelected());
1206 Console jconsole = null;
1209 * control whether the java console is visible or not
1213 void showConsole(boolean selected)
1215 showConsole.setSelected(selected);
1216 // TODO: decide if we should update properties file
1217 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1219 jconsole.setVisible(selected);
1222 void reorderAssociatedWindows(boolean minimize, boolean close)
1224 JInternalFrame[] frames = desktop.getAllFrames();
1225 if (frames == null || frames.length < 1)
1230 AlignViewport source = null, target = null;
1231 if (frames[0] instanceof AlignFrame)
1233 source = ((AlignFrame) frames[0]).getCurrentView();
1235 else if (frames[0] instanceof TreePanel)
1237 source = ((TreePanel) frames[0]).getViewPort();
1239 else if (frames[0] instanceof PCAPanel)
1241 source = ((PCAPanel) frames[0]).av;
1243 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1245 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1250 for (int i = 0; i < frames.length; i++)
1253 if (frames[i] == null)
1257 if (frames[i] instanceof AlignFrame)
1259 target = ((AlignFrame) frames[i]).getCurrentView();
1261 else if (frames[i] instanceof TreePanel)
1263 target = ((TreePanel) frames[i]).getViewPort();
1265 else if (frames[i] instanceof PCAPanel)
1267 target = ((PCAPanel) frames[i]).av;
1269 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1271 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1274 if (source == target)
1280 frames[i].setClosed(true);
1284 frames[i].setIcon(minimize);
1287 frames[i].toFront();
1291 } catch (java.beans.PropertyVetoException ex)
1305 protected void preferences_actionPerformed(ActionEvent e)
1316 public void saveState_actionPerformed(ActionEvent e)
1318 JalviewFileChooser chooser = new JalviewFileChooser(
1319 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1320 { "jar" }, new String[]
1321 { "Jalview Project" }, "Jalview Project");
1323 chooser.setFileView(new JalviewFileView());
1324 chooser.setDialogTitle("Save State");
1326 int value = chooser.showSaveDialog(this);
1328 if (value == JalviewFileChooser.APPROVE_OPTION)
1330 final Desktop me = this;
1331 final java.io.File choice = chooser.getSelectedFile();
1332 new Thread(new Runnable()
1337 setProgressBar("Saving jalview project " + choice.getName(),
1339 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1340 // TODO catch and handle errors for savestate
1341 // TODO prevent user from messing with the Desktop whilst we're saving
1344 new Jalview2XML().SaveState(choice);
1345 } catch (OutOfMemoryError oom)
1348 "Whilst saving current state to " + choice.getName(), oom);
1349 } catch (Exception ex)
1352 .error("Problems whilst trying to save to "
1353 + choice.getName(), ex);
1354 JOptionPane.showMessageDialog(me,
1355 "Error whilst saving current state to " + choice.getName(),
1356 "Couldn't save project", JOptionPane.WARNING_MESSAGE);
1358 setProgressBar(null, choice.hashCode());
1370 public void loadState_actionPerformed(ActionEvent e)
1372 JalviewFileChooser chooser = new JalviewFileChooser(
1373 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1374 { "jar" }, new String[]
1375 { "Jalview Project" }, "Jalview Project");
1376 chooser.setFileView(new JalviewFileView());
1377 chooser.setDialogTitle("Restore state");
1379 int value = chooser.showOpenDialog(this);
1381 if (value == JalviewFileChooser.APPROVE_OPTION)
1383 final String choice = chooser.getSelectedFile().getAbsolutePath();
1384 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1385 .getSelectedFile().getParent());
1386 new Thread(new Runnable()
1390 setProgressBar("loading jalview project " + choice,
1394 new Jalview2XML().LoadJalviewAlign(choice);
1395 } catch (OutOfMemoryError oom)
1397 new OOMWarning("Whilst loading project from " + choice, oom);
1398 } catch (Exception ex)
1400 Cache.log.error("Problems whilst loading project from "
1402 JOptionPane.showMessageDialog(Desktop.desktop,
1403 "Error whilst loading project from " + choice,
1404 "Couldn't load project", JOptionPane.WARNING_MESSAGE);
1406 setProgressBar(null, choice.hashCode());
1412 public void inputSequence_actionPerformed(ActionEvent e)
1414 new SequenceFetcher(this);
1417 JPanel progressPanel;
1418 ArrayList<JPanel> fileLoadingPanels=new ArrayList<JPanel>();
1419 public void startLoading(final String fileName)
1421 if (fileLoadingCount == 0)
1423 fileLoadingPanels.add(addProgressPanel("Loading File: " + fileName + " "));
1428 private JPanel addProgressPanel(String string)
1430 if (progressPanel == null)
1432 progressPanel = new JPanel(new GridLayout(1,1));
1433 totalProgressCount = 0;
1434 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1436 JPanel thisprogress=new JPanel(new BorderLayout(10,5));
1437 JProgressBar progressBar = new JProgressBar();
1438 progressBar.setIndeterminate(true);
1440 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1442 thisprogress.add(progressBar, BorderLayout.CENTER);
1443 progressPanel.add(thisprogress);
1444 ((GridLayout)progressPanel.getLayout()).setRows(((GridLayout)progressPanel.getLayout()).getRows()+1);
1445 ++totalProgressCount;
1446 instance.validate();
1447 return thisprogress;
1450 int totalProgressCount = 0;
1452 private void removeProgressPanel(JPanel progbar)
1454 if (progressPanel != null)
1456 progressPanel.remove(progbar);
1457 GridLayout gl = (GridLayout) progressPanel.getLayout();
1458 gl.setRows(gl.getRows()-1);
1459 if (--totalProgressCount < 1)
1461 this.getContentPane().remove(progressPanel);
1462 progressPanel = null;
1468 public void stopLoading()
1471 if (fileLoadingCount < 1)
1473 for (JPanel flp : fileLoadingPanels)
1475 removeProgressPanel(flp);
1477 fileLoadingPanels.clear();
1478 fileLoadingCount = 0;
1483 public static int getViewCount(String alignmentId)
1485 AlignViewport[] aps = getViewports(alignmentId);
1486 return (aps == null) ? 0 : aps.length;
1491 * @param alignmentId
1492 * @return all AlignmentPanels concerning the alignmentId sequence set
1494 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1497 if (Desktop.desktop == null)
1499 // no frames created and in headless mode
1500 // TODO: verify that frames are recoverable when in headless mode
1503 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1504 ArrayList aps = new ArrayList();
1505 for (int t = 0; t < frames.length; t++)
1507 if (frames[t] instanceof AlignFrame)
1509 AlignFrame af = (AlignFrame) frames[t];
1510 for (int a = 0; a < af.alignPanels.size(); a++)
1513 .equals(((AlignmentPanel) af.alignPanels.elementAt(a)).av
1514 .getSequenceSetId()))
1516 aps.add(af.alignPanels.elementAt(a));
1521 if (aps.size() == 0)
1525 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1526 for (int t = 0; t < vap.length; t++)
1528 vap[t] = (AlignmentPanel) aps.get(t);
1534 * get all the viewports on an alignment.
1536 * @param sequenceSetId
1537 * unique alignment id
1538 * @return all viewports on the alignment bound to sequenceSetId
1540 public static AlignViewport[] getViewports(String sequenceSetId)
1542 Vector viewp = new Vector();
1543 if (desktop != null)
1545 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1547 for (int t = 0; t < frames.length; t++)
1549 if (frames[t] instanceof AlignFrame)
1551 AlignFrame afr = ((AlignFrame) frames[t]);
1552 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1554 if (afr.alignPanels != null)
1556 for (int a = 0; a < afr.alignPanels.size(); a++)
1558 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1559 .elementAt(a)).av.getSequenceSetId()))
1561 viewp.addElement(((AlignmentPanel) afr.alignPanels
1568 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1573 if (viewp.size() > 0)
1575 AlignViewport[] vp = new AlignViewport[viewp.size()];
1583 public void explodeViews(AlignFrame af)
1585 int size = af.alignPanels.size();
1591 for (int i = 0; i < size; i++)
1593 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1594 AlignFrame newaf = new AlignFrame(ap);
1595 if (ap.av.explodedPosition != null
1596 && !ap.av.explodedPosition.equals(af.getBounds()))
1598 newaf.setBounds(ap.av.explodedPosition);
1601 ap.av.gatherViewsHere = false;
1603 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1604 AlignFrame.DEFAULT_HEIGHT);
1607 af.alignPanels.clear();
1608 af.closeMenuItem_actionPerformed(true);
1612 public void gatherViews(AlignFrame source)
1614 source.viewport.gatherViewsHere = true;
1615 source.viewport.explodedPosition = source.getBounds();
1616 JInternalFrame[] frames = desktop.getAllFrames();
1617 String viewId = source.viewport.getSequenceSetId();
1619 for (int t = 0; t < frames.length; t++)
1621 if (frames[t] instanceof AlignFrame && frames[t] != source)
1623 AlignFrame af = (AlignFrame) frames[t];
1624 boolean gatherThis = false;
1625 for (int a = 0; a < af.alignPanels.size(); a++)
1627 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1628 if (viewId.equals(ap.av.getSequenceSetId()))
1631 ap.av.gatherViewsHere = false;
1632 ap.av.explodedPosition = af.getBounds();
1633 source.addAlignmentPanel(ap, false);
1639 af.alignPanels.clear();
1640 af.closeMenuItem_actionPerformed(true);
1647 jalview.gui.VamsasApplication v_client = null;
1649 public void vamsasImport_actionPerformed(ActionEvent e)
1651 if (v_client == null)
1653 // Load and try to start a session.
1654 JalviewFileChooser chooser = new JalviewFileChooser(
1655 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1657 chooser.setFileView(new JalviewFileView());
1658 chooser.setDialogTitle("Open a saved VAMSAS session");
1659 chooser.setToolTipText("select a vamsas session to be opened as a new vamsas session.");
1661 int value = chooser.showOpenDialog(this);
1663 if (value == JalviewFileChooser.APPROVE_OPTION)
1665 String fle = chooser.getSelectedFile().toString();
1666 if (!vamsasImport(chooser.getSelectedFile()))
1668 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1669 "Couldn't import '" + fle + "' as a new vamsas session.",
1670 "Vamsas Document Import Failed",
1671 JOptionPane.ERROR_MESSAGE);
1677 jalview.bin.Cache.log
1678 .error("Implementation error - load session from a running session is not supported.");
1683 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1686 * @return true if import was a success and a session was started.
1688 public boolean vamsasImport(URL url)
1690 // TODO: create progress bar
1691 if (v_client != null)
1694 jalview.bin.Cache.log
1695 .error("Implementation error - load session from a running session is not supported.");
1701 // copy the URL content to a temporary local file
1702 // TODO: be a bit cleverer here with nio (?!)
1703 File file = File.createTempFile("vdocfromurl", ".vdj");
1704 FileOutputStream fos = new FileOutputStream(file);
1705 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1706 byte[] buffer = new byte[2048];
1708 while ((ln = bis.read(buffer)) > -1)
1710 fos.write(buffer, 0, ln);
1714 v_client = new jalview.gui.VamsasApplication(this, file,
1715 url.toExternalForm());
1716 } catch (Exception ex)
1718 jalview.bin.Cache.log.error(
1719 "Failed to create new vamsas session from contents of URL "
1723 setupVamsasConnectedGui();
1724 v_client.initial_update(); // TODO: thread ?
1725 return v_client.inSession();
1729 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1732 * @return true if import was a success and a session was started.
1734 public boolean vamsasImport(File file)
1736 if (v_client != null)
1739 jalview.bin.Cache.log
1740 .error("Implementation error - load session from a running session is not supported.");
1744 setProgressBar("Importing VAMSAS session from " + file.getName(),
1748 v_client = new jalview.gui.VamsasApplication(this, file, null);
1749 } catch (Exception ex)
1751 setProgressBar("Importing VAMSAS session from " + file.getName(),
1753 jalview.bin.Cache.log.error(
1754 "New vamsas session from existing session file failed:", ex);
1757 setupVamsasConnectedGui();
1758 v_client.initial_update(); // TODO: thread ?
1759 setProgressBar("Importing VAMSAS session from " + file.getName(),
1761 return v_client.inSession();
1764 public boolean joinVamsasSession(String mysesid)
1766 if (v_client != null)
1769 "Trying to join a vamsas session when another is already connected.");
1771 if (mysesid == null)
1773 throw new Error("Invalid vamsas session id.");
1775 v_client = new VamsasApplication(this, mysesid);
1776 setupVamsasConnectedGui();
1777 v_client.initial_update();
1778 return (v_client.inSession());
1781 public void vamsasStart_actionPerformed(ActionEvent e)
1783 if (v_client == null)
1786 // we just start a default session for moment.
1788 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1789 * getProperty("LAST_DIRECTORY"));
1791 * chooser.setFileView(new JalviewFileView());
1792 * chooser.setDialogTitle("Load Vamsas file");
1793 * chooser.setToolTipText("Import");
1795 * int value = chooser.showOpenDialog(this);
1797 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1798 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1800 v_client = new VamsasApplication(this);
1801 setupVamsasConnectedGui();
1802 v_client.initial_update(); // TODO: thread ?
1806 // store current data in session.
1807 v_client.push_update(); // TODO: thread
1811 protected void setupVamsasConnectedGui()
1813 vamsasStart.setText("Session Update");
1814 vamsasSave.setVisible(true);
1815 vamsasStop.setVisible(true);
1816 vamsasImport.setVisible(false); // Document import to existing session is
1817 // not possible for vamsas-client-1.0.
1820 protected void setupVamsasDisconnectedGui()
1822 vamsasSave.setVisible(false);
1823 vamsasStop.setVisible(false);
1824 vamsasImport.setVisible(true);
1825 vamsasStart.setText("New Vamsas Session");
1828 public void vamsasStop_actionPerformed(ActionEvent e)
1830 if (v_client != null)
1832 v_client.end_session();
1834 setupVamsasDisconnectedGui();
1838 protected void buildVamsasStMenu()
1840 if (v_client == null)
1842 String[] sess = null;
1845 sess = VamsasApplication.getSessionList();
1846 } catch (Exception e)
1848 jalview.bin.Cache.log.warn(
1849 "Problem getting current sessions list.", e);
1854 jalview.bin.Cache.log.debug("Got current sessions list: "
1855 + sess.length + " entries.");
1856 VamsasStMenu.removeAll();
1857 for (int i = 0; i < sess.length; i++)
1859 JMenuItem sessit = new JMenuItem();
1860 sessit.setText(sess[i]);
1861 sessit.setToolTipText("Connect to session " + sess[i]);
1862 final Desktop dsktp = this;
1863 final String mysesid = sess[i];
1864 sessit.addActionListener(new ActionListener()
1867 public void actionPerformed(ActionEvent e)
1869 if (dsktp.v_client == null)
1871 Thread rthr = new Thread(new Runnable()
1876 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1877 dsktp.setupVamsasConnectedGui();
1878 dsktp.v_client.initial_update();
1886 VamsasStMenu.add(sessit);
1888 // don't show an empty menu.
1889 VamsasStMenu.setVisible(sess.length > 0);
1894 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1895 VamsasStMenu.removeAll();
1896 VamsasStMenu.setVisible(false);
1901 // Not interested in the content. Just hide ourselves.
1902 VamsasStMenu.setVisible(false);
1906 public void vamsasSave_actionPerformed(ActionEvent e)
1908 if (v_client != null)
1910 JalviewFileChooser chooser = new JalviewFileChooser(
1911 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1912 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1914 { "Vamsas Document" }, "Vamsas Document");
1916 chooser.setFileView(new JalviewFileView());
1917 chooser.setDialogTitle("Save Vamsas Document Archive");
1919 int value = chooser.showSaveDialog(this);
1921 if (value == JalviewFileChooser.APPROVE_OPTION)
1923 java.io.File choice = chooser.getSelectedFile();
1924 JPanel progpanel = addProgressPanel("Saving VAMSAS Document to "
1925 + choice.getName());
1926 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1927 String warnmsg = null;
1928 String warnttl = null;
1931 v_client.vclient.storeDocument(choice);
1934 warnttl = "Serious Problem saving Vamsas Document";
1935 warnmsg = ex.toString();
1936 jalview.bin.Cache.log.error("Error Whilst saving document to "
1939 } catch (Exception ex)
1941 warnttl = "Problem saving Vamsas Document.";
1942 warnmsg = ex.toString();
1943 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
1947 removeProgressPanel(progpanel);
1948 if (warnmsg != null)
1950 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1952 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
1958 JPanel vamUpdate = null;
1961 * hide vamsas user gui bits when a vamsas document event is being handled.
1964 * true to hide gui, false to reveal gui
1966 public void setVamsasUpdate(boolean b)
1968 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
1969 + (b ? "in progress" : "finished"));
1971 if (vamUpdate != null)
1973 this.removeProgressPanel(vamUpdate);
1977 vamUpdate = this.addProgressPanel("Updating vamsas session");
1979 vamsasStart.setVisible(!b);
1980 vamsasStop.setVisible(!b);
1981 vamsasSave.setVisible(!b);
1984 public JInternalFrame[] getAllFrames()
1986 return desktop.getAllFrames();
1990 * Checks the given url to see if it gives a response indicating that the user
1991 * should be informed of a new questionnaire.
1995 public void checkForQuestionnaire(String url)
1997 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
1998 // javax.swing.SwingUtilities.invokeLater(jvq);
1999 new Thread(jvq).start();
2003 * Proxy class for JDesktopPane which optionally displays the current memory
2004 * usage and highlights the desktop area with a red bar if free memory runs
2009 public class MyDesktopPane extends JDesktopPane implements Runnable
2012 boolean showMemoryUsage = false;
2016 java.text.NumberFormat df;
2018 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2021 public MyDesktopPane(boolean showMemoryUsage)
2023 showMemoryUsage(showMemoryUsage);
2026 public void showMemoryUsage(boolean showMemoryUsage)
2028 this.showMemoryUsage = showMemoryUsage;
2029 if (showMemoryUsage)
2031 Thread worker = new Thread(this);
2036 public boolean isShowMemoryUsage()
2038 return showMemoryUsage;
2043 df = java.text.NumberFormat.getNumberInstance();
2044 df.setMaximumFractionDigits(2);
2045 runtime = Runtime.getRuntime();
2047 while (showMemoryUsage)
2051 maxMemory = runtime.maxMemory() / 1048576f;
2052 allocatedMemory = runtime.totalMemory() / 1048576f;
2053 freeMemory = runtime.freeMemory() / 1048576f;
2054 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2056 percentUsage = (totalFreeMemory / maxMemory) * 100;
2058 // if (percentUsage < 20)
2060 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2062 // instance.set.setBorder(border1);
2065 // sleep after showing usage
2067 } catch (Exception ex)
2069 ex.printStackTrace();
2074 public void paintComponent(Graphics g)
2076 if (showMemoryUsage && g != null && df != null)
2078 if (percentUsage < 20)
2079 g.setColor(Color.red);
2080 FontMetrics fm = g.getFontMetrics();
2084 "Total Free Memory: " + df.format(totalFreeMemory)
2085 + "MB; Max Memory: " + df.format(maxMemory)
2086 + "MB; " + df.format(percentUsage) + "%", 10,
2087 getHeight() - fm.getHeight());
2094 * fixes stacking order after a modal dialog to ensure windows that should be on top actually are
2096 public void relayerWindows()
2101 protected JMenuItem groovyShell;
2103 public void doGroovyCheck()
2105 if (jalview.bin.Cache.groovyJarsPresent())
2107 groovyShell = new JMenuItem();
2108 groovyShell.setText("Groovy Console...");
2109 groovyShell.addActionListener(new ActionListener()
2111 public void actionPerformed(ActionEvent e)
2113 groovyShell_actionPerformed(e);
2116 toolsMenu.add(groovyShell);
2117 groovyShell.setVisible(true);
2122 * Accessor method to quickly get all the AlignmentFrames loaded.
2124 public static AlignFrame[] getAlignframes()
2126 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2132 Vector avp = new Vector();
2136 for (int i = frames.length - 1; i > -1; i--)
2138 if (frames[i] instanceof AlignFrame)
2140 AlignFrame af = (AlignFrame) frames[i];
2144 } catch (Exception ex)
2146 ex.printStackTrace();
2148 if (avp.size() == 0)
2152 AlignFrame afs[] = new AlignFrame[avp.size()];
2153 for (int i = 0, j = avp.size(); i < j; i++)
2155 afs[i] = (AlignFrame) avp.elementAt(i);
2160 public AppJmol[] getJmols()
2162 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2168 Vector avp = new Vector();
2172 for (int i = frames.length - 1; i > -1; i--)
2174 if (frames[i] instanceof AppJmol)
2176 AppJmol af = (AppJmol) frames[i];
2180 } catch (Exception ex)
2182 ex.printStackTrace();
2184 if (avp.size() == 0)
2188 AppJmol afs[] = new AppJmol[avp.size()];
2189 for (int i = 0, j = avp.size(); i < j; i++)
2191 afs[i] = (AppJmol) avp.elementAt(i);
2198 * Add Groovy Support to Jalview
2200 public void groovyShell_actionPerformed(ActionEvent e)
2202 // use reflection to avoid creating compilation dependency.
2203 if (!jalview.bin.Cache.groovyJarsPresent())
2206 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
2210 Class gcClass = Desktop.class.getClassLoader().loadClass(
2211 "groovy.ui.Console");
2212 Constructor gccons = gcClass.getConstructor(null);
2213 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2215 { String.class, Object.class });
2216 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2217 Object gc = gccons.newInstance(null);
2218 setvar.invoke(gc, new Object[]
2219 { "Jalview", this });
2220 run.invoke(gc, null);
2221 } catch (Exception ex)
2223 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2225 .showInternalMessageDialog(
2228 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
2229 "Jalview Groovy Support Failed",
2230 JOptionPane.ERROR_MESSAGE);
2235 * Progress bars managed by the IProgressIndicator method.
2237 private Hashtable<Long,JPanel> progressBars;
2238 private Hashtable<Long,IProgressIndicatorHandler> progressBarHandlers;
2243 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2245 public void setProgressBar(String message, long id)
2247 if (progressBars == null)
2249 progressBars = new Hashtable<Long,JPanel>();
2250 progressBarHandlers = new Hashtable<Long,IProgressIndicatorHandler>();
2253 if (progressBars.get(new Long(id)) != null)
2255 JPanel progressPanel = progressBars
2256 .remove(new Long(id));
2257 if (progressBarHandlers.contains(new Long(id)))
2259 progressBarHandlers.remove(new Long(id));
2261 removeProgressPanel(progressPanel);
2265 progressBars.put(new Long(id), addProgressPanel(message));
2272 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2273 * jalview.gui.IProgressIndicatorHandler)
2275 public void registerHandler(final long id,
2276 final IProgressIndicatorHandler handler)
2278 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2281 "call setProgressBar before registering the progress bar's handler.");
2283 progressBarHandlers.put(new Long(id), handler);
2284 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
2285 if (handler.canCancel())
2287 JButton cancel = new JButton("Cancel");
2288 final IProgressIndicator us = this;
2289 cancel.addActionListener(new ActionListener()
2292 public void actionPerformed(ActionEvent e)
2294 handler.cancelActivity(id);
2297 + ((JLabel) progressPanel.getComponent(0))
2301 progressPanel.add(cancel, BorderLayout.EAST);
2306 * This will return the first AlignFrame viewing AlignViewport av. It will
2307 * break if there are more than one AlignFrames viewing a particular av. This
2310 * @return alignFrame for av
2312 public static AlignFrame getAlignFrameFor(AlignViewport av)
2314 if (desktop != null)
2316 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2317 for (int panel = 0; aps != null && panel < aps.length; panel++)
2319 if (aps[panel] != null && aps[panel].av == av)
2321 return aps[panel].alignFrame;
2328 public VamsasApplication getVamsasApplication()
2335 * flag set if jalview GUI is being operated programmatically
2337 private boolean inBatchMode = false;
2340 * check if jalview GUI is being operated programmatically
2342 * @return inBatchMode
2344 public boolean isInBatchMode()
2350 * set flag if jalview GUI is being operated programmatically
2352 * @param inBatchMode
2354 public void setInBatchMode(boolean inBatchMode)
2356 this.inBatchMode = inBatchMode;
2359 public void startServiceDiscovery()
2361 startServiceDiscovery(false);
2364 public void startServiceDiscovery(boolean blocking)
2366 boolean alive = true;
2367 Thread t0 = null, t1 = null, t2 = null;
2369 // todo: changesupport handlers need to be transferred
2370 if (discoverer == null)
2372 discoverer = new jalview.ws.jws1.Discoverer();
2373 // register PCS handler for desktop.
2374 discoverer.addPropertyChangeListener(changeSupport);
2376 // JAL-940 - disabled JWS1 service configuration - always start discoverer until we phase out completely
2379 (t0 = new Thread(discoverer)).start();
2384 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2386 // EnfinEnvision web service menu entries are rebuild every time the
2387 // menu is shown, so no changeSupport events are needed.
2388 jalview.ws.EnfinEnvision2OneWay.getInstance();
2389 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2392 } catch (Exception e)
2395 .info("Exception when trying to launch Envision2 workflow discovery.",
2397 Cache.log.info(e.getStackTrace());
2399 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2401 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2403 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2405 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2411 // TODO: do rest service discovery
2420 } catch (Exception e)
2423 alive = (t1 != null && t1.isAlive())
2424 || (t2 != null && t2.isAlive())
2425 || (t3 != null && t3.isAlive())
2426 || (t0 != null && t0.isAlive());
2432 * called to check if the service discovery process completed successfully.
2436 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2438 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2440 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2441 .getErrorMessages();
2444 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2446 if (serviceChangedDialog == null)
2448 // only run if we aren't already displaying one of these.
2449 javax.swing.SwingUtilities
2450 .invokeLater(serviceChangedDialog = new Runnable()
2456 .showInternalMessageDialog(
2459 + "It may be that you have invalid JABA URLs\nin your web service preferences.\n\nGo to the Web services tab of the\nTools->Preferences dialog box to change them.\n",
2460 "Preferences Problem",
2461 JOptionPane.WARNING_MESSAGE);
2462 serviceChangedDialog = null;
2471 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2478 private Runnable serviceChangedDialog = null;
2481 * start a thread to open a URL in the configured browser. Pops up a warning
2482 * dialog to the user if there is an exception when calling out to the browser
2487 public static void showUrl(final String url)
2489 showUrl(url, Desktop.instance);
2492 * Like showUrl but allows progress handler to be specified
2494 * @param progress (null) or object implementing IProgressIndicator
2496 public static void showUrl(final String url, final IProgressIndicator progress)
2498 new Thread(new Runnable()
2504 if (progress!=null) {
2505 progress.setProgressBar("Opening "+url, this.hashCode());
2507 jalview.util.BrowserLauncher.openURL(url);
2508 } catch (Exception ex)
2511 .showInternalMessageDialog(
2513 "Unixers: Couldn't find default web browser."
2514 + "\nAdd the full path to your browser in Preferences.",
2515 "Web browser not found",
2516 JOptionPane.WARNING_MESSAGE);
2518 ex.printStackTrace();
2520 if (progress!=null) {
2521 progress.setProgressBar(null, this.hashCode());
2527 public static WsParamSetManager wsparamManager = null;
2529 public static ParamManager getUserParameterStore()
2531 if (wsparamManager == null)
2533 wsparamManager = new WsParamSetManager();
2535 return wsparamManager;