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)
338 this.addMouseListener(new MouseAdapter()
340 public void mousePressed(MouseEvent evt)
342 if (SwingUtilities.isRightMouseButton(evt))
344 showPasteMenu(evt.getX(), evt.getY());
348 this.addFocusListener(new FocusListener()
352 public void focusLost(FocusEvent e)
354 // TODO Auto-generated method stub
359 public void focusGained(FocusEvent e)
361 Cache.log.debug("Relaying windows after focus gain");
362 // make sure that we sort windows properly after we gain focus
363 instance.relayerWindows();
366 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
367 // Spawn a thread that shows the splashscreen
368 SwingUtilities.invokeLater(new Runnable()
377 // Thread off a new instance of the file chooser - this reduces the time it
378 // takes to open it later on.
379 new Thread(new Runnable()
383 Cache.log.debug("Filechooser init thread started.");
384 JalviewFileChooser chooser = new JalviewFileChooser(
385 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
386 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
387 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
388 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
389 Cache.log.debug("Filechooser init thread finished.");
392 // Add the service change listener
393 changeSupport.addJalviewPropertyChangeListener("services",
394 new PropertyChangeListener()
398 public void propertyChange(PropertyChangeEvent evt)
400 Cache.log.debug("Firing service changed event for "
401 + evt.getNewValue());
402 JalviewServicesChanged(evt);
408 protected void showNews_actionPerformed(ActionEvent e)
410 showNews(showNews.isSelected());
412 void showNews(boolean visible)
415 Cache.log.debug((visible?"Showing":"Hiding")+" news.");
416 showNews.setSelected(visible);
417 if (visible && !jvnews.isVisible())
419 new Thread(new Runnable() {
423 long instance=System.currentTimeMillis();
424 Desktop.instance.setProgressBar("Refreshing news", instance);
425 jvnews.refreshNews();
426 Desktop.instance.setProgressBar(null, instance);
435 * recover the last known dimensions for a jalview window
438 * - empty string is desktop, all other windows have unique prefix
439 * @return null or last known dimensions scaled to current geometry (if last
440 * window geom was known)
442 Rectangle getLastKnownDimensions(String windowName)
444 // TODO: lock aspect ratio for scaling desktop Bug #0058199
445 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
446 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
447 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
448 String width = jalview.bin.Cache.getProperty(windowName
450 String height = jalview.bin.Cache.getProperty(windowName
452 if ((x != null) && (y != null) && (width != null) && (height != null))
454 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
455 .parseInt(width), ih = Integer.parseInt(height);
456 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
458 // attempt #1 - try to cope with change in screen geometry - this
459 // version doesn't preserve original jv aspect ratio.
460 // take ratio of current screen size vs original screen size.
461 double sw = ((1f * screenSize.width) / (1f * Integer
462 .parseInt(jalview.bin.Cache
463 .getProperty("SCREENGEOMETRY_WIDTH"))));
464 double sh = ((1f * screenSize.height) / (1f * Integer
465 .parseInt(jalview.bin.Cache
466 .getProperty("SCREENGEOMETRY_HEIGHT"))));
467 // rescale the bounds depending upon the current screen geometry.
468 ix = (int) (ix * sw);
469 iw = (int) (iw * sw);
470 iy = (int) (iy * sh);
471 ih = (int) (ih * sh);
472 while (ix >= screenSize.width)
474 jalview.bin.Cache.log
475 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
476 ix -= screenSize.width;
478 while (iy >= screenSize.height)
480 jalview.bin.Cache.log
481 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
482 iy -= screenSize.height;
484 jalview.bin.Cache.log.debug("Got last known dimensions for "
485 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
488 // return dimensions for new instance
489 return new Rectangle(ix, iy, iw, ih);
494 private void doVamsasClientCheck()
496 if (jalview.bin.Cache.vamsasJarsPresent())
498 setupVamsasDisconnectedGui();
499 VamsasMenu.setVisible(true);
500 final Desktop us = this;
501 VamsasMenu.addMenuListener(new MenuListener()
503 // this listener remembers when the menu was first selected, and
504 // doesn't rebuild the session list until it has been cleared and
506 boolean refresh = true;
508 public void menuCanceled(MenuEvent e)
513 public void menuDeselected(MenuEvent e)
518 public void menuSelected(MenuEvent e)
522 us.buildVamsasStMenu();
527 vamsasStart.setVisible(true);
531 void showPasteMenu(int x, int y)
533 JPopupMenu popup = new JPopupMenu();
534 JMenuItem item = new JMenuItem("Paste To New Window");
535 item.addActionListener(new ActionListener()
537 public void actionPerformed(ActionEvent evt)
544 popup.show(this, x, y);
551 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
552 Transferable contents = c.getContents(this);
554 if (contents != null)
556 String file = (String) contents
557 .getTransferData(DataFlavor.stringFlavor);
559 String format = new IdentifyFile().Identify(file,
560 FormatAdapter.PASTE);
562 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
565 } catch (Exception ex)
568 .println("Unable to paste alignment from system clipboard:\n"
574 * Adds and opens the given frame to the desktop
585 public static synchronized void addInternalFrame(
586 final JInternalFrame frame, String title, int w, int h)
588 addInternalFrame(frame, title, w, h, true);
605 public static synchronized void addInternalFrame(
606 final JInternalFrame frame, String title, int w, int h,
610 // TODO: allow callers to determine X and Y position of frame (eg. via
612 // TODO: consider fixing method to update entries in the window submenu with
613 // the current window title
615 frame.setTitle(title);
616 if (frame.getWidth() < 1 || frame.getHeight() < 1)
620 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
621 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
622 // IF JALVIEW IS RUNNING HEADLESS
623 // ///////////////////////////////////////////////
624 if (System.getProperty("java.awt.headless") != null
625 && System.getProperty("java.awt.headless").equals("true"))
632 frame.setVisible(true);
633 frame.setClosable(true);
634 frame.setResizable(resizable);
635 frame.setMaximizable(resizable);
636 frame.setIconifiable(resizable);
637 frame.setFrameIcon(null);
639 if (frame.getX() < 1 && frame.getY() < 1)
641 frame.setLocation(xOffset * openFrameCount, yOffset
642 * ((openFrameCount - 1) % 10) + yOffset);
645 final JMenuItem menuItem = new JMenuItem(title);
646 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
648 public void internalFrameActivated(
649 javax.swing.event.InternalFrameEvent evt)
651 JInternalFrame itf = desktop.getSelectedFrame();
659 public void internalFrameClosed(
660 javax.swing.event.InternalFrameEvent evt)
662 PaintRefresher.RemoveComponent(frame);
664 windowMenu.remove(menuItem);
665 JInternalFrame itf = desktop.getSelectedFrame();
674 menuItem.addActionListener(new ActionListener()
676 public void actionPerformed(ActionEvent e)
680 frame.setSelected(true);
681 frame.setIcon(false);
682 } catch (java.beans.PropertyVetoException ex)
688 menuItem.addMouseListener(new MouseListener()
692 public void mouseReleased(MouseEvent e)
697 public void mousePressed(MouseEvent e)
702 public void mouseExited(MouseEvent e)
706 frame.setSelected(false);
707 } catch (PropertyVetoException e1)
713 public void mouseEntered(MouseEvent e)
717 frame.setSelected(true);
718 } catch (PropertyVetoException e1)
724 public void mouseClicked(MouseEvent e)
730 windowMenu.add(menuItem);
736 frame.setSelected(true);
737 frame.requestFocus();
738 } catch (java.beans.PropertyVetoException ve)
741 catch (java.lang.ClassCastException cex)
743 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);
747 public void lostOwnership(Clipboard clipboard, Transferable contents)
751 Desktop.jalviewClipboard = null;
754 internalCopy = false;
757 public void dragEnter(DropTargetDragEvent evt)
761 public void dragExit(DropTargetEvent evt)
765 public void dragOver(DropTargetDragEvent evt)
769 public void dropActionChanged(DropTargetDragEvent evt)
779 public void drop(DropTargetDropEvent evt)
781 Transferable t = evt.getTransferable();
782 java.util.List files = null;
783 java.util.List protocols = null;
787 DataFlavor uriListFlavor = new DataFlavor(
788 "text/uri-list;class=java.lang.String");
789 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
791 // Works on Windows and MacOSX
792 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
793 files = (java.util.List) t
794 .getTransferData(DataFlavor.javaFileListFlavor);
796 else if (t.isDataFlavorSupported(uriListFlavor))
798 // This is used by Unix drag system
799 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
800 String data = (String) t.getTransferData(uriListFlavor);
801 files = new java.util.ArrayList(1);
802 protocols = new java.util.ArrayList(1);
803 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
804 data, "\r\n"); st.hasMoreTokens();)
806 String s = st.nextToken();
807 if (s.startsWith("#"))
809 // the line is a comment (as per the RFC 2483)
812 java.net.URI uri = new java.net.URI(s);
813 if (uri.getScheme().toLowerCase().startsWith("http"))
815 protocols.add(FormatAdapter.URL);
816 files.add(uri.toString());
820 // otherwise preserve old behaviour: catch all for file objects
821 java.io.File file = new java.io.File(uri);
822 protocols.add(FormatAdapter.FILE);
823 files.add(file.toString());
827 } catch (Exception e)
835 for (int i = 0; i < files.size(); i++)
837 String file = files.get(i).toString();
838 String protocol = (protocols == null) ? FormatAdapter.FILE
839 : (String) protocols.get(i);
840 String format = null;
842 if (file.endsWith(".jar"))
849 format = new IdentifyFile().Identify(file, protocol);
852 new FileLoader().LoadFile(file, protocol, format);
855 } catch (Exception ex)
867 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
869 JalviewFileChooser chooser = new JalviewFileChooser(
870 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
871 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
872 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
873 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
875 chooser.setFileView(new JalviewFileView());
876 chooser.setDialogTitle("Open local file");
877 chooser.setToolTipText("Open");
879 int value = chooser.showOpenDialog(this);
881 if (value == JalviewFileChooser.APPROVE_OPTION)
883 String choice = chooser.getSelectedFile().getPath();
884 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
885 .getSelectedFile().getParent());
887 String format = null;
888 if (chooser.getSelectedFormat().equals("Jalview"))
894 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
897 if (viewport != null)
899 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
904 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
915 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
917 // This construct allows us to have a wider textfield
919 JLabel label = new JLabel("Enter URL of Input File");
920 final JComboBox history = new JComboBox();
922 JPanel panel = new JPanel(new GridLayout(2, 1));
925 history.setPreferredSize(new Dimension(400, 20));
926 history.setEditable(true);
927 history.addItem("http://www.");
929 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
933 if (historyItems != null)
935 st = new StringTokenizer(historyItems, "\t");
937 while (st.hasMoreTokens())
939 history.addItem(st.nextElement());
943 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
944 "Input Alignment From URL", JOptionPane.OK_CANCEL_OPTION);
946 if (reply != JOptionPane.OK_OPTION)
951 String url = history.getSelectedItem().toString();
953 if (url.toLowerCase().endsWith(".jar"))
955 if (viewport != null)
957 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
962 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
967 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
969 if (format.equals("URL NOT FOUND"))
971 JOptionPane.showInternalMessageDialog(Desktop.desktop,
972 "Couldn't locate " + url, "URL not found",
973 JOptionPane.WARNING_MESSAGE);
978 if (viewport != null)
980 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
984 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
995 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
997 CutAndPasteTransfer cap = new CutAndPasteTransfer();
998 cap.setForInput(viewport);
999 Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
1007 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1009 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1010 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1012 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1013 getBounds().y, getWidth(), getHeight()));
1015 if (jconsole != null)
1017 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1018 jconsole.stopConsole();
1022 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1029 private void storeLastKnownDimensions(String string, Rectangle jc)
1031 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1032 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1033 + " height:" + jc.height);
1035 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1036 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1037 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1038 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1047 public void aboutMenuItem_actionPerformed(ActionEvent e)
1049 StringBuffer message = getAboutMessage(false);
1050 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1052 message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1054 public StringBuffer getAboutMessage(boolean shortv)
1056 StringBuffer message=new StringBuffer();
1057 message.append("<html>");
1060 message.append("<h1><strong>Jalview "
1061 + jalview.bin.Cache.getProperty("VERSION") + "</strong></h1><br>");
1062 message.append("<strong>Last Updated: <em>"+jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")+"</em></strong>");
1066 message.append("<strong>Jalview version "
1067 + jalview.bin.Cache.getProperty("VERSION") + "; last updated: "
1068 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1071 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1074 message.append("<br>...Checking latest version...</br>");
1076 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1077 .equals(jalview.bin.Cache.getProperty("VERSION")))
1080 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1081 .indexOf("automated build") == -1)
1084 // Displayed when code version and jnlp version do not match and code
1085 // version is not a development build
1086 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1089 message.append("<br>!! Jalview version "
1090 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1092 + " is available for download from "+jalview.bin.Cache.getDefault("www.jalview.org","http://www.jalview.org")+" !!");
1094 message.append("</div>");
1097 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")
1098 + "<br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1099 + "<br>For help, see the FAQ at www.jalview.org and/or join the jalview-discuss@jalview.org mailing list"
1100 + "<br>If you use Jalview, please cite:"
1101 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1102 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1103 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1114 public void documentationMenuItem_actionPerformed(ActionEvent e)
1118 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
1119 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
1120 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
1122 javax.help.HelpBroker hb = hs.createHelpBroker();
1123 hb.setCurrentID("home");
1124 hb.setDisplayed(true);
1125 } catch (Exception ex)
1130 public void closeAll_actionPerformed(ActionEvent e)
1132 JInternalFrame[] frames = desktop.getAllFrames();
1133 for (int i = 0; i < frames.length; i++)
1137 frames[i].setClosed(true);
1138 } catch (java.beans.PropertyVetoException ex)
1142 System.out.println("ALL CLOSED");
1143 if (v_client != null)
1145 // TODO clear binding to vamsas document objects on close_all
1150 public void raiseRelated_actionPerformed(ActionEvent e)
1152 reorderAssociatedWindows(false, false);
1155 public void minimizeAssociated_actionPerformed(ActionEvent e)
1157 reorderAssociatedWindows(true, false);
1160 void closeAssociatedWindows()
1162 reorderAssociatedWindows(false, true);
1168 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1171 protected void garbageCollect_actionPerformed(ActionEvent e)
1173 // We simply collect the garbage
1174 jalview.bin.Cache.log.debug("Collecting garbage...");
1176 jalview.bin.Cache.log.debug("Finished garbage collection.");
1183 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1186 protected void showMemusage_actionPerformed(ActionEvent e)
1188 desktop.showMemoryUsage(showMemusage.isSelected());
1195 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1198 protected void showConsole_actionPerformed(ActionEvent e)
1200 showConsole(showConsole.isSelected());
1203 Console jconsole = null;
1206 * control whether the java console is visible or not
1210 void showConsole(boolean selected)
1212 showConsole.setSelected(selected);
1213 // TODO: decide if we should update properties file
1214 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1216 jconsole.setVisible(selected);
1219 void reorderAssociatedWindows(boolean minimize, boolean close)
1221 JInternalFrame[] frames = desktop.getAllFrames();
1222 if (frames == null || frames.length < 1)
1227 AlignViewport source = null, target = null;
1228 if (frames[0] instanceof AlignFrame)
1230 source = ((AlignFrame) frames[0]).getCurrentView();
1232 else if (frames[0] instanceof TreePanel)
1234 source = ((TreePanel) frames[0]).getViewPort();
1236 else if (frames[0] instanceof PCAPanel)
1238 source = ((PCAPanel) frames[0]).av;
1240 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1242 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1247 for (int i = 0; i < frames.length; i++)
1250 if (frames[i] == null)
1254 if (frames[i] instanceof AlignFrame)
1256 target = ((AlignFrame) frames[i]).getCurrentView();
1258 else if (frames[i] instanceof TreePanel)
1260 target = ((TreePanel) frames[i]).getViewPort();
1262 else if (frames[i] instanceof PCAPanel)
1264 target = ((PCAPanel) frames[i]).av;
1266 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1268 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1271 if (source == target)
1277 frames[i].setClosed(true);
1281 frames[i].setIcon(minimize);
1284 frames[i].toFront();
1288 } catch (java.beans.PropertyVetoException ex)
1302 protected void preferences_actionPerformed(ActionEvent e)
1313 public void saveState_actionPerformed(ActionEvent e)
1315 JalviewFileChooser chooser = new JalviewFileChooser(
1316 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1317 { "jar" }, new String[]
1318 { "Jalview Project" }, "Jalview Project");
1320 chooser.setFileView(new JalviewFileView());
1321 chooser.setDialogTitle("Save State");
1323 int value = chooser.showSaveDialog(this);
1325 if (value == JalviewFileChooser.APPROVE_OPTION)
1327 final Desktop me = this;
1328 final java.io.File choice = chooser.getSelectedFile();
1329 new Thread(new Runnable()
1334 setProgressBar("Saving jalview project " + choice.getName(),
1336 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1337 // TODO catch and handle errors for savestate
1338 // TODO prevent user from messing with the Desktop whilst we're saving
1341 new Jalview2XML().SaveState(choice);
1342 } catch (OutOfMemoryError oom)
1345 "Whilst saving current state to " + choice.getName(), oom);
1346 } catch (Exception ex)
1349 .error("Problems whilst trying to save to "
1350 + choice.getName(), ex);
1351 JOptionPane.showMessageDialog(me,
1352 "Error whilst saving current state to " + choice.getName(),
1353 "Couldn't save project", JOptionPane.WARNING_MESSAGE);
1355 setProgressBar(null, choice.hashCode());
1367 public void loadState_actionPerformed(ActionEvent e)
1369 JalviewFileChooser chooser = new JalviewFileChooser(
1370 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1371 { "jar" }, new String[]
1372 { "Jalview Project" }, "Jalview Project");
1373 chooser.setFileView(new JalviewFileView());
1374 chooser.setDialogTitle("Restore state");
1376 int value = chooser.showOpenDialog(this);
1378 if (value == JalviewFileChooser.APPROVE_OPTION)
1380 final String choice = chooser.getSelectedFile().getAbsolutePath();
1381 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1382 .getSelectedFile().getParent());
1383 new Thread(new Runnable()
1387 setProgressBar("loading jalview project " + choice,
1391 new Jalview2XML().LoadJalviewAlign(choice);
1392 } catch (OutOfMemoryError oom)
1394 new OOMWarning("Whilst loading project from " + choice, oom);
1395 } catch (Exception ex)
1397 Cache.log.error("Problems whilst loading project from "
1399 JOptionPane.showMessageDialog(Desktop.desktop,
1400 "Error whilst loading project from " + choice,
1401 "Couldn't load project", JOptionPane.WARNING_MESSAGE);
1403 setProgressBar(null, choice.hashCode());
1409 public void inputSequence_actionPerformed(ActionEvent e)
1411 new SequenceFetcher(this);
1414 JPanel progressPanel;
1415 ArrayList<JPanel> fileLoadingPanels=new ArrayList<JPanel>();
1416 public void startLoading(final String fileName)
1418 if (fileLoadingCount == 0)
1420 fileLoadingPanels.add(addProgressPanel("Loading File: " + fileName + " "));
1425 private JPanel addProgressPanel(String string)
1427 if (progressPanel == null)
1429 progressPanel = new JPanel(new GridLayout(1,1));
1430 totalProgressCount = 0;
1431 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1433 JPanel thisprogress=new JPanel(new BorderLayout(10,5));
1434 JProgressBar progressBar = new JProgressBar();
1435 progressBar.setIndeterminate(true);
1437 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1439 thisprogress.add(progressBar, BorderLayout.CENTER);
1440 progressPanel.add(thisprogress);
1441 ((GridLayout)progressPanel.getLayout()).setRows(((GridLayout)progressPanel.getLayout()).getRows()+1);
1442 ++totalProgressCount;
1443 instance.validate();
1444 return thisprogress;
1447 int totalProgressCount = 0;
1449 private void removeProgressPanel(JPanel progbar)
1451 if (progressPanel != null)
1453 progressPanel.remove(progbar);
1454 GridLayout gl = (GridLayout) progressPanel.getLayout();
1455 gl.setRows(gl.getRows()-1);
1456 if (--totalProgressCount < 1)
1458 this.getContentPane().remove(progressPanel);
1459 progressPanel = null;
1465 public void stopLoading()
1468 if (fileLoadingCount < 1)
1470 for (JPanel flp : fileLoadingPanels)
1472 removeProgressPanel(flp);
1474 fileLoadingPanels.clear();
1475 fileLoadingCount = 0;
1480 public static int getViewCount(String alignmentId)
1482 AlignViewport[] aps = getViewports(alignmentId);
1483 return (aps == null) ? 0 : aps.length;
1488 * @param alignmentId
1489 * @return all AlignmentPanels concerning the alignmentId sequence set
1491 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1494 if (Desktop.desktop == null)
1496 // no frames created and in headless mode
1497 // TODO: verify that frames are recoverable when in headless mode
1500 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1501 ArrayList aps = new ArrayList();
1502 for (int t = 0; t < frames.length; t++)
1504 if (frames[t] instanceof AlignFrame)
1506 AlignFrame af = (AlignFrame) frames[t];
1507 for (int a = 0; a < af.alignPanels.size(); a++)
1510 .equals(((AlignmentPanel) af.alignPanels.elementAt(a)).av
1511 .getSequenceSetId()))
1513 aps.add(af.alignPanels.elementAt(a));
1518 if (aps.size() == 0)
1522 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1523 for (int t = 0; t < vap.length; t++)
1525 vap[t] = (AlignmentPanel) aps.get(t);
1531 * get all the viewports on an alignment.
1533 * @param sequenceSetId
1534 * unique alignment id
1535 * @return all viewports on the alignment bound to sequenceSetId
1537 public static AlignViewport[] getViewports(String sequenceSetId)
1539 Vector viewp = new Vector();
1540 if (desktop != null)
1542 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1544 for (int t = 0; t < frames.length; t++)
1546 if (frames[t] instanceof AlignFrame)
1548 AlignFrame afr = ((AlignFrame) frames[t]);
1549 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1551 if (afr.alignPanels != null)
1553 for (int a = 0; a < afr.alignPanels.size(); a++)
1555 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1556 .elementAt(a)).av.getSequenceSetId()))
1558 viewp.addElement(((AlignmentPanel) afr.alignPanels
1565 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1570 if (viewp.size() > 0)
1572 AlignViewport[] vp = new AlignViewport[viewp.size()];
1580 public void explodeViews(AlignFrame af)
1582 int size = af.alignPanels.size();
1588 for (int i = 0; i < size; i++)
1590 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1591 AlignFrame newaf = new AlignFrame(ap);
1592 if (ap.av.explodedPosition != null
1593 && !ap.av.explodedPosition.equals(af.getBounds()))
1595 newaf.setBounds(ap.av.explodedPosition);
1598 ap.av.gatherViewsHere = false;
1600 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1601 AlignFrame.DEFAULT_HEIGHT);
1604 af.alignPanels.clear();
1605 af.closeMenuItem_actionPerformed(true);
1609 public void gatherViews(AlignFrame source)
1611 source.viewport.gatherViewsHere = true;
1612 source.viewport.explodedPosition = source.getBounds();
1613 JInternalFrame[] frames = desktop.getAllFrames();
1614 String viewId = source.viewport.getSequenceSetId();
1616 for (int t = 0; t < frames.length; t++)
1618 if (frames[t] instanceof AlignFrame && frames[t] != source)
1620 AlignFrame af = (AlignFrame) frames[t];
1621 boolean gatherThis = false;
1622 for (int a = 0; a < af.alignPanels.size(); a++)
1624 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1625 if (viewId.equals(ap.av.getSequenceSetId()))
1628 ap.av.gatherViewsHere = false;
1629 ap.av.explodedPosition = af.getBounds();
1630 source.addAlignmentPanel(ap, false);
1636 af.alignPanels.clear();
1637 af.closeMenuItem_actionPerformed(true);
1644 jalview.gui.VamsasApplication v_client = null;
1646 public void vamsasImport_actionPerformed(ActionEvent e)
1648 if (v_client == null)
1650 // Load and try to start a session.
1651 JalviewFileChooser chooser = new JalviewFileChooser(
1652 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1654 chooser.setFileView(new JalviewFileView());
1655 chooser.setDialogTitle("Open a saved VAMSAS session");
1656 chooser.setToolTipText("select a vamsas session to be opened as a new vamsas session.");
1658 int value = chooser.showOpenDialog(this);
1660 if (value == JalviewFileChooser.APPROVE_OPTION)
1662 String fle = chooser.getSelectedFile().toString();
1663 if (!vamsasImport(chooser.getSelectedFile()))
1665 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1666 "Couldn't import '" + fle + "' as a new vamsas session.",
1667 "Vamsas Document Import Failed",
1668 JOptionPane.ERROR_MESSAGE);
1674 jalview.bin.Cache.log
1675 .error("Implementation error - load session from a running session is not supported.");
1680 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1683 * @return true if import was a success and a session was started.
1685 public boolean vamsasImport(URL url)
1687 // TODO: create progress bar
1688 if (v_client != null)
1691 jalview.bin.Cache.log
1692 .error("Implementation error - load session from a running session is not supported.");
1698 // copy the URL content to a temporary local file
1699 // TODO: be a bit cleverer here with nio (?!)
1700 File file = File.createTempFile("vdocfromurl", ".vdj");
1701 FileOutputStream fos = new FileOutputStream(file);
1702 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1703 byte[] buffer = new byte[2048];
1705 while ((ln = bis.read(buffer)) > -1)
1707 fos.write(buffer, 0, ln);
1711 v_client = new jalview.gui.VamsasApplication(this, file,
1712 url.toExternalForm());
1713 } catch (Exception ex)
1715 jalview.bin.Cache.log.error(
1716 "Failed to create new vamsas session from contents of URL "
1720 setupVamsasConnectedGui();
1721 v_client.initial_update(); // TODO: thread ?
1722 return v_client.inSession();
1726 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1729 * @return true if import was a success and a session was started.
1731 public boolean vamsasImport(File file)
1733 if (v_client != null)
1736 jalview.bin.Cache.log
1737 .error("Implementation error - load session from a running session is not supported.");
1741 setProgressBar("Importing VAMSAS session from " + file.getName(),
1745 v_client = new jalview.gui.VamsasApplication(this, file, null);
1746 } catch (Exception ex)
1748 setProgressBar("Importing VAMSAS session from " + file.getName(),
1750 jalview.bin.Cache.log.error(
1751 "New vamsas session from existing session file failed:", ex);
1754 setupVamsasConnectedGui();
1755 v_client.initial_update(); // TODO: thread ?
1756 setProgressBar("Importing VAMSAS session from " + file.getName(),
1758 return v_client.inSession();
1761 public boolean joinVamsasSession(String mysesid)
1763 if (v_client != null)
1766 "Trying to join a vamsas session when another is already connected.");
1768 if (mysesid == null)
1770 throw new Error("Invalid vamsas session id.");
1772 v_client = new VamsasApplication(this, mysesid);
1773 setupVamsasConnectedGui();
1774 v_client.initial_update();
1775 return (v_client.inSession());
1778 public void vamsasStart_actionPerformed(ActionEvent e)
1780 if (v_client == null)
1783 // we just start a default session for moment.
1785 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1786 * getProperty("LAST_DIRECTORY"));
1788 * chooser.setFileView(new JalviewFileView());
1789 * chooser.setDialogTitle("Load Vamsas file");
1790 * chooser.setToolTipText("Import");
1792 * int value = chooser.showOpenDialog(this);
1794 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1795 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1797 v_client = new VamsasApplication(this);
1798 setupVamsasConnectedGui();
1799 v_client.initial_update(); // TODO: thread ?
1803 // store current data in session.
1804 v_client.push_update(); // TODO: thread
1808 protected void setupVamsasConnectedGui()
1810 vamsasStart.setText("Session Update");
1811 vamsasSave.setVisible(true);
1812 vamsasStop.setVisible(true);
1813 vamsasImport.setVisible(false); // Document import to existing session is
1814 // not possible for vamsas-client-1.0.
1817 protected void setupVamsasDisconnectedGui()
1819 vamsasSave.setVisible(false);
1820 vamsasStop.setVisible(false);
1821 vamsasImport.setVisible(true);
1822 vamsasStart.setText("New Vamsas Session");
1825 public void vamsasStop_actionPerformed(ActionEvent e)
1827 if (v_client != null)
1829 v_client.end_session();
1831 setupVamsasDisconnectedGui();
1835 protected void buildVamsasStMenu()
1837 if (v_client == null)
1839 String[] sess = null;
1842 sess = VamsasApplication.getSessionList();
1843 } catch (Exception e)
1845 jalview.bin.Cache.log.warn(
1846 "Problem getting current sessions list.", e);
1851 jalview.bin.Cache.log.debug("Got current sessions list: "
1852 + sess.length + " entries.");
1853 VamsasStMenu.removeAll();
1854 for (int i = 0; i < sess.length; i++)
1856 JMenuItem sessit = new JMenuItem();
1857 sessit.setText(sess[i]);
1858 sessit.setToolTipText("Connect to session " + sess[i]);
1859 final Desktop dsktp = this;
1860 final String mysesid = sess[i];
1861 sessit.addActionListener(new ActionListener()
1864 public void actionPerformed(ActionEvent e)
1866 if (dsktp.v_client == null)
1868 Thread rthr = new Thread(new Runnable()
1873 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1874 dsktp.setupVamsasConnectedGui();
1875 dsktp.v_client.initial_update();
1883 VamsasStMenu.add(sessit);
1885 // don't show an empty menu.
1886 VamsasStMenu.setVisible(sess.length > 0);
1891 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1892 VamsasStMenu.removeAll();
1893 VamsasStMenu.setVisible(false);
1898 // Not interested in the content. Just hide ourselves.
1899 VamsasStMenu.setVisible(false);
1903 public void vamsasSave_actionPerformed(ActionEvent e)
1905 if (v_client != null)
1907 JalviewFileChooser chooser = new JalviewFileChooser(
1908 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1909 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1911 { "Vamsas Document" }, "Vamsas Document");
1913 chooser.setFileView(new JalviewFileView());
1914 chooser.setDialogTitle("Save Vamsas Document Archive");
1916 int value = chooser.showSaveDialog(this);
1918 if (value == JalviewFileChooser.APPROVE_OPTION)
1920 java.io.File choice = chooser.getSelectedFile();
1921 JPanel progpanel = addProgressPanel("Saving VAMSAS Document to "
1922 + choice.getName());
1923 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1924 String warnmsg = null;
1925 String warnttl = null;
1928 v_client.vclient.storeDocument(choice);
1931 warnttl = "Serious Problem saving Vamsas Document";
1932 warnmsg = ex.toString();
1933 jalview.bin.Cache.log.error("Error Whilst saving document to "
1936 } catch (Exception ex)
1938 warnttl = "Problem saving Vamsas Document.";
1939 warnmsg = ex.toString();
1940 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
1944 removeProgressPanel(progpanel);
1945 if (warnmsg != null)
1947 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1949 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
1955 JPanel vamUpdate = null;
1958 * hide vamsas user gui bits when a vamsas document event is being handled.
1961 * true to hide gui, false to reveal gui
1963 public void setVamsasUpdate(boolean b)
1965 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
1966 + (b ? "in progress" : "finished"));
1968 if (vamUpdate != null)
1970 this.removeProgressPanel(vamUpdate);
1974 vamUpdate = this.addProgressPanel("Updating vamsas session");
1976 vamsasStart.setVisible(!b);
1977 vamsasStop.setVisible(!b);
1978 vamsasSave.setVisible(!b);
1981 public JInternalFrame[] getAllFrames()
1983 return desktop.getAllFrames();
1987 * Checks the given url to see if it gives a response indicating that the user
1988 * should be informed of a new questionnaire.
1992 public void checkForQuestionnaire(String url)
1994 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
1995 // javax.swing.SwingUtilities.invokeLater(jvq);
1996 new Thread(jvq).start();
2000 * Proxy class for JDesktopPane which optionally displays the current memory
2001 * usage and highlights the desktop area with a red bar if free memory runs
2006 public class MyDesktopPane extends JDesktopPane implements Runnable
2009 boolean showMemoryUsage = false;
2013 java.text.NumberFormat df;
2015 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2018 public MyDesktopPane(boolean showMemoryUsage)
2020 showMemoryUsage(showMemoryUsage);
2023 public void showMemoryUsage(boolean showMemoryUsage)
2025 this.showMemoryUsage = showMemoryUsage;
2026 if (showMemoryUsage)
2028 Thread worker = new Thread(this);
2033 public boolean isShowMemoryUsage()
2035 return showMemoryUsage;
2040 df = java.text.NumberFormat.getNumberInstance();
2041 df.setMaximumFractionDigits(2);
2042 runtime = Runtime.getRuntime();
2044 while (showMemoryUsage)
2048 maxMemory = runtime.maxMemory() / 1048576f;
2049 allocatedMemory = runtime.totalMemory() / 1048576f;
2050 freeMemory = runtime.freeMemory() / 1048576f;
2051 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2053 percentUsage = (totalFreeMemory / maxMemory) * 100;
2055 // if (percentUsage < 20)
2057 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2059 // instance.set.setBorder(border1);
2062 // sleep after showing usage
2064 } catch (Exception ex)
2066 ex.printStackTrace();
2071 public void paintComponent(Graphics g)
2073 if (showMemoryUsage && g != null && df != null)
2075 if (percentUsage < 20)
2076 g.setColor(Color.red);
2077 FontMetrics fm = g.getFontMetrics();
2081 "Total Free Memory: " + df.format(totalFreeMemory)
2082 + "MB; Max Memory: " + df.format(maxMemory)
2083 + "MB; " + df.format(percentUsage) + "%", 10,
2084 getHeight() - fm.getHeight());
2092 * fixes stacking order after a modal dialog to ensure windows that should be on top actually are
2094 public void relayerWindows()
2099 protected JMenuItem groovyShell;
2101 public void doGroovyCheck()
2103 if (jalview.bin.Cache.groovyJarsPresent())
2105 groovyShell = new JMenuItem();
2106 groovyShell.setText("Groovy Console...");
2107 groovyShell.addActionListener(new ActionListener()
2109 public void actionPerformed(ActionEvent e)
2111 groovyShell_actionPerformed(e);
2114 toolsMenu.add(groovyShell);
2115 groovyShell.setVisible(true);
2120 * Accessor method to quickly get all the AlignmentFrames loaded.
2122 public static AlignFrame[] getAlignframes()
2124 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2130 Vector avp = new Vector();
2134 for (int i = frames.length - 1; i > -1; i--)
2136 if (frames[i] instanceof AlignFrame)
2138 AlignFrame af = (AlignFrame) frames[i];
2142 } catch (Exception ex)
2144 ex.printStackTrace();
2146 if (avp.size() == 0)
2150 AlignFrame afs[] = new AlignFrame[avp.size()];
2151 for (int i = 0, j = avp.size(); i < j; i++)
2153 afs[i] = (AlignFrame) avp.elementAt(i);
2158 public AppJmol[] getJmols()
2160 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2166 Vector avp = new Vector();
2170 for (int i = frames.length - 1; i > -1; i--)
2172 if (frames[i] instanceof AppJmol)
2174 AppJmol af = (AppJmol) frames[i];
2178 } catch (Exception ex)
2180 ex.printStackTrace();
2182 if (avp.size() == 0)
2186 AppJmol afs[] = new AppJmol[avp.size()];
2187 for (int i = 0, j = avp.size(); i < j; i++)
2189 afs[i] = (AppJmol) avp.elementAt(i);
2196 * Add Groovy Support to Jalview
2198 public void groovyShell_actionPerformed(ActionEvent e)
2200 // use reflection to avoid creating compilation dependency.
2201 if (!jalview.bin.Cache.groovyJarsPresent())
2204 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
2208 Class gcClass = Desktop.class.getClassLoader().loadClass(
2209 "groovy.ui.Console");
2210 Constructor gccons = gcClass.getConstructor(null);
2211 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2213 { String.class, Object.class });
2214 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2215 Object gc = gccons.newInstance(null);
2216 setvar.invoke(gc, new Object[]
2217 { "Jalview", this });
2218 run.invoke(gc, null);
2219 } catch (Exception ex)
2221 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2223 .showInternalMessageDialog(
2226 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
2227 "Jalview Groovy Support Failed",
2228 JOptionPane.ERROR_MESSAGE);
2233 * Progress bars managed by the IProgressIndicator method.
2235 private Hashtable<Long,JPanel> progressBars;
2236 private Hashtable<Long,IProgressIndicatorHandler> progressBarHandlers;
2241 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2243 public void setProgressBar(String message, long id)
2245 if (progressBars == null)
2247 progressBars = new Hashtable<Long,JPanel>();
2248 progressBarHandlers = new Hashtable<Long,IProgressIndicatorHandler>();
2251 if (progressBars.get(new Long(id)) != null)
2253 JPanel progressPanel = progressBars
2254 .remove(new Long(id));
2255 if (progressBarHandlers.contains(new Long(id)))
2257 progressBarHandlers.remove(new Long(id));
2259 removeProgressPanel(progressPanel);
2263 progressBars.put(new Long(id), addProgressPanel(message));
2270 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2271 * jalview.gui.IProgressIndicatorHandler)
2273 public void registerHandler(final long id,
2274 final IProgressIndicatorHandler handler)
2276 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2279 "call setProgressBar before registering the progress bar's handler.");
2281 progressBarHandlers.put(new Long(id), handler);
2282 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
2283 if (handler.canCancel())
2285 JButton cancel = new JButton("Cancel");
2286 final IProgressIndicator us = this;
2287 cancel.addActionListener(new ActionListener()
2290 public void actionPerformed(ActionEvent e)
2292 handler.cancelActivity(id);
2295 + ((JLabel) progressPanel.getComponent(0))
2299 progressPanel.add(cancel, BorderLayout.EAST);
2304 * This will return the first AlignFrame viewing AlignViewport av. It will
2305 * break if there are more than one AlignFrames viewing a particular av. This
2308 * @return alignFrame for av
2310 public static AlignFrame getAlignFrameFor(AlignViewport av)
2312 if (desktop != null)
2314 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2315 for (int panel = 0; aps != null && panel < aps.length; panel++)
2317 if (aps[panel] != null && aps[panel].av == av)
2319 return aps[panel].alignFrame;
2326 public VamsasApplication getVamsasApplication()
2333 * flag set if jalview GUI is being operated programmatically
2335 private boolean inBatchMode = false;
2338 * check if jalview GUI is being operated programmatically
2340 * @return inBatchMode
2342 public boolean isInBatchMode()
2348 * set flag if jalview GUI is being operated programmatically
2350 * @param inBatchMode
2352 public void setInBatchMode(boolean inBatchMode)
2354 this.inBatchMode = inBatchMode;
2357 public void startServiceDiscovery()
2359 startServiceDiscovery(false);
2362 public void startServiceDiscovery(boolean blocking)
2364 boolean alive = true;
2365 Thread t0 = null, t1 = null, t2 = null;
2367 // todo: changesupport handlers need to be transferred
2368 if (discoverer == null)
2370 discoverer = new jalview.ws.jws1.Discoverer();
2371 // register PCS handler for desktop.
2372 discoverer.addPropertyChangeListener(changeSupport);
2374 // JAL-940 - disabled JWS1 service configuration - always start discoverer until we phase out completely
2377 (t0 = new Thread(discoverer)).start();
2382 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2384 // EnfinEnvision web service menu entries are rebuild every time the
2385 // menu is shown, so no changeSupport events are needed.
2386 jalview.ws.EnfinEnvision2OneWay.getInstance();
2387 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2390 } catch (Exception e)
2393 .info("Exception when trying to launch Envision2 workflow discovery.",
2395 Cache.log.info(e.getStackTrace());
2397 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2399 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2401 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2403 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2409 // TODO: do rest service discovery
2418 } catch (Exception e)
2421 alive = (t1 != null && t1.isAlive())
2422 || (t2 != null && t2.isAlive())
2423 || (t3 != null && t3.isAlive())
2424 || (t0 != null && t0.isAlive());
2430 * called to check if the service discovery process completed successfully.
2434 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2436 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2438 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2439 .getErrorMessages();
2442 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2444 if (serviceChangedDialog == null)
2446 // only run if we aren't already displaying one of these.
2447 javax.swing.SwingUtilities
2448 .invokeLater(serviceChangedDialog = new Runnable()
2454 .showInternalMessageDialog(
2457 + "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",
2458 "Preferences Problem",
2459 JOptionPane.WARNING_MESSAGE);
2460 serviceChangedDialog = null;
2469 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2476 private Runnable serviceChangedDialog = null;
2479 * start a thread to open a URL in the configured browser. Pops up a warning
2480 * dialog to the user if there is an exception when calling out to the browser
2485 public static void showUrl(final String url)
2487 showUrl(url, Desktop.instance);
2490 * Like showUrl but allows progress handler to be specified
2492 * @param progress (null) or object implementing IProgressIndicator
2494 public static void showUrl(final String url, final IProgressIndicator progress)
2496 new Thread(new Runnable()
2502 if (progress!=null) {
2503 progress.setProgressBar("Opening "+url, this.hashCode());
2505 jalview.util.BrowserLauncher.openURL(url);
2506 } catch (Exception ex)
2509 .showInternalMessageDialog(
2511 "Unixers: Couldn't find default web browser."
2512 + "\nAdd the full path to your browser in Preferences.",
2513 "Web browser not found",
2514 JOptionPane.WARNING_MESSAGE);
2516 ex.printStackTrace();
2518 if (progress!=null) {
2519 progress.setProgressBar(null, this.hashCode());
2525 public static WsParamSetManager wsparamManager = null;
2527 public static ParamManager getUserParameterStore()
2529 if (wsparamManager == null)
2531 wsparamManager = new WsParamSetManager();
2533 return wsparamManager;