2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, 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 = new StringBuffer("Jalview version "
1053 + jalview.bin.Cache.getProperty("VERSION") + "; last updated: "
1054 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1056 if (!jalview.bin.Cache.getProperty("LATEST_VERSION").equals(
1057 jalview.bin.Cache.getProperty("VERSION")))
1059 message.append("\n\n!! Jalview version "
1060 + jalview.bin.Cache.getProperty("LATEST_VERSION")
1061 + " is available for download from "+jalview.bin.Cache.getDefault("www.jalview.org","http://www.jalview.org")+" !!\n");
1064 // TODO: update this text for each release or centrally store it for lite
1066 message.append("\nAuthors: Jim Procter, Andrew Waterhouse, Michele Clamp, James Cuff, Steve Searle,\n David Martin & Geoff Barton."
1067 + "\nDevelopment managed by The Barton Group, University of Dundee, Scotland, UK.\n"
1068 + "\nFor help, see the FAQ at www.jalview.org and/or join the jalview-discuss@jalview.org mailing list\n"
1069 + "\nIf you use Jalview, please cite:"
1070 + "\nWaterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1071 + "\nJalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1072 + "\nBioinformatics doi: 10.1093/bioinformatics/btp033");
1073 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1075 message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1084 public void documentationMenuItem_actionPerformed(ActionEvent e)
1088 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
1089 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
1090 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
1092 javax.help.HelpBroker hb = hs.createHelpBroker();
1093 hb.setCurrentID("home");
1094 hb.setDisplayed(true);
1095 } catch (Exception ex)
1100 public void closeAll_actionPerformed(ActionEvent e)
1102 JInternalFrame[] frames = desktop.getAllFrames();
1103 for (int i = 0; i < frames.length; i++)
1107 frames[i].setClosed(true);
1108 } catch (java.beans.PropertyVetoException ex)
1112 System.out.println("ALL CLOSED");
1113 if (v_client != null)
1115 // TODO clear binding to vamsas document objects on close_all
1120 public void raiseRelated_actionPerformed(ActionEvent e)
1122 reorderAssociatedWindows(false, false);
1125 public void minimizeAssociated_actionPerformed(ActionEvent e)
1127 reorderAssociatedWindows(true, false);
1130 void closeAssociatedWindows()
1132 reorderAssociatedWindows(false, true);
1138 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1141 protected void garbageCollect_actionPerformed(ActionEvent e)
1143 // We simply collect the garbage
1144 jalview.bin.Cache.log.debug("Collecting garbage...");
1146 jalview.bin.Cache.log.debug("Finished garbage collection.");
1153 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1156 protected void showMemusage_actionPerformed(ActionEvent e)
1158 desktop.showMemoryUsage(showMemusage.isSelected());
1165 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1168 protected void showConsole_actionPerformed(ActionEvent e)
1170 showConsole(showConsole.isSelected());
1173 Console jconsole = null;
1176 * control whether the java console is visible or not
1180 void showConsole(boolean selected)
1182 showConsole.setSelected(selected);
1183 // TODO: decide if we should update properties file
1184 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1186 jconsole.setVisible(selected);
1189 void reorderAssociatedWindows(boolean minimize, boolean close)
1191 JInternalFrame[] frames = desktop.getAllFrames();
1192 if (frames == null || frames.length < 1)
1197 AlignViewport source = null, target = null;
1198 if (frames[0] instanceof AlignFrame)
1200 source = ((AlignFrame) frames[0]).getCurrentView();
1202 else if (frames[0] instanceof TreePanel)
1204 source = ((TreePanel) frames[0]).getViewPort();
1206 else if (frames[0] instanceof PCAPanel)
1208 source = ((PCAPanel) frames[0]).av;
1210 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1212 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1217 for (int i = 0; i < frames.length; i++)
1220 if (frames[i] == null)
1224 if (frames[i] instanceof AlignFrame)
1226 target = ((AlignFrame) frames[i]).getCurrentView();
1228 else if (frames[i] instanceof TreePanel)
1230 target = ((TreePanel) frames[i]).getViewPort();
1232 else if (frames[i] instanceof PCAPanel)
1234 target = ((PCAPanel) frames[i]).av;
1236 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1238 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1241 if (source == target)
1247 frames[i].setClosed(true);
1251 frames[i].setIcon(minimize);
1254 frames[i].toFront();
1258 } catch (java.beans.PropertyVetoException ex)
1272 protected void preferences_actionPerformed(ActionEvent e)
1283 public void saveState_actionPerformed(ActionEvent e)
1285 JalviewFileChooser chooser = new JalviewFileChooser(
1286 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1287 { "jar" }, new String[]
1288 { "Jalview Project" }, "Jalview Project");
1290 chooser.setFileView(new JalviewFileView());
1291 chooser.setDialogTitle("Save State");
1293 int value = chooser.showSaveDialog(this);
1295 if (value == JalviewFileChooser.APPROVE_OPTION)
1297 final Desktop me = this;
1298 final java.io.File choice = chooser.getSelectedFile();
1299 new Thread(new Runnable()
1304 setProgressBar("Saving jalview project " + choice.getName(),
1306 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1307 // TODO catch and handle errors for savestate
1308 // TODO prevent user from messing with the Desktop whilst we're saving
1311 new Jalview2XML().SaveState(choice);
1312 } catch (OutOfMemoryError oom)
1315 "Whilst saving current state to " + choice.getName(), oom);
1316 } catch (Exception ex)
1319 .error("Problems whilst trying to save to "
1320 + choice.getName(), ex);
1321 JOptionPane.showMessageDialog(me,
1322 "Error whilst saving current state to " + choice.getName(),
1323 "Couldn't save project", JOptionPane.WARNING_MESSAGE);
1325 setProgressBar(null, choice.hashCode());
1337 public void loadState_actionPerformed(ActionEvent e)
1339 JalviewFileChooser chooser = new JalviewFileChooser(
1340 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1341 { "jar" }, new String[]
1342 { "Jalview Project" }, "Jalview Project");
1343 chooser.setFileView(new JalviewFileView());
1344 chooser.setDialogTitle("Restore state");
1346 int value = chooser.showOpenDialog(this);
1348 if (value == JalviewFileChooser.APPROVE_OPTION)
1350 final String choice = chooser.getSelectedFile().getAbsolutePath();
1351 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1352 .getSelectedFile().getParent());
1353 new Thread(new Runnable()
1357 setProgressBar("loading jalview project " + choice,
1361 new Jalview2XML().LoadJalviewAlign(choice);
1362 } catch (OutOfMemoryError oom)
1364 new OOMWarning("Whilst loading project from " + choice, oom);
1365 } catch (Exception ex)
1367 Cache.log.error("Problems whilst loading project from "
1369 JOptionPane.showMessageDialog(Desktop.desktop,
1370 "Error whilst loading project from " + choice,
1371 "Couldn't load project", JOptionPane.WARNING_MESSAGE);
1373 setProgressBar(null, choice.hashCode());
1379 public void inputSequence_actionPerformed(ActionEvent e)
1381 new SequenceFetcher(this);
1384 JPanel progressPanel;
1385 ArrayList<JPanel> fileLoadingPanels=new ArrayList<JPanel>();
1386 public void startLoading(final String fileName)
1388 if (fileLoadingCount == 0)
1390 fileLoadingPanels.add(addProgressPanel("Loading File: " + fileName + " "));
1395 private JPanel addProgressPanel(String string)
1397 if (progressPanel == null)
1399 progressPanel = new JPanel(new GridLayout(1,1));
1400 totalProgressCount = 0;
1401 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1403 JPanel thisprogress=new JPanel(new BorderLayout(10,5));
1404 JProgressBar progressBar = new JProgressBar();
1405 progressBar.setIndeterminate(true);
1407 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1409 thisprogress.add(progressBar, BorderLayout.CENTER);
1410 progressPanel.add(thisprogress);
1411 ((GridLayout)progressPanel.getLayout()).setRows(((GridLayout)progressPanel.getLayout()).getRows()+1);
1412 ++totalProgressCount;
1413 instance.validate();
1414 return thisprogress;
1417 int totalProgressCount = 0;
1419 private void removeProgressPanel(JPanel progbar)
1421 if (progressPanel != null)
1423 progressPanel.remove(progbar);
1424 GridLayout gl = (GridLayout) progressPanel.getLayout();
1425 gl.setRows(gl.getRows()-1);
1426 if (--totalProgressCount < 1)
1428 this.getContentPane().remove(progressPanel);
1429 progressPanel = null;
1435 public void stopLoading()
1438 if (fileLoadingCount < 1)
1440 for (JPanel flp : fileLoadingPanels)
1442 removeProgressPanel(flp);
1444 fileLoadingPanels.clear();
1445 fileLoadingCount = 0;
1450 public static int getViewCount(String alignmentId)
1452 AlignViewport[] aps = getViewports(alignmentId);
1453 return (aps == null) ? 0 : aps.length;
1458 * @param alignmentId
1459 * @return all AlignmentPanels concerning the alignmentId sequence set
1461 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1464 if (Desktop.desktop == null)
1466 // no frames created and in headless mode
1467 // TODO: verify that frames are recoverable when in headless mode
1470 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1471 ArrayList aps = new ArrayList();
1472 for (int t = 0; t < frames.length; t++)
1474 if (frames[t] instanceof AlignFrame)
1476 AlignFrame af = (AlignFrame) frames[t];
1477 for (int a = 0; a < af.alignPanels.size(); a++)
1480 .equals(((AlignmentPanel) af.alignPanels.elementAt(a)).av
1481 .getSequenceSetId()))
1483 aps.add(af.alignPanels.elementAt(a));
1488 if (aps.size() == 0)
1492 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1493 for (int t = 0; t < vap.length; t++)
1495 vap[t] = (AlignmentPanel) aps.get(t);
1501 * get all the viewports on an alignment.
1503 * @param sequenceSetId
1504 * unique alignment id
1505 * @return all viewports on the alignment bound to sequenceSetId
1507 public static AlignViewport[] getViewports(String sequenceSetId)
1509 Vector viewp = new Vector();
1510 if (desktop != null)
1512 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1514 for (int t = 0; t < frames.length; t++)
1516 if (frames[t] instanceof AlignFrame)
1518 AlignFrame afr = ((AlignFrame) frames[t]);
1519 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1521 if (afr.alignPanels != null)
1523 for (int a = 0; a < afr.alignPanels.size(); a++)
1525 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1526 .elementAt(a)).av.getSequenceSetId()))
1528 viewp.addElement(((AlignmentPanel) afr.alignPanels
1535 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1540 if (viewp.size() > 0)
1542 AlignViewport[] vp = new AlignViewport[viewp.size()];
1550 public void explodeViews(AlignFrame af)
1552 int size = af.alignPanels.size();
1558 for (int i = 0; i < size; i++)
1560 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1561 AlignFrame newaf = new AlignFrame(ap);
1562 if (ap.av.explodedPosition != null
1563 && !ap.av.explodedPosition.equals(af.getBounds()))
1565 newaf.setBounds(ap.av.explodedPosition);
1568 ap.av.gatherViewsHere = false;
1570 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1571 AlignFrame.DEFAULT_HEIGHT);
1574 af.alignPanels.clear();
1575 af.closeMenuItem_actionPerformed(true);
1579 public void gatherViews(AlignFrame source)
1581 source.viewport.gatherViewsHere = true;
1582 source.viewport.explodedPosition = source.getBounds();
1583 JInternalFrame[] frames = desktop.getAllFrames();
1584 String viewId = source.viewport.sequenceSetID;
1586 for (int t = 0; t < frames.length; t++)
1588 if (frames[t] instanceof AlignFrame && frames[t] != source)
1590 AlignFrame af = (AlignFrame) frames[t];
1591 boolean gatherThis = false;
1592 for (int a = 0; a < af.alignPanels.size(); a++)
1594 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1595 if (viewId.equals(ap.av.getSequenceSetId()))
1598 ap.av.gatherViewsHere = false;
1599 ap.av.explodedPosition = af.getBounds();
1600 source.addAlignmentPanel(ap, false);
1606 af.alignPanels.clear();
1607 af.closeMenuItem_actionPerformed(true);
1614 jalview.gui.VamsasApplication v_client = null;
1616 public void vamsasImport_actionPerformed(ActionEvent e)
1618 if (v_client == null)
1620 // Load and try to start a session.
1621 JalviewFileChooser chooser = new JalviewFileChooser(
1622 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1624 chooser.setFileView(new JalviewFileView());
1625 chooser.setDialogTitle("Open a saved VAMSAS session");
1626 chooser.setToolTipText("select a vamsas session to be opened as a new vamsas session.");
1628 int value = chooser.showOpenDialog(this);
1630 if (value == JalviewFileChooser.APPROVE_OPTION)
1632 String fle = chooser.getSelectedFile().toString();
1633 if (!vamsasImport(chooser.getSelectedFile()))
1635 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1636 "Couldn't import '" + fle + "' as a new vamsas session.",
1637 "Vamsas Document Import Failed",
1638 JOptionPane.ERROR_MESSAGE);
1644 jalview.bin.Cache.log
1645 .error("Implementation error - load session from a running session is not supported.");
1650 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1653 * @return true if import was a success and a session was started.
1655 public boolean vamsasImport(URL url)
1657 // TODO: create progress bar
1658 if (v_client != null)
1661 jalview.bin.Cache.log
1662 .error("Implementation error - load session from a running session is not supported.");
1668 // copy the URL content to a temporary local file
1669 // TODO: be a bit cleverer here with nio (?!)
1670 File file = File.createTempFile("vdocfromurl", ".vdj");
1671 FileOutputStream fos = new FileOutputStream(file);
1672 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1673 byte[] buffer = new byte[2048];
1675 while ((ln = bis.read(buffer)) > -1)
1677 fos.write(buffer, 0, ln);
1681 v_client = new jalview.gui.VamsasApplication(this, file,
1682 url.toExternalForm());
1683 } catch (Exception ex)
1685 jalview.bin.Cache.log.error(
1686 "Failed to create new vamsas session from contents of URL "
1690 setupVamsasConnectedGui();
1691 v_client.initial_update(); // TODO: thread ?
1692 return v_client.inSession();
1696 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1699 * @return true if import was a success and a session was started.
1701 public boolean vamsasImport(File file)
1703 if (v_client != null)
1706 jalview.bin.Cache.log
1707 .error("Implementation error - load session from a running session is not supported.");
1711 setProgressBar("Importing VAMSAS session from " + file.getName(),
1715 v_client = new jalview.gui.VamsasApplication(this, file, null);
1716 } catch (Exception ex)
1718 setProgressBar("Importing VAMSAS session from " + file.getName(),
1720 jalview.bin.Cache.log.error(
1721 "New vamsas session from existing session file failed:", ex);
1724 setupVamsasConnectedGui();
1725 v_client.initial_update(); // TODO: thread ?
1726 setProgressBar("Importing VAMSAS session from " + file.getName(),
1728 return v_client.inSession();
1731 public boolean joinVamsasSession(String mysesid)
1733 if (v_client != null)
1736 "Trying to join a vamsas session when another is already connected.");
1738 if (mysesid == null)
1740 throw new Error("Invalid vamsas session id.");
1742 v_client = new VamsasApplication(this, mysesid);
1743 setupVamsasConnectedGui();
1744 v_client.initial_update();
1745 return (v_client.inSession());
1748 public void vamsasStart_actionPerformed(ActionEvent e)
1750 if (v_client == null)
1753 // we just start a default session for moment.
1755 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1756 * getProperty("LAST_DIRECTORY"));
1758 * chooser.setFileView(new JalviewFileView());
1759 * chooser.setDialogTitle("Load Vamsas file");
1760 * chooser.setToolTipText("Import");
1762 * int value = chooser.showOpenDialog(this);
1764 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1765 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1767 v_client = new VamsasApplication(this);
1768 setupVamsasConnectedGui();
1769 v_client.initial_update(); // TODO: thread ?
1773 // store current data in session.
1774 v_client.push_update(); // TODO: thread
1778 protected void setupVamsasConnectedGui()
1780 vamsasStart.setText("Session Update");
1781 vamsasSave.setVisible(true);
1782 vamsasStop.setVisible(true);
1783 vamsasImport.setVisible(false); // Document import to existing session is
1784 // not possible for vamsas-client-1.0.
1787 protected void setupVamsasDisconnectedGui()
1789 vamsasSave.setVisible(false);
1790 vamsasStop.setVisible(false);
1791 vamsasImport.setVisible(true);
1792 vamsasStart.setText("New Vamsas Session");
1795 public void vamsasStop_actionPerformed(ActionEvent e)
1797 if (v_client != null)
1799 v_client.end_session();
1801 setupVamsasDisconnectedGui();
1805 protected void buildVamsasStMenu()
1807 if (v_client == null)
1809 String[] sess = null;
1812 sess = VamsasApplication.getSessionList();
1813 } catch (Exception e)
1815 jalview.bin.Cache.log.warn(
1816 "Problem getting current sessions list.", e);
1821 jalview.bin.Cache.log.debug("Got current sessions list: "
1822 + sess.length + " entries.");
1823 VamsasStMenu.removeAll();
1824 for (int i = 0; i < sess.length; i++)
1826 JMenuItem sessit = new JMenuItem();
1827 sessit.setText(sess[i]);
1828 sessit.setToolTipText("Connect to session " + sess[i]);
1829 final Desktop dsktp = this;
1830 final String mysesid = sess[i];
1831 sessit.addActionListener(new ActionListener()
1834 public void actionPerformed(ActionEvent e)
1836 if (dsktp.v_client == null)
1838 Thread rthr = new Thread(new Runnable()
1843 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1844 dsktp.setupVamsasConnectedGui();
1845 dsktp.v_client.initial_update();
1853 VamsasStMenu.add(sessit);
1855 // don't show an empty menu.
1856 VamsasStMenu.setVisible(sess.length > 0);
1861 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1862 VamsasStMenu.removeAll();
1863 VamsasStMenu.setVisible(false);
1868 // Not interested in the content. Just hide ourselves.
1869 VamsasStMenu.setVisible(false);
1873 public void vamsasSave_actionPerformed(ActionEvent e)
1875 if (v_client != null)
1877 JalviewFileChooser chooser = new JalviewFileChooser(
1878 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1879 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1881 { "Vamsas Document" }, "Vamsas Document");
1883 chooser.setFileView(new JalviewFileView());
1884 chooser.setDialogTitle("Save Vamsas Document Archive");
1886 int value = chooser.showSaveDialog(this);
1888 if (value == JalviewFileChooser.APPROVE_OPTION)
1890 java.io.File choice = chooser.getSelectedFile();
1891 JPanel progpanel = addProgressPanel("Saving VAMSAS Document to "
1892 + choice.getName());
1893 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1894 String warnmsg = null;
1895 String warnttl = null;
1898 v_client.vclient.storeDocument(choice);
1901 warnttl = "Serious Problem saving Vamsas Document";
1902 warnmsg = ex.toString();
1903 jalview.bin.Cache.log.error("Error Whilst saving document to "
1906 } catch (Exception ex)
1908 warnttl = "Problem saving Vamsas Document.";
1909 warnmsg = ex.toString();
1910 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
1914 removeProgressPanel(progpanel);
1915 if (warnmsg != null)
1917 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1919 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
1925 JPanel vamUpdate = null;
1928 * hide vamsas user gui bits when a vamsas document event is being handled.
1931 * true to hide gui, false to reveal gui
1933 public void setVamsasUpdate(boolean b)
1935 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
1936 + (b ? "in progress" : "finished"));
1938 if (vamUpdate != null)
1940 this.removeProgressPanel(vamUpdate);
1944 vamUpdate = this.addProgressPanel("Updating vamsas session");
1946 vamsasStart.setVisible(!b);
1947 vamsasStop.setVisible(!b);
1948 vamsasSave.setVisible(!b);
1951 public JInternalFrame[] getAllFrames()
1953 return desktop.getAllFrames();
1957 * Checks the given url to see if it gives a response indicating that the user
1958 * should be informed of a new questionnaire.
1962 public void checkForQuestionnaire(String url)
1964 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
1965 // javax.swing.SwingUtilities.invokeLater(jvq);
1966 new Thread(jvq).start();
1970 * Proxy class for JDesktopPane which optionally displays the current memory
1971 * usage and highlights the desktop area with a red bar if free memory runs
1976 public class MyDesktopPane extends JDesktopPane implements Runnable
1979 boolean showMemoryUsage = false;
1983 java.text.NumberFormat df;
1985 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
1988 public MyDesktopPane(boolean showMemoryUsage)
1990 showMemoryUsage(showMemoryUsage);
1993 public void showMemoryUsage(boolean showMemoryUsage)
1995 this.showMemoryUsage = showMemoryUsage;
1996 if (showMemoryUsage)
1998 Thread worker = new Thread(this);
2003 public boolean isShowMemoryUsage()
2005 return showMemoryUsage;
2010 df = java.text.NumberFormat.getNumberInstance();
2011 df.setMaximumFractionDigits(2);
2012 runtime = Runtime.getRuntime();
2014 while (showMemoryUsage)
2018 maxMemory = runtime.maxMemory() / 1048576f;
2019 allocatedMemory = runtime.totalMemory() / 1048576f;
2020 freeMemory = runtime.freeMemory() / 1048576f;
2021 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2023 percentUsage = (totalFreeMemory / maxMemory) * 100;
2025 // if (percentUsage < 20)
2027 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2029 // instance.set.setBorder(border1);
2032 // sleep after showing usage
2034 } catch (Exception ex)
2036 ex.printStackTrace();
2041 public void paintComponent(Graphics g)
2043 if (showMemoryUsage && g != null && df != null)
2045 if (percentUsage < 20)
2046 g.setColor(Color.red);
2047 FontMetrics fm = g.getFontMetrics();
2051 "Total Free Memory: " + df.format(totalFreeMemory)
2052 + "MB; Max Memory: " + df.format(maxMemory)
2053 + "MB; " + df.format(percentUsage) + "%", 10,
2054 getHeight() - fm.getHeight());
2061 * fixes stacking order after a modal dialog to ensure windows that should be on top actually are
2063 public void relayerWindows()
2068 protected JMenuItem groovyShell;
2070 public void doGroovyCheck()
2072 if (jalview.bin.Cache.groovyJarsPresent())
2074 groovyShell = new JMenuItem();
2075 groovyShell.setText("Groovy Console...");
2076 groovyShell.addActionListener(new ActionListener()
2078 public void actionPerformed(ActionEvent e)
2080 groovyShell_actionPerformed(e);
2083 toolsMenu.add(groovyShell);
2084 groovyShell.setVisible(true);
2089 * Accessor method to quickly get all the AlignmentFrames loaded.
2091 public static AlignFrame[] getAlignframes()
2093 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2099 Vector avp = new Vector();
2103 for (int i = frames.length - 1; i > -1; i--)
2105 if (frames[i] instanceof AlignFrame)
2107 AlignFrame af = (AlignFrame) frames[i];
2111 } catch (Exception ex)
2113 ex.printStackTrace();
2115 if (avp.size() == 0)
2119 AlignFrame afs[] = new AlignFrame[avp.size()];
2120 for (int i = 0, j = avp.size(); i < j; i++)
2122 afs[i] = (AlignFrame) avp.elementAt(i);
2127 public AppJmol[] getJmols()
2129 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2135 Vector avp = new Vector();
2139 for (int i = frames.length - 1; i > -1; i--)
2141 if (frames[i] instanceof AppJmol)
2143 AppJmol af = (AppJmol) frames[i];
2147 } catch (Exception ex)
2149 ex.printStackTrace();
2151 if (avp.size() == 0)
2155 AppJmol afs[] = new AppJmol[avp.size()];
2156 for (int i = 0, j = avp.size(); i < j; i++)
2158 afs[i] = (AppJmol) avp.elementAt(i);
2165 * Add Groovy Support to Jalview
2167 public void groovyShell_actionPerformed(ActionEvent e)
2169 // use reflection to avoid creating compilation dependency.
2170 if (!jalview.bin.Cache.groovyJarsPresent())
2173 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
2177 Class gcClass = Desktop.class.getClassLoader().loadClass(
2178 "groovy.ui.Console");
2179 Constructor gccons = gcClass.getConstructor(null);
2180 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2182 { String.class, Object.class });
2183 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2184 Object gc = gccons.newInstance(null);
2185 setvar.invoke(gc, new Object[]
2186 { "Jalview", this });
2187 run.invoke(gc, null);
2188 } catch (Exception ex)
2190 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2192 .showInternalMessageDialog(
2195 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
2196 "Jalview Groovy Support Failed",
2197 JOptionPane.ERROR_MESSAGE);
2202 * Progress bars managed by the IProgressIndicator method.
2204 private Hashtable<Long,JPanel> progressBars;
2205 private Hashtable<Long,IProgressIndicatorHandler> progressBarHandlers;
2210 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2212 public void setProgressBar(String message, long id)
2214 if (progressBars == null)
2216 progressBars = new Hashtable<Long,JPanel>();
2217 progressBarHandlers = new Hashtable<Long,IProgressIndicatorHandler>();
2220 if (progressBars.get(new Long(id)) != null)
2222 JPanel progressPanel = progressBars
2223 .remove(new Long(id));
2224 if (progressBarHandlers.contains(new Long(id)))
2226 progressBarHandlers.remove(new Long(id));
2228 removeProgressPanel(progressPanel);
2232 progressBars.put(new Long(id), addProgressPanel(message));
2239 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2240 * jalview.gui.IProgressIndicatorHandler)
2242 public void registerHandler(final long id,
2243 final IProgressIndicatorHandler handler)
2245 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2248 "call setProgressBar before registering the progress bar's handler.");
2250 progressBarHandlers.put(new Long(id), handler);
2251 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
2252 if (handler.canCancel())
2254 JButton cancel = new JButton("Cancel");
2255 final IProgressIndicator us = this;
2256 cancel.addActionListener(new ActionListener()
2259 public void actionPerformed(ActionEvent e)
2261 handler.cancelActivity(id);
2264 + ((JLabel) progressPanel.getComponent(0))
2268 progressPanel.add(cancel, BorderLayout.EAST);
2273 * This will return the first AlignFrame viewing AlignViewport av. It will
2274 * break if there are more than one AlignFrames viewing a particular av. This
2277 * @return alignFrame for av
2279 public static AlignFrame getAlignFrameFor(AlignViewport av)
2281 if (desktop != null)
2283 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2284 for (int panel = 0; aps != null && panel < aps.length; panel++)
2286 if (aps[panel] != null && aps[panel].av == av)
2288 return aps[panel].alignFrame;
2295 public VamsasApplication getVamsasApplication()
2302 * flag set if jalview GUI is being operated programmatically
2304 private boolean inBatchMode = false;
2307 * check if jalview GUI is being operated programmatically
2309 * @return inBatchMode
2311 public boolean isInBatchMode()
2317 * set flag if jalview GUI is being operated programmatically
2319 * @param inBatchMode
2321 public void setInBatchMode(boolean inBatchMode)
2323 this.inBatchMode = inBatchMode;
2326 public void startServiceDiscovery()
2328 startServiceDiscovery(false);
2331 public void startServiceDiscovery(boolean blocking)
2333 boolean alive = true;
2334 Thread t0 = null, t1 = null, t2 = null;
2336 // todo: changesupport handlers need to be transferred
2337 if (discoverer == null)
2339 discoverer = new jalview.ws.jws1.Discoverer();
2340 // register PCS handler for desktop.
2341 discoverer.addPropertyChangeListener(changeSupport);
2343 // JAL-940 - disabled JWS1 service configuration - always start discoverer until we phase out completely
2346 (t0 = new Thread(discoverer)).start();
2351 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2353 // EnfinEnvision web service menu entries are rebuild every time the
2354 // menu is shown, so no changeSupport events are needed.
2355 jalview.ws.EnfinEnvision2OneWay.getInstance();
2356 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2359 } catch (Exception e)
2362 .info("Exception when trying to launch Envision2 workflow discovery.",
2364 Cache.log.info(e.getStackTrace());
2366 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2368 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2370 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2372 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2378 // TODO: do rest service discovery
2387 } catch (Exception e)
2390 alive = (t1 != null && t1.isAlive())
2391 || (t2 != null && t2.isAlive())
2392 || (t3 != null && t3.isAlive())
2393 || (t0 != null && t0.isAlive());
2399 * called to check if the service discovery process completed successfully.
2403 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2405 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2407 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2408 .getErrorMessages();
2411 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2413 if (serviceChangedDialog == null)
2415 // only run if we aren't already displaying one of these.
2416 javax.swing.SwingUtilities
2417 .invokeLater(serviceChangedDialog = new Runnable()
2423 .showInternalMessageDialog(
2426 + "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",
2427 "Preferences Problem",
2428 JOptionPane.WARNING_MESSAGE);
2429 serviceChangedDialog = null;
2438 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2445 private Runnable serviceChangedDialog = null;
2448 * start a thread to open a URL in the configured browser. Pops up a warning
2449 * dialog to the user if there is an exception when calling out to the browser
2454 public static void showUrl(final String url)
2456 showUrl(url, Desktop.instance);
2459 * Like showUrl but allows progress handler to be specified
2461 * @param progress (null) or object implementing IProgressIndicator
2463 public static void showUrl(final String url, final IProgressIndicator progress)
2465 new Thread(new Runnable()
2471 if (progress!=null) {
2472 progress.setProgressBar("Opening "+url, this.hashCode());
2474 jalview.util.BrowserLauncher.openURL(url);
2475 } catch (Exception ex)
2478 .showInternalMessageDialog(
2480 "Unixers: Couldn't find default web browser."
2481 + "\nAdd the full path to your browser in Preferences.",
2482 "Web browser not found",
2483 JOptionPane.WARNING_MESSAGE);
2485 ex.printStackTrace();
2487 if (progress!=null) {
2488 progress.setProgressBar(null, this.hashCode());
2494 public static WsParamSetManager wsparamManager = null;
2496 public static ParamManager getUserParameterStore()
2498 if (wsparamManager == null)
2500 wsparamManager = new WsParamSetManager();
2502 return wsparamManager;