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)
211 delegate.dragFrame(f, newX, newY);
214 public void endDraggingFrame(JComponent f)
216 delegate.endDraggingFrame(f);
219 public void endResizingFrame(JComponent f)
221 delegate.endResizingFrame(f);
224 public void iconifyFrame(JInternalFrame f)
226 delegate.iconifyFrame(f);
229 public void maximizeFrame(JInternalFrame f)
231 delegate.maximizeFrame(f);
234 public void minimizeFrame(JInternalFrame f)
236 delegate.minimizeFrame(f);
239 public void openFrame(JInternalFrame f)
241 delegate.openFrame(f);
244 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
247 Rectangle b=desktop.getBounds();
252 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
255 public void setBoundsForFrame(JComponent f, int newX, int newY,
256 int newWidth, int newHeight)
258 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
261 // All other methods, simply delegate
266 * Creates a new Desktop object.
271 * A note to implementors. It is ESSENTIAL that any activities that might
272 * block are spawned off as threads rather than waited for during this
276 doVamsasClientCheck();
279 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
280 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
281 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
283 boolean showjconsole = jalview.bin.Cache.getDefault(
284 "SHOW_JAVA_CONSOLE", false);
285 desktop = new MyDesktopPane(selmemusage);
286 showMemusage.setSelected(selmemusage);
287 desktop.setBackground(Color.white);
288 getContentPane().setLayout(new BorderLayout());
289 // alternate config - have scrollbars - see notes in JAL-153
290 //JScrollPane sp = new JScrollPane();
291 //sp.getViewport().setView(desktop);
292 //getContentPane().add(sp, BorderLayout.CENTER);
293 getContentPane().add(desktop, BorderLayout.CENTER);
294 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
297 // This line prevents Windows Look&Feel resizing all new windows to maximum
298 // if previous window was maximised
299 desktop.setDesktopManager(new MyDesktopManager(
300 new DefaultDesktopManager()));
302 Rectangle dims = getLastKnownDimensions("");
309 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
310 setBounds((int) (screenSize.width - 900) / 2,
311 (int) (screenSize.height - 650) / 2, 900, 650);
313 jconsole = new Console(this, showjconsole);
314 // add essential build information
315 jconsole.setHeader("Jalview Desktop "
316 + jalview.bin.Cache.getProperty("VERSION") + "\n"
318 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
319 + "Java version: " + System.getProperty("java.version") + "\n"
320 + System.getProperty("os.arch") + " "
321 + System.getProperty("os.name") + " "
322 + System.getProperty("os.version"));
324 showConsole(showjconsole);
326 showNews.setVisible(false);
327 final Desktop me = this;
328 // Thread off the news reader, in case there are connection problems.
329 new Thread( new Runnable() {
333 Cache.log.debug("Starting news thread.");
335 jvnews = new BlogReader(me);
336 showNews.setVisible(true);
337 Cache.log.debug("Completed news thread.");
341 this.addWindowListener(new WindowAdapter()
343 public void windowClosing(WindowEvent evt)
350 this.addMouseListener(ma=new MouseAdapter()
352 public void mousePressed(MouseEvent evt)
354 if (SwingUtilities.isRightMouseButton(evt))
356 showPasteMenu(evt.getX(), evt.getY());
360 desktop.addMouseListener(ma);
362 this.addFocusListener(new FocusListener()
366 public void focusLost(FocusEvent e)
368 // TODO Auto-generated method stub
373 public void focusGained(FocusEvent e)
375 Cache.log.debug("Relaying windows after focus gain");
376 // make sure that we sort windows properly after we gain focus
377 instance.relayerWindows();
380 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
381 // Spawn a thread that shows the splashscreen
382 SwingUtilities.invokeLater(new Runnable()
391 // Thread off a new instance of the file chooser - this reduces the time it
392 // takes to open it later on.
393 new Thread(new Runnable()
397 Cache.log.debug("Filechooser init thread started.");
398 JalviewFileChooser chooser = new JalviewFileChooser(
399 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
400 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
401 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
402 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
403 Cache.log.debug("Filechooser init thread finished.");
406 // Add the service change listener
407 changeSupport.addJalviewPropertyChangeListener("services",
408 new PropertyChangeListener()
412 public void propertyChange(PropertyChangeEvent evt)
414 Cache.log.debug("Firing service changed event for "
415 + evt.getNewValue());
416 JalviewServicesChanged(evt);
422 protected void showNews_actionPerformed(ActionEvent e)
424 showNews(showNews.isSelected());
426 void showNews(boolean visible)
429 Cache.log.debug((visible?"Showing":"Hiding")+" news.");
430 showNews.setSelected(visible);
431 if (visible && !jvnews.isVisible())
433 new Thread(new Runnable() {
437 long instance=System.currentTimeMillis();
438 Desktop.instance.setProgressBar("Refreshing news", instance);
439 jvnews.refreshNews();
440 Desktop.instance.setProgressBar(null, instance);
449 * recover the last known dimensions for a jalview window
452 * - empty string is desktop, all other windows have unique prefix
453 * @return null or last known dimensions scaled to current geometry (if last
454 * window geom was known)
456 Rectangle getLastKnownDimensions(String windowName)
458 // TODO: lock aspect ratio for scaling desktop Bug #0058199
459 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
460 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
461 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
462 String width = jalview.bin.Cache.getProperty(windowName
464 String height = jalview.bin.Cache.getProperty(windowName
466 if ((x != null) && (y != null) && (width != null) && (height != null))
468 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
469 .parseInt(width), ih = Integer.parseInt(height);
470 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
472 // attempt #1 - try to cope with change in screen geometry - this
473 // version doesn't preserve original jv aspect ratio.
474 // take ratio of current screen size vs original screen size.
475 double sw = ((1f * screenSize.width) / (1f * Integer
476 .parseInt(jalview.bin.Cache
477 .getProperty("SCREENGEOMETRY_WIDTH"))));
478 double sh = ((1f * screenSize.height) / (1f * Integer
479 .parseInt(jalview.bin.Cache
480 .getProperty("SCREENGEOMETRY_HEIGHT"))));
481 // rescale the bounds depending upon the current screen geometry.
482 ix = (int) (ix * sw);
483 iw = (int) (iw * sw);
484 iy = (int) (iy * sh);
485 ih = (int) (ih * sh);
486 while (ix >= screenSize.width)
488 jalview.bin.Cache.log
489 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
490 ix -= screenSize.width;
492 while (iy >= screenSize.height)
494 jalview.bin.Cache.log
495 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
496 iy -= screenSize.height;
498 jalview.bin.Cache.log.debug("Got last known dimensions for "
499 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
502 // return dimensions for new instance
503 return new Rectangle(ix, iy, iw, ih);
508 private void doVamsasClientCheck()
510 if (jalview.bin.Cache.vamsasJarsPresent())
512 setupVamsasDisconnectedGui();
513 VamsasMenu.setVisible(true);
514 final Desktop us = this;
515 VamsasMenu.addMenuListener(new MenuListener()
517 // this listener remembers when the menu was first selected, and
518 // doesn't rebuild the session list until it has been cleared and
520 boolean refresh = true;
522 public void menuCanceled(MenuEvent e)
527 public void menuDeselected(MenuEvent e)
532 public void menuSelected(MenuEvent e)
536 us.buildVamsasStMenu();
541 vamsasStart.setVisible(true);
545 void showPasteMenu(int x, int y)
547 JPopupMenu popup = new JPopupMenu();
548 JMenuItem item = new JMenuItem("Paste To New Window");
549 item.addActionListener(new ActionListener()
551 public void actionPerformed(ActionEvent evt)
558 popup.show(this, x, y);
565 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
566 Transferable contents = c.getContents(this);
568 if (contents != null)
570 String file = (String) contents
571 .getTransferData(DataFlavor.stringFlavor);
573 String format = new IdentifyFile().Identify(file,
574 FormatAdapter.PASTE);
576 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
579 } catch (Exception ex)
582 .println("Unable to paste alignment from system clipboard:\n"
588 * Adds and opens the given frame to the desktop
599 public static synchronized void addInternalFrame(
600 final JInternalFrame frame, String title, int w, int h)
602 addInternalFrame(frame, title, w, h, true);
619 public static synchronized void addInternalFrame(
620 final JInternalFrame frame, String title, int w, int h,
624 // TODO: allow callers to determine X and Y position of frame (eg. via
626 // TODO: consider fixing method to update entries in the window submenu with
627 // the current window title
629 frame.setTitle(title);
630 if (frame.getWidth() < 1 || frame.getHeight() < 1)
634 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
635 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
636 // IF JALVIEW IS RUNNING HEADLESS
637 // ///////////////////////////////////////////////
638 if (System.getProperty("java.awt.headless") != null
639 && System.getProperty("java.awt.headless").equals("true"))
646 frame.setVisible(true);
647 frame.setClosable(true);
648 frame.setResizable(resizable);
649 frame.setMaximizable(resizable);
650 frame.setIconifiable(resizable);
651 frame.setFrameIcon(null);
653 if (frame.getX() < 1 && frame.getY() < 1)
655 frame.setLocation(xOffset * openFrameCount, yOffset
656 * ((openFrameCount - 1) % 10) + yOffset);
659 final JMenuItem menuItem = new JMenuItem(title);
660 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
662 public void internalFrameActivated(
663 javax.swing.event.InternalFrameEvent evt)
665 JInternalFrame itf = desktop.getSelectedFrame();
673 public void internalFrameClosed(
674 javax.swing.event.InternalFrameEvent evt)
676 PaintRefresher.RemoveComponent(frame);
678 windowMenu.remove(menuItem);
679 JInternalFrame itf = desktop.getSelectedFrame();
688 menuItem.addActionListener(new ActionListener()
690 public void actionPerformed(ActionEvent e)
694 frame.setSelected(true);
695 frame.setIcon(false);
696 } catch (java.beans.PropertyVetoException ex)
702 menuItem.addMouseListener(new MouseListener()
706 public void mouseReleased(MouseEvent e)
711 public void mousePressed(MouseEvent e)
716 public void mouseExited(MouseEvent e)
720 frame.setSelected(false);
721 } catch (PropertyVetoException e1)
727 public void mouseEntered(MouseEvent e)
731 frame.setSelected(true);
732 } catch (PropertyVetoException e1)
738 public void mouseClicked(MouseEvent e)
744 windowMenu.add(menuItem);
750 frame.setSelected(true);
751 frame.requestFocus();
752 } catch (java.beans.PropertyVetoException ve)
755 catch (java.lang.ClassCastException cex)
757 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);
761 public void lostOwnership(Clipboard clipboard, Transferable contents)
765 Desktop.jalviewClipboard = null;
768 internalCopy = false;
771 public void dragEnter(DropTargetDragEvent evt)
775 public void dragExit(DropTargetEvent evt)
779 public void dragOver(DropTargetDragEvent evt)
783 public void dropActionChanged(DropTargetDragEvent evt)
793 public void drop(DropTargetDropEvent evt)
795 Transferable t = evt.getTransferable();
796 java.util.List files = null;
797 java.util.List protocols = null;
801 DataFlavor uriListFlavor = new DataFlavor(
802 "text/uri-list;class=java.lang.String");
803 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
805 // Works on Windows and MacOSX
806 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
807 files = (java.util.List) t
808 .getTransferData(DataFlavor.javaFileListFlavor);
810 else if (t.isDataFlavorSupported(uriListFlavor))
812 // This is used by Unix drag system
813 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
814 String data = (String) t.getTransferData(uriListFlavor);
815 files = new java.util.ArrayList(1);
816 protocols = new java.util.ArrayList(1);
817 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
818 data, "\r\n"); st.hasMoreTokens();)
820 String s = st.nextToken();
821 if (s.startsWith("#"))
823 // the line is a comment (as per the RFC 2483)
826 java.net.URI uri = new java.net.URI(s);
827 if (uri.getScheme().toLowerCase().startsWith("http"))
829 protocols.add(FormatAdapter.URL);
830 files.add(uri.toString());
834 // otherwise preserve old behaviour: catch all for file objects
835 java.io.File file = new java.io.File(uri);
836 protocols.add(FormatAdapter.FILE);
837 files.add(file.toString());
841 } catch (Exception e)
849 for (int i = 0; i < files.size(); i++)
851 String file = files.get(i).toString();
852 String protocol = (protocols == null) ? FormatAdapter.FILE
853 : (String) protocols.get(i);
854 String format = null;
856 if (file.endsWith(".jar"))
863 format = new IdentifyFile().Identify(file, protocol);
866 new FileLoader().LoadFile(file, protocol, format);
869 } catch (Exception ex)
881 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
883 JalviewFileChooser chooser = new JalviewFileChooser(
884 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
885 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
886 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
887 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
889 chooser.setFileView(new JalviewFileView());
890 chooser.setDialogTitle("Open local file");
891 chooser.setToolTipText("Open");
893 int value = chooser.showOpenDialog(this);
895 if (value == JalviewFileChooser.APPROVE_OPTION)
897 String choice = chooser.getSelectedFile().getPath();
898 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
899 .getSelectedFile().getParent());
901 String format = null;
902 if (chooser.getSelectedFormat().equals("Jalview"))
908 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
911 if (viewport != null)
913 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
918 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
929 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
931 // This construct allows us to have a wider textfield
933 JLabel label = new JLabel("Enter URL of Input File");
934 final JComboBox history = new JComboBox();
936 JPanel panel = new JPanel(new GridLayout(2, 1));
939 history.setPreferredSize(new Dimension(400, 20));
940 history.setEditable(true);
941 history.addItem("http://www.");
943 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
947 if (historyItems != null)
949 st = new StringTokenizer(historyItems, "\t");
951 while (st.hasMoreTokens())
953 history.addItem(st.nextElement());
957 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
958 "Input Alignment From URL", JOptionPane.OK_CANCEL_OPTION);
960 if (reply != JOptionPane.OK_OPTION)
965 String url = history.getSelectedItem().toString();
967 if (url.toLowerCase().endsWith(".jar"))
969 if (viewport != null)
971 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
976 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
981 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
983 if (format.equals("URL NOT FOUND"))
985 JOptionPane.showInternalMessageDialog(Desktop.desktop,
986 "Couldn't locate " + url, "URL not found",
987 JOptionPane.WARNING_MESSAGE);
992 if (viewport != null)
994 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
998 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1009 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1011 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1012 cap.setForInput(viewport);
1013 Desktop.addInternalFrame(cap, "Cut & Paste Alignment File", 600, 500);
1021 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1023 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1024 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1026 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1027 getBounds().y, getWidth(), getHeight()));
1029 if (jconsole != null)
1031 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1032 jconsole.stopConsole();
1036 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1043 private void storeLastKnownDimensions(String string, Rectangle jc)
1045 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1046 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1047 + " height:" + jc.height);
1049 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1050 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1051 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1052 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1061 public void aboutMenuItem_actionPerformed(ActionEvent e)
1063 StringBuffer message = new StringBuffer("Jalview version "
1064 + jalview.bin.Cache.getProperty("VERSION") + "; last updated: "
1065 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1067 if (!jalview.bin.Cache.getProperty("LATEST_VERSION").equals(
1068 jalview.bin.Cache.getProperty("VERSION")))
1070 message.append("\n\n!! Jalview version "
1071 + jalview.bin.Cache.getProperty("LATEST_VERSION")
1072 + " is available for download from "+jalview.bin.Cache.getDefault("www.jalview.org","http://www.jalview.org")+" !!\n");
1075 // TODO: update this text for each release or centrally store it for lite
1077 message.append("\nAuthors: Jim Procter, Andrew Waterhouse, Michele Clamp, James Cuff, Steve Searle,\n David Martin & Geoff Barton."
1078 + "\nDevelopment managed by The Barton Group, University of Dundee, Scotland, UK.\n"
1079 + "\nFor help, see the FAQ at www.jalview.org and/or join the jalview-discuss@jalview.org mailing list\n"
1080 + "\nIf you use Jalview, please cite:"
1081 + "\nWaterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1082 + "\nJalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1083 + "\nBioinformatics doi: 10.1093/bioinformatics/btp033");
1084 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1086 message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1095 public void documentationMenuItem_actionPerformed(ActionEvent e)
1099 ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();
1100 java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");
1101 javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);
1103 javax.help.HelpBroker hb = hs.createHelpBroker();
1104 hb.setCurrentID("home");
1105 hb.setDisplayed(true);
1106 } catch (Exception ex)
1111 public void closeAll_actionPerformed(ActionEvent e)
1113 JInternalFrame[] frames = desktop.getAllFrames();
1114 for (int i = 0; i < frames.length; i++)
1118 frames[i].setClosed(true);
1119 } catch (java.beans.PropertyVetoException ex)
1123 System.out.println("ALL CLOSED");
1124 if (v_client != null)
1126 // TODO clear binding to vamsas document objects on close_all
1131 public void raiseRelated_actionPerformed(ActionEvent e)
1133 reorderAssociatedWindows(false, false);
1136 public void minimizeAssociated_actionPerformed(ActionEvent e)
1138 reorderAssociatedWindows(true, false);
1141 void closeAssociatedWindows()
1143 reorderAssociatedWindows(false, true);
1149 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1152 protected void garbageCollect_actionPerformed(ActionEvent e)
1154 // We simply collect the garbage
1155 jalview.bin.Cache.log.debug("Collecting garbage...");
1157 jalview.bin.Cache.log.debug("Finished garbage collection.");
1164 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1167 protected void showMemusage_actionPerformed(ActionEvent e)
1169 desktop.showMemoryUsage(showMemusage.isSelected());
1176 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1179 protected void showConsole_actionPerformed(ActionEvent e)
1181 showConsole(showConsole.isSelected());
1184 Console jconsole = null;
1187 * control whether the java console is visible or not
1191 void showConsole(boolean selected)
1193 showConsole.setSelected(selected);
1194 // TODO: decide if we should update properties file
1195 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1197 jconsole.setVisible(selected);
1200 void reorderAssociatedWindows(boolean minimize, boolean close)
1202 JInternalFrame[] frames = desktop.getAllFrames();
1203 if (frames == null || frames.length < 1)
1208 AlignViewport source = null, target = null;
1209 if (frames[0] instanceof AlignFrame)
1211 source = ((AlignFrame) frames[0]).getCurrentView();
1213 else if (frames[0] instanceof TreePanel)
1215 source = ((TreePanel) frames[0]).getViewPort();
1217 else if (frames[0] instanceof PCAPanel)
1219 source = ((PCAPanel) frames[0]).av;
1221 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1223 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1228 for (int i = 0; i < frames.length; i++)
1231 if (frames[i] == null)
1235 if (frames[i] instanceof AlignFrame)
1237 target = ((AlignFrame) frames[i]).getCurrentView();
1239 else if (frames[i] instanceof TreePanel)
1241 target = ((TreePanel) frames[i]).getViewPort();
1243 else if (frames[i] instanceof PCAPanel)
1245 target = ((PCAPanel) frames[i]).av;
1247 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1249 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1252 if (source == target)
1258 frames[i].setClosed(true);
1262 frames[i].setIcon(minimize);
1265 frames[i].toFront();
1269 } catch (java.beans.PropertyVetoException ex)
1283 protected void preferences_actionPerformed(ActionEvent e)
1294 public void saveState_actionPerformed(ActionEvent e)
1296 JalviewFileChooser chooser = new JalviewFileChooser(
1297 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1298 { "jar" }, new String[]
1299 { "Jalview Project" }, "Jalview Project");
1301 chooser.setFileView(new JalviewFileView());
1302 chooser.setDialogTitle("Save State");
1304 int value = chooser.showSaveDialog(this);
1306 if (value == JalviewFileChooser.APPROVE_OPTION)
1308 final Desktop me = this;
1309 final java.io.File choice = chooser.getSelectedFile();
1310 new Thread(new Runnable()
1315 setProgressBar("Saving jalview project " + choice.getName(),
1317 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1318 // TODO catch and handle errors for savestate
1319 // TODO prevent user from messing with the Desktop whilst we're saving
1322 new Jalview2XML().SaveState(choice);
1323 } catch (OutOfMemoryError oom)
1326 "Whilst saving current state to " + choice.getName(), oom);
1327 } catch (Exception ex)
1330 .error("Problems whilst trying to save to "
1331 + choice.getName(), ex);
1332 JOptionPane.showMessageDialog(me,
1333 "Error whilst saving current state to " + choice.getName(),
1334 "Couldn't save project", JOptionPane.WARNING_MESSAGE);
1336 setProgressBar(null, choice.hashCode());
1348 public void loadState_actionPerformed(ActionEvent e)
1350 JalviewFileChooser chooser = new JalviewFileChooser(
1351 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1352 { "jar" }, new String[]
1353 { "Jalview Project" }, "Jalview Project");
1354 chooser.setFileView(new JalviewFileView());
1355 chooser.setDialogTitle("Restore state");
1357 int value = chooser.showOpenDialog(this);
1359 if (value == JalviewFileChooser.APPROVE_OPTION)
1361 final String choice = chooser.getSelectedFile().getAbsolutePath();
1362 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1363 .getSelectedFile().getParent());
1364 new Thread(new Runnable()
1368 setProgressBar("loading jalview project " + choice,
1372 new Jalview2XML().LoadJalviewAlign(choice);
1373 } catch (OutOfMemoryError oom)
1375 new OOMWarning("Whilst loading project from " + choice, oom);
1376 } catch (Exception ex)
1378 Cache.log.error("Problems whilst loading project from "
1380 JOptionPane.showMessageDialog(Desktop.desktop,
1381 "Error whilst loading project from " + choice,
1382 "Couldn't load project", JOptionPane.WARNING_MESSAGE);
1384 setProgressBar(null, choice.hashCode());
1390 public void inputSequence_actionPerformed(ActionEvent e)
1392 new SequenceFetcher(this);
1395 JPanel progressPanel;
1396 ArrayList<JPanel> fileLoadingPanels=new ArrayList<JPanel>();
1397 public void startLoading(final String fileName)
1399 if (fileLoadingCount == 0)
1401 fileLoadingPanels.add(addProgressPanel("Loading File: " + fileName + " "));
1406 private JPanel addProgressPanel(String string)
1408 if (progressPanel == null)
1410 progressPanel = new JPanel(new GridLayout(1,1));
1411 totalProgressCount = 0;
1412 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1414 JPanel thisprogress=new JPanel(new BorderLayout(10,5));
1415 JProgressBar progressBar = new JProgressBar();
1416 progressBar.setIndeterminate(true);
1418 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1420 thisprogress.add(progressBar, BorderLayout.CENTER);
1421 progressPanel.add(thisprogress);
1422 ((GridLayout)progressPanel.getLayout()).setRows(((GridLayout)progressPanel.getLayout()).getRows()+1);
1423 ++totalProgressCount;
1424 instance.validate();
1425 return thisprogress;
1428 int totalProgressCount = 0;
1430 private void removeProgressPanel(JPanel progbar)
1432 if (progressPanel != null)
1434 progressPanel.remove(progbar);
1435 GridLayout gl = (GridLayout) progressPanel.getLayout();
1436 gl.setRows(gl.getRows()-1);
1437 if (--totalProgressCount < 1)
1439 this.getContentPane().remove(progressPanel);
1440 progressPanel = null;
1446 public void stopLoading()
1449 if (fileLoadingCount < 1)
1451 for (JPanel flp : fileLoadingPanels)
1453 removeProgressPanel(flp);
1455 fileLoadingPanels.clear();
1456 fileLoadingCount = 0;
1461 public static int getViewCount(String alignmentId)
1463 AlignViewport[] aps = getViewports(alignmentId);
1464 return (aps == null) ? 0 : aps.length;
1469 * @param alignmentId
1470 * @return all AlignmentPanels concerning the alignmentId sequence set
1472 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1475 if (Desktop.desktop == null)
1477 // no frames created and in headless mode
1478 // TODO: verify that frames are recoverable when in headless mode
1481 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1482 ArrayList aps = new ArrayList();
1483 for (int t = 0; t < frames.length; t++)
1485 if (frames[t] instanceof AlignFrame)
1487 AlignFrame af = (AlignFrame) frames[t];
1488 for (int a = 0; a < af.alignPanels.size(); a++)
1491 .equals(((AlignmentPanel) af.alignPanels.elementAt(a)).av
1492 .getSequenceSetId()))
1494 aps.add(af.alignPanels.elementAt(a));
1499 if (aps.size() == 0)
1503 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1504 for (int t = 0; t < vap.length; t++)
1506 vap[t] = (AlignmentPanel) aps.get(t);
1512 * get all the viewports on an alignment.
1514 * @param sequenceSetId
1515 * unique alignment id
1516 * @return all viewports on the alignment bound to sequenceSetId
1518 public static AlignViewport[] getViewports(String sequenceSetId)
1520 Vector viewp = new Vector();
1521 if (desktop != null)
1523 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1525 for (int t = 0; t < frames.length; t++)
1527 if (frames[t] instanceof AlignFrame)
1529 AlignFrame afr = ((AlignFrame) frames[t]);
1530 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1532 if (afr.alignPanels != null)
1534 for (int a = 0; a < afr.alignPanels.size(); a++)
1536 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1537 .elementAt(a)).av.getSequenceSetId()))
1539 viewp.addElement(((AlignmentPanel) afr.alignPanels
1546 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1551 if (viewp.size() > 0)
1553 AlignViewport[] vp = new AlignViewport[viewp.size()];
1561 public void explodeViews(AlignFrame af)
1563 int size = af.alignPanels.size();
1569 for (int i = 0; i < size; i++)
1571 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1572 AlignFrame newaf = new AlignFrame(ap);
1573 if (ap.av.explodedPosition != null
1574 && !ap.av.explodedPosition.equals(af.getBounds()))
1576 newaf.setBounds(ap.av.explodedPosition);
1579 ap.av.gatherViewsHere = false;
1581 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1582 AlignFrame.DEFAULT_HEIGHT);
1585 af.alignPanels.clear();
1586 af.closeMenuItem_actionPerformed(true);
1590 public void gatherViews(AlignFrame source)
1592 source.viewport.gatherViewsHere = true;
1593 source.viewport.explodedPosition = source.getBounds();
1594 JInternalFrame[] frames = desktop.getAllFrames();
1595 String viewId = source.viewport.sequenceSetID;
1597 for (int t = 0; t < frames.length; t++)
1599 if (frames[t] instanceof AlignFrame && frames[t] != source)
1601 AlignFrame af = (AlignFrame) frames[t];
1602 boolean gatherThis = false;
1603 for (int a = 0; a < af.alignPanels.size(); a++)
1605 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1606 if (viewId.equals(ap.av.getSequenceSetId()))
1609 ap.av.gatherViewsHere = false;
1610 ap.av.explodedPosition = af.getBounds();
1611 source.addAlignmentPanel(ap, false);
1617 af.alignPanels.clear();
1618 af.closeMenuItem_actionPerformed(true);
1625 jalview.gui.VamsasApplication v_client = null;
1627 public void vamsasImport_actionPerformed(ActionEvent e)
1629 if (v_client == null)
1631 // Load and try to start a session.
1632 JalviewFileChooser chooser = new JalviewFileChooser(
1633 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1635 chooser.setFileView(new JalviewFileView());
1636 chooser.setDialogTitle("Open a saved VAMSAS session");
1637 chooser.setToolTipText("select a vamsas session to be opened as a new vamsas session.");
1639 int value = chooser.showOpenDialog(this);
1641 if (value == JalviewFileChooser.APPROVE_OPTION)
1643 String fle = chooser.getSelectedFile().toString();
1644 if (!vamsasImport(chooser.getSelectedFile()))
1646 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1647 "Couldn't import '" + fle + "' as a new vamsas session.",
1648 "Vamsas Document Import Failed",
1649 JOptionPane.ERROR_MESSAGE);
1655 jalview.bin.Cache.log
1656 .error("Implementation error - load session from a running session is not supported.");
1661 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1664 * @return true if import was a success and a session was started.
1666 public boolean vamsasImport(URL url)
1668 // TODO: create progress bar
1669 if (v_client != null)
1672 jalview.bin.Cache.log
1673 .error("Implementation error - load session from a running session is not supported.");
1679 // copy the URL content to a temporary local file
1680 // TODO: be a bit cleverer here with nio (?!)
1681 File file = File.createTempFile("vdocfromurl", ".vdj");
1682 FileOutputStream fos = new FileOutputStream(file);
1683 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1684 byte[] buffer = new byte[2048];
1686 while ((ln = bis.read(buffer)) > -1)
1688 fos.write(buffer, 0, ln);
1692 v_client = new jalview.gui.VamsasApplication(this, file,
1693 url.toExternalForm());
1694 } catch (Exception ex)
1696 jalview.bin.Cache.log.error(
1697 "Failed to create new vamsas session from contents of URL "
1701 setupVamsasConnectedGui();
1702 v_client.initial_update(); // TODO: thread ?
1703 return v_client.inSession();
1707 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1710 * @return true if import was a success and a session was started.
1712 public boolean vamsasImport(File file)
1714 if (v_client != null)
1717 jalview.bin.Cache.log
1718 .error("Implementation error - load session from a running session is not supported.");
1722 setProgressBar("Importing VAMSAS session from " + file.getName(),
1726 v_client = new jalview.gui.VamsasApplication(this, file, null);
1727 } catch (Exception ex)
1729 setProgressBar("Importing VAMSAS session from " + file.getName(),
1731 jalview.bin.Cache.log.error(
1732 "New vamsas session from existing session file failed:", ex);
1735 setupVamsasConnectedGui();
1736 v_client.initial_update(); // TODO: thread ?
1737 setProgressBar("Importing VAMSAS session from " + file.getName(),
1739 return v_client.inSession();
1742 public boolean joinVamsasSession(String mysesid)
1744 if (v_client != null)
1747 "Trying to join a vamsas session when another is already connected.");
1749 if (mysesid == null)
1751 throw new Error("Invalid vamsas session id.");
1753 v_client = new VamsasApplication(this, mysesid);
1754 setupVamsasConnectedGui();
1755 v_client.initial_update();
1756 return (v_client.inSession());
1759 public void vamsasStart_actionPerformed(ActionEvent e)
1761 if (v_client == null)
1764 // we just start a default session for moment.
1766 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1767 * getProperty("LAST_DIRECTORY"));
1769 * chooser.setFileView(new JalviewFileView());
1770 * chooser.setDialogTitle("Load Vamsas file");
1771 * chooser.setToolTipText("Import");
1773 * int value = chooser.showOpenDialog(this);
1775 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1776 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1778 v_client = new VamsasApplication(this);
1779 setupVamsasConnectedGui();
1780 v_client.initial_update(); // TODO: thread ?
1784 // store current data in session.
1785 v_client.push_update(); // TODO: thread
1789 protected void setupVamsasConnectedGui()
1791 vamsasStart.setText("Session Update");
1792 vamsasSave.setVisible(true);
1793 vamsasStop.setVisible(true);
1794 vamsasImport.setVisible(false); // Document import to existing session is
1795 // not possible for vamsas-client-1.0.
1798 protected void setupVamsasDisconnectedGui()
1800 vamsasSave.setVisible(false);
1801 vamsasStop.setVisible(false);
1802 vamsasImport.setVisible(true);
1803 vamsasStart.setText("New Vamsas Session");
1806 public void vamsasStop_actionPerformed(ActionEvent e)
1808 if (v_client != null)
1810 v_client.end_session();
1812 setupVamsasDisconnectedGui();
1816 protected void buildVamsasStMenu()
1818 if (v_client == null)
1820 String[] sess = null;
1823 sess = VamsasApplication.getSessionList();
1824 } catch (Exception e)
1826 jalview.bin.Cache.log.warn(
1827 "Problem getting current sessions list.", e);
1832 jalview.bin.Cache.log.debug("Got current sessions list: "
1833 + sess.length + " entries.");
1834 VamsasStMenu.removeAll();
1835 for (int i = 0; i < sess.length; i++)
1837 JMenuItem sessit = new JMenuItem();
1838 sessit.setText(sess[i]);
1839 sessit.setToolTipText("Connect to session " + sess[i]);
1840 final Desktop dsktp = this;
1841 final String mysesid = sess[i];
1842 sessit.addActionListener(new ActionListener()
1845 public void actionPerformed(ActionEvent e)
1847 if (dsktp.v_client == null)
1849 Thread rthr = new Thread(new Runnable()
1854 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1855 dsktp.setupVamsasConnectedGui();
1856 dsktp.v_client.initial_update();
1864 VamsasStMenu.add(sessit);
1866 // don't show an empty menu.
1867 VamsasStMenu.setVisible(sess.length > 0);
1872 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1873 VamsasStMenu.removeAll();
1874 VamsasStMenu.setVisible(false);
1879 // Not interested in the content. Just hide ourselves.
1880 VamsasStMenu.setVisible(false);
1884 public void vamsasSave_actionPerformed(ActionEvent e)
1886 if (v_client != null)
1888 JalviewFileChooser chooser = new JalviewFileChooser(
1889 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1890 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
1892 { "Vamsas Document" }, "Vamsas Document");
1894 chooser.setFileView(new JalviewFileView());
1895 chooser.setDialogTitle("Save Vamsas Document Archive");
1897 int value = chooser.showSaveDialog(this);
1899 if (value == JalviewFileChooser.APPROVE_OPTION)
1901 java.io.File choice = chooser.getSelectedFile();
1902 JPanel progpanel = addProgressPanel("Saving VAMSAS Document to "
1903 + choice.getName());
1904 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
1905 String warnmsg = null;
1906 String warnttl = null;
1909 v_client.vclient.storeDocument(choice);
1912 warnttl = "Serious Problem saving Vamsas Document";
1913 warnmsg = ex.toString();
1914 jalview.bin.Cache.log.error("Error Whilst saving document to "
1917 } catch (Exception ex)
1919 warnttl = "Problem saving Vamsas Document.";
1920 warnmsg = ex.toString();
1921 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
1925 removeProgressPanel(progpanel);
1926 if (warnmsg != null)
1928 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1930 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
1936 JPanel vamUpdate = null;
1939 * hide vamsas user gui bits when a vamsas document event is being handled.
1942 * true to hide gui, false to reveal gui
1944 public void setVamsasUpdate(boolean b)
1946 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
1947 + (b ? "in progress" : "finished"));
1949 if (vamUpdate != null)
1951 this.removeProgressPanel(vamUpdate);
1955 vamUpdate = this.addProgressPanel("Updating vamsas session");
1957 vamsasStart.setVisible(!b);
1958 vamsasStop.setVisible(!b);
1959 vamsasSave.setVisible(!b);
1962 public JInternalFrame[] getAllFrames()
1964 return desktop.getAllFrames();
1968 * Checks the given url to see if it gives a response indicating that the user
1969 * should be informed of a new questionnaire.
1973 public void checkForQuestionnaire(String url)
1975 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
1976 // javax.swing.SwingUtilities.invokeLater(jvq);
1977 new Thread(jvq).start();
1981 * Proxy class for JDesktopPane which optionally displays the current memory
1982 * usage and highlights the desktop area with a red bar if free memory runs
1987 public class MyDesktopPane extends JDesktopPane implements Runnable
1990 boolean showMemoryUsage = false;
1994 java.text.NumberFormat df;
1996 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
1999 public MyDesktopPane(boolean showMemoryUsage)
2001 showMemoryUsage(showMemoryUsage);
2004 public void showMemoryUsage(boolean showMemoryUsage)
2006 this.showMemoryUsage = showMemoryUsage;
2007 if (showMemoryUsage)
2009 Thread worker = new Thread(this);
2014 public boolean isShowMemoryUsage()
2016 return showMemoryUsage;
2021 df = java.text.NumberFormat.getNumberInstance();
2022 df.setMaximumFractionDigits(2);
2023 runtime = Runtime.getRuntime();
2025 while (showMemoryUsage)
2029 maxMemory = runtime.maxMemory() / 1048576f;
2030 allocatedMemory = runtime.totalMemory() / 1048576f;
2031 freeMemory = runtime.freeMemory() / 1048576f;
2032 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2034 percentUsage = (totalFreeMemory / maxMemory) * 100;
2036 // if (percentUsage < 20)
2038 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2040 // instance.set.setBorder(border1);
2043 // sleep after showing usage
2045 } catch (Exception ex)
2047 ex.printStackTrace();
2052 public void paintComponent(Graphics g)
2054 if (showMemoryUsage && g != null && df != null)
2056 if (percentUsage < 20)
2057 g.setColor(Color.red);
2058 FontMetrics fm = g.getFontMetrics();
2062 "Total Free Memory: " + df.format(totalFreeMemory)
2063 + "MB; Max Memory: " + df.format(maxMemory)
2064 + "MB; " + df.format(percentUsage) + "%", 10,
2065 getHeight() - fm.getHeight());
2072 * fixes stacking order after a modal dialog to ensure windows that should be on top actually are
2074 public void relayerWindows()
2079 protected JMenuItem groovyShell;
2081 public void doGroovyCheck()
2083 if (jalview.bin.Cache.groovyJarsPresent())
2085 groovyShell = new JMenuItem();
2086 groovyShell.setText("Groovy Console...");
2087 groovyShell.addActionListener(new ActionListener()
2089 public void actionPerformed(ActionEvent e)
2091 groovyShell_actionPerformed(e);
2094 toolsMenu.add(groovyShell);
2095 groovyShell.setVisible(true);
2100 * Accessor method to quickly get all the AlignmentFrames loaded.
2102 public static AlignFrame[] getAlignframes()
2104 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2110 Vector avp = new Vector();
2114 for (int i = frames.length - 1; i > -1; i--)
2116 if (frames[i] instanceof AlignFrame)
2118 AlignFrame af = (AlignFrame) frames[i];
2122 } catch (Exception ex)
2124 ex.printStackTrace();
2126 if (avp.size() == 0)
2130 AlignFrame afs[] = new AlignFrame[avp.size()];
2131 for (int i = 0, j = avp.size(); i < j; i++)
2133 afs[i] = (AlignFrame) avp.elementAt(i);
2138 public AppJmol[] getJmols()
2140 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2146 Vector avp = new Vector();
2150 for (int i = frames.length - 1; i > -1; i--)
2152 if (frames[i] instanceof AppJmol)
2154 AppJmol af = (AppJmol) frames[i];
2158 } catch (Exception ex)
2160 ex.printStackTrace();
2162 if (avp.size() == 0)
2166 AppJmol afs[] = new AppJmol[avp.size()];
2167 for (int i = 0, j = avp.size(); i < j; i++)
2169 afs[i] = (AppJmol) avp.elementAt(i);
2176 * Add Groovy Support to Jalview
2178 public void groovyShell_actionPerformed(ActionEvent e)
2180 // use reflection to avoid creating compilation dependency.
2181 if (!jalview.bin.Cache.groovyJarsPresent())
2184 "Implementation Error. Cannot create groovyShell without Groovy on the classpath!");
2188 Class gcClass = Desktop.class.getClassLoader().loadClass(
2189 "groovy.ui.Console");
2190 Constructor gccons = gcClass.getConstructor(null);
2191 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2193 { String.class, Object.class });
2194 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2195 Object gc = gccons.newInstance(null);
2196 setvar.invoke(gc, new Object[]
2197 { "Jalview", this });
2198 run.invoke(gc, null);
2199 } catch (Exception ex)
2201 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2203 .showInternalMessageDialog(
2206 "Couldn't create the groovy Shell. Check the error log for the details of what went wrong.",
2207 "Jalview Groovy Support Failed",
2208 JOptionPane.ERROR_MESSAGE);
2213 * Progress bars managed by the IProgressIndicator method.
2215 private Hashtable<Long,JPanel> progressBars;
2216 private Hashtable<Long,IProgressIndicatorHandler> progressBarHandlers;
2221 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2223 public void setProgressBar(String message, long id)
2225 if (progressBars == null)
2227 progressBars = new Hashtable<Long,JPanel>();
2228 progressBarHandlers = new Hashtable<Long,IProgressIndicatorHandler>();
2231 if (progressBars.get(new Long(id)) != null)
2233 JPanel progressPanel = progressBars
2234 .remove(new Long(id));
2235 if (progressBarHandlers.contains(new Long(id)))
2237 progressBarHandlers.remove(new Long(id));
2239 removeProgressPanel(progressPanel);
2243 progressBars.put(new Long(id), addProgressPanel(message));
2250 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2251 * jalview.gui.IProgressIndicatorHandler)
2253 public void registerHandler(final long id,
2254 final IProgressIndicatorHandler handler)
2256 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2259 "call setProgressBar before registering the progress bar's handler.");
2261 progressBarHandlers.put(new Long(id), handler);
2262 final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
2263 if (handler.canCancel())
2265 JButton cancel = new JButton("Cancel");
2266 final IProgressIndicator us = this;
2267 cancel.addActionListener(new ActionListener()
2270 public void actionPerformed(ActionEvent e)
2272 handler.cancelActivity(id);
2275 + ((JLabel) progressPanel.getComponent(0))
2279 progressPanel.add(cancel, BorderLayout.EAST);
2284 * This will return the first AlignFrame viewing AlignViewport av. It will
2285 * break if there are more than one AlignFrames viewing a particular av. This
2288 * @return alignFrame for av
2290 public static AlignFrame getAlignFrameFor(AlignViewport av)
2292 if (desktop != null)
2294 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2295 for (int panel = 0; aps != null && panel < aps.length; panel++)
2297 if (aps[panel] != null && aps[panel].av == av)
2299 return aps[panel].alignFrame;
2306 public VamsasApplication getVamsasApplication()
2313 * flag set if jalview GUI is being operated programmatically
2315 private boolean inBatchMode = false;
2318 * check if jalview GUI is being operated programmatically
2320 * @return inBatchMode
2322 public boolean isInBatchMode()
2328 * set flag if jalview GUI is being operated programmatically
2330 * @param inBatchMode
2332 public void setInBatchMode(boolean inBatchMode)
2334 this.inBatchMode = inBatchMode;
2337 public void startServiceDiscovery()
2339 startServiceDiscovery(false);
2342 public void startServiceDiscovery(boolean blocking)
2344 boolean alive = true;
2345 Thread t0 = null, t1 = null, t2 = null;
2347 // todo: changesupport handlers need to be transferred
2348 if (discoverer == null)
2350 discoverer = new jalview.ws.jws1.Discoverer();
2351 // register PCS handler for desktop.
2352 discoverer.addPropertyChangeListener(changeSupport);
2354 // JAL-940 - disabled JWS1 service configuration - always start discoverer until we phase out completely
2357 (t0 = new Thread(discoverer)).start();
2362 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2364 // EnfinEnvision web service menu entries are rebuild every time the
2365 // menu is shown, so no changeSupport events are needed.
2366 jalview.ws.EnfinEnvision2OneWay.getInstance();
2367 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2370 } catch (Exception e)
2373 .info("Exception when trying to launch Envision2 workflow discovery.",
2375 Cache.log.info(e.getStackTrace());
2377 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2379 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2381 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2383 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2389 // TODO: do rest service discovery
2398 } catch (Exception e)
2401 alive = (t1 != null && t1.isAlive())
2402 || (t2 != null && t2.isAlive())
2403 || (t3 != null && t3.isAlive())
2404 || (t0 != null && t0.isAlive());
2410 * called to check if the service discovery process completed successfully.
2414 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2416 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2418 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2419 .getErrorMessages();
2422 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2424 if (serviceChangedDialog == null)
2426 // only run if we aren't already displaying one of these.
2427 javax.swing.SwingUtilities
2428 .invokeLater(serviceChangedDialog = new Runnable()
2434 .showInternalMessageDialog(
2437 + "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",
2438 "Preferences Problem",
2439 JOptionPane.WARNING_MESSAGE);
2440 serviceChangedDialog = null;
2449 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2456 private Runnable serviceChangedDialog = null;
2459 * start a thread to open a URL in the configured browser. Pops up a warning
2460 * dialog to the user if there is an exception when calling out to the browser
2465 public static void showUrl(final String url)
2467 showUrl(url, Desktop.instance);
2470 * Like showUrl but allows progress handler to be specified
2472 * @param progress (null) or object implementing IProgressIndicator
2474 public static void showUrl(final String url, final IProgressIndicator progress)
2476 new Thread(new Runnable()
2482 if (progress!=null) {
2483 progress.setProgressBar("Opening "+url, this.hashCode());
2485 jalview.util.BrowserLauncher.openURL(url);
2486 } catch (Exception ex)
2489 .showInternalMessageDialog(
2491 "Unixers: Couldn't find default web browser."
2492 + "\nAdd the full path to your browser in Preferences.",
2493 "Web browser not found",
2494 JOptionPane.WARNING_MESSAGE);
2496 ex.printStackTrace();
2498 if (progress!=null) {
2499 progress.setProgressBar(null, this.hashCode());
2505 public static WsParamSetManager wsparamManager = null;
2507 public static ParamManager getUserParameterStore()
2509 if (wsparamManager == null)
2511 wsparamManager = new WsParamSetManager();
2513 return wsparamManager;