2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.bin.Cache;
24 import jalview.io.FileLoader;
25 import jalview.io.FormatAdapter;
26 import jalview.io.IdentifyFile;
27 import jalview.io.JalviewFileChooser;
28 import jalview.io.JalviewFileView;
29 import jalview.structure.StructureSelectionManager;
30 import jalview.util.ImageMaker;
31 import jalview.util.MessageManager;
32 import jalview.ws.params.ParamManager;
34 import java.awt.BorderLayout;
35 import java.awt.Color;
36 import java.awt.Dimension;
37 import java.awt.FontMetrics;
38 import java.awt.Graphics;
39 import java.awt.GridLayout;
40 import java.awt.Point;
41 import java.awt.Rectangle;
42 import java.awt.Toolkit;
43 import java.awt.datatransfer.Clipboard;
44 import java.awt.datatransfer.ClipboardOwner;
45 import java.awt.datatransfer.DataFlavor;
46 import java.awt.datatransfer.Transferable;
47 import java.awt.dnd.DnDConstants;
48 import java.awt.dnd.DropTargetDragEvent;
49 import java.awt.dnd.DropTargetDropEvent;
50 import java.awt.dnd.DropTargetEvent;
51 import java.awt.dnd.DropTargetListener;
52 import java.awt.event.ActionEvent;
53 import java.awt.event.ActionListener;
54 import java.awt.event.FocusEvent;
55 import java.awt.event.FocusListener;
56 import java.awt.event.MouseAdapter;
57 import java.awt.event.MouseEvent;
58 import java.awt.event.MouseListener;
59 import java.awt.event.WindowAdapter;
60 import java.awt.event.WindowEvent;
61 import java.beans.PropertyChangeEvent;
62 import java.beans.PropertyChangeListener;
63 import java.beans.PropertyVetoException;
64 import java.io.BufferedInputStream;
66 import java.io.FileOutputStream;
67 import java.lang.reflect.Constructor;
69 import java.util.ArrayList;
70 import java.util.Hashtable;
71 import java.util.StringTokenizer;
72 import java.util.Vector;
73 import java.util.concurrent.ExecutorService;
74 import java.util.concurrent.Executors;
75 import java.util.concurrent.Semaphore;
77 import javax.swing.DefaultDesktopManager;
78 import javax.swing.DesktopManager;
79 import javax.swing.JButton;
80 import javax.swing.JComboBox;
81 import javax.swing.JComponent;
82 import javax.swing.JDesktopPane;
83 import javax.swing.JFrame;
84 import javax.swing.JInternalFrame;
85 import javax.swing.JLabel;
86 import javax.swing.JMenuItem;
87 import javax.swing.JOptionPane;
88 import javax.swing.JPanel;
89 import javax.swing.JPopupMenu;
90 import javax.swing.JProgressBar;
91 import javax.swing.SwingUtilities;
92 import javax.swing.event.HyperlinkEvent;
93 import javax.swing.event.HyperlinkEvent.EventType;
94 import javax.swing.event.MenuEvent;
95 import javax.swing.event.MenuListener;
102 * @version $Revision: 1.155 $
104 public class Desktop extends jalview.jbgui.GDesktop implements
105 DropTargetListener, ClipboardOwner, IProgressIndicator,
106 jalview.api.StructureSelectionManagerProvider
109 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
112 * news reader - null if it was never started.
114 private BlogReader jvnews = null;
118 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
120 public void addJalviewPropertyChangeListener(
121 PropertyChangeListener listener)
123 changeSupport.addJalviewPropertyChangeListener(listener);
127 * @param propertyName
129 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
130 * java.beans.PropertyChangeListener)
132 public void addJalviewPropertyChangeListener(String propertyName,
133 PropertyChangeListener listener)
135 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
139 * @param propertyName
141 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
142 * java.beans.PropertyChangeListener)
144 public void removeJalviewPropertyChangeListener(String propertyName,
145 PropertyChangeListener listener)
147 changeSupport.removeJalviewPropertyChangeListener(propertyName,
151 /** Singleton Desktop instance */
152 public static Desktop instance;
154 public static MyDesktopPane desktop;
156 static int openFrameCount = 0;
158 static final int xOffset = 30;
160 static final int yOffset = 30;
162 public static jalview.ws.jws1.Discoverer discoverer;
164 public static Object[] jalviewClipboard;
166 public static boolean internalCopy = false;
168 static int fileLoadingCount = 0;
170 class MyDesktopManager implements DesktopManager
173 private DesktopManager delegate;
175 public MyDesktopManager(DesktopManager delegate)
177 this.delegate = delegate;
180 public void activateFrame(JInternalFrame f)
184 delegate.activateFrame(f);
185 } catch (NullPointerException npe)
187 Point p = getMousePosition();
188 instance.showPasteMenu(p.x, p.y);
192 public void beginDraggingFrame(JComponent f)
194 delegate.beginDraggingFrame(f);
197 public void beginResizingFrame(JComponent f, int direction)
199 delegate.beginResizingFrame(f, direction);
202 public void closeFrame(JInternalFrame f)
204 delegate.closeFrame(f);
207 public void deactivateFrame(JInternalFrame f)
209 delegate.deactivateFrame(f);
212 public void deiconifyFrame(JInternalFrame f)
214 delegate.deiconifyFrame(f);
217 public void dragFrame(JComponent f, int newX, int newY)
223 delegate.dragFrame(f, newX, newY);
226 public void endDraggingFrame(JComponent f)
228 delegate.endDraggingFrame(f);
231 public void endResizingFrame(JComponent f)
233 delegate.endResizingFrame(f);
236 public void iconifyFrame(JInternalFrame f)
238 delegate.iconifyFrame(f);
241 public void maximizeFrame(JInternalFrame f)
243 delegate.maximizeFrame(f);
246 public void minimizeFrame(JInternalFrame f)
248 delegate.minimizeFrame(f);
251 public void openFrame(JInternalFrame f)
253 delegate.openFrame(f);
256 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
259 Rectangle b = desktop.getBounds();
264 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
267 public void setBoundsForFrame(JComponent f, int newX, int newY,
268 int newWidth, int newHeight)
270 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
273 // All other methods, simply delegate
278 * Creates a new Desktop object.
283 * A note to implementors. It is ESSENTIAL that any activities that might
284 * block are spawned off as threads rather than waited for during this
288 doVamsasClientCheck();
290 doConfigureStructurePrefs();
291 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
292 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
293 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
295 boolean showjconsole = jalview.bin.Cache.getDefault(
296 "SHOW_JAVA_CONSOLE", false);
297 desktop = new MyDesktopPane(selmemusage);
298 showMemusage.setSelected(selmemusage);
299 desktop.setBackground(Color.white);
300 getContentPane().setLayout(new BorderLayout());
301 // alternate config - have scrollbars - see notes in JAL-153
302 // JScrollPane sp = new JScrollPane();
303 // sp.getViewport().setView(desktop);
304 // getContentPane().add(sp, BorderLayout.CENTER);
305 getContentPane().add(desktop, BorderLayout.CENTER);
306 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
308 // This line prevents Windows Look&Feel resizing all new windows to maximum
309 // if previous window was maximised
310 desktop.setDesktopManager(new MyDesktopManager(
311 new DefaultDesktopManager()));
313 Rectangle dims = getLastKnownDimensions("");
320 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
321 setBounds((screenSize.width - 900) / 2,
322 (screenSize.height - 650) / 2, 900, 650);
324 jconsole = new Console(this, showjconsole);
325 // add essential build information
326 jconsole.setHeader("Jalview Version: "
327 + jalview.bin.Cache.getProperty("VERSION") + "\n"
328 + "Jalview Installation: "
329 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
332 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
333 + "Java version: " + System.getProperty("java.version") + "\n"
334 + System.getProperty("os.arch") + " "
335 + System.getProperty("os.name") + " "
336 + System.getProperty("os.version"));
338 showConsole(showjconsole);
340 showNews.setVisible(false);
342 this.addWindowListener(new WindowAdapter()
344 public void windowClosing(WindowEvent evt)
351 this.addMouseListener(ma = new MouseAdapter()
353 public void mousePressed(MouseEvent evt)
355 if (SwingUtilities.isRightMouseButton(evt))
357 showPasteMenu(evt.getX(), evt.getY());
361 desktop.addMouseListener(ma);
363 this.addFocusListener(new FocusListener()
367 public void focusLost(FocusEvent e)
369 // TODO Auto-generated method stub
374 public void focusGained(FocusEvent e)
376 Cache.log.debug("Relaying windows after focus gain");
377 // make sure that we sort windows properly after we gain focus
378 instance.relayerWindows();
381 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
382 // Spawn a thread that shows the splashscreen
383 SwingUtilities.invokeLater(new Runnable()
392 // Thread off a new instance of the file chooser - this reduces the time it
393 // takes to open it later on.
394 new Thread(new Runnable()
398 Cache.log.debug("Filechooser init thread started.");
399 JalviewFileChooser chooser = new JalviewFileChooser(
400 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
401 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
402 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
403 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
404 Cache.log.debug("Filechooser init thread finished.");
407 // Add the service change listener
408 changeSupport.addJalviewPropertyChangeListener("services",
409 new PropertyChangeListener()
413 public void propertyChange(PropertyChangeEvent evt)
415 Cache.log.debug("Firing service changed event for "
416 + evt.getNewValue());
417 JalviewServicesChanged(evt);
423 public void doConfigureStructurePrefs()
425 // configure services
426 StructureSelectionManager ssm = StructureSelectionManager
427 .getStructureSelectionManager(this);
428 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
430 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
431 Preferences.ADD_TEMPFACT_ANN, true));
432 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(Preferences.STRUCT_FROM_PDB, true));
433 ssm.setSecStructServices(jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW,
438 ssm.setAddTempFacAnnot(false);
439 ssm.setProcessSecondaryStructure(false);
440 ssm.setSecStructServices(false);
444 public void checkForNews()
446 final Desktop me = this;
447 // Thread off the news reader, in case there are connection problems.
448 addDialogThread(new Runnable()
453 Cache.log.debug("Starting news thread.");
455 jvnews = new BlogReader(me);
456 showNews.setVisible(true);
457 Cache.log.debug("Completed news thread.");
462 protected void showNews_actionPerformed(ActionEvent e)
464 showNews(showNews.isSelected());
467 void showNews(boolean visible)
470 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
471 showNews.setSelected(visible);
472 if (visible && !jvnews.isVisible())
474 new Thread(new Runnable()
479 long instance = System.currentTimeMillis();
480 Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_news"), instance);
481 jvnews.refreshNews();
482 Desktop.instance.setProgressBar(null, instance);
491 * recover the last known dimensions for a jalview window
494 * - empty string is desktop, all other windows have unique prefix
495 * @return null or last known dimensions scaled to current geometry (if last
496 * window geom was known)
498 Rectangle getLastKnownDimensions(String windowName)
500 // TODO: lock aspect ratio for scaling desktop Bug #0058199
501 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
502 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
503 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
504 String width = jalview.bin.Cache.getProperty(windowName
506 String height = jalview.bin.Cache.getProperty(windowName
508 if ((x != null) && (y != null) && (width != null) && (height != null))
510 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
511 .parseInt(width), ih = Integer.parseInt(height);
512 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
514 // attempt #1 - try to cope with change in screen geometry - this
515 // version doesn't preserve original jv aspect ratio.
516 // take ratio of current screen size vs original screen size.
517 double sw = ((1f * screenSize.width) / (1f * Integer
518 .parseInt(jalview.bin.Cache
519 .getProperty("SCREENGEOMETRY_WIDTH"))));
520 double sh = ((1f * screenSize.height) / (1f * Integer
521 .parseInt(jalview.bin.Cache
522 .getProperty("SCREENGEOMETRY_HEIGHT"))));
523 // rescale the bounds depending upon the current screen geometry.
524 ix = (int) (ix * sw);
525 iw = (int) (iw * sw);
526 iy = (int) (iy * sh);
527 ih = (int) (ih * sh);
528 while (ix >= screenSize.width)
530 jalview.bin.Cache.log
531 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
532 ix -= screenSize.width;
534 while (iy >= screenSize.height)
536 jalview.bin.Cache.log
537 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
538 iy -= screenSize.height;
540 jalview.bin.Cache.log.debug("Got last known dimensions for "
541 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
544 // return dimensions for new instance
545 return new Rectangle(ix, iy, iw, ih);
550 private void doVamsasClientCheck()
552 if (jalview.bin.Cache.vamsasJarsPresent())
554 setupVamsasDisconnectedGui();
555 VamsasMenu.setVisible(true);
556 final Desktop us = this;
557 VamsasMenu.addMenuListener(new MenuListener()
559 // this listener remembers when the menu was first selected, and
560 // doesn't rebuild the session list until it has been cleared and
562 boolean refresh = true;
564 public void menuCanceled(MenuEvent e)
569 public void menuDeselected(MenuEvent e)
574 public void menuSelected(MenuEvent e)
578 us.buildVamsasStMenu();
583 vamsasStart.setVisible(true);
587 void showPasteMenu(int x, int y)
589 JPopupMenu popup = new JPopupMenu();
590 JMenuItem item = new JMenuItem(
591 MessageManager.getString("label.paste_new_window"));
592 item.addActionListener(new ActionListener()
594 public void actionPerformed(ActionEvent evt)
601 popup.show(this, x, y);
608 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
609 Transferable contents = c.getContents(this);
611 if (contents != null)
613 String file = (String) contents
614 .getTransferData(DataFlavor.stringFlavor);
616 String format = new IdentifyFile().Identify(file,
617 FormatAdapter.PASTE);
619 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
622 } catch (Exception ex)
625 .println("Unable to paste alignment from system clipboard:\n"
631 * Adds and opens the given frame to the desktop
642 public static synchronized void addInternalFrame(
643 final JInternalFrame frame, String title, int w, int h)
645 addInternalFrame(frame, title, w, h, true);
662 public static synchronized void addInternalFrame(
663 final JInternalFrame frame, String title, int w, int h,
667 // TODO: allow callers to determine X and Y position of frame (eg. via
669 // TODO: consider fixing method to update entries in the window submenu with
670 // the current window title
672 frame.setTitle(title);
673 if (frame.getWidth() < 1 || frame.getHeight() < 1)
677 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
678 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
679 // IF JALVIEW IS RUNNING HEADLESS
680 // ///////////////////////////////////////////////
682 || (System.getProperty("java.awt.headless") != null && System
683 .getProperty("java.awt.headless").equals("true")))
690 frame.setVisible(true);
691 frame.setClosable(true);
692 frame.setResizable(resizable);
693 frame.setMaximizable(resizable);
694 frame.setIconifiable(resizable);
695 frame.setFrameIcon(null);
697 if (frame.getX() < 1 && frame.getY() < 1)
699 frame.setLocation(xOffset * openFrameCount, yOffset
700 * ((openFrameCount - 1) % 10) + yOffset);
703 final JMenuItem menuItem = new JMenuItem(title);
704 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
706 public void internalFrameActivated(
707 javax.swing.event.InternalFrameEvent evt)
709 JInternalFrame itf = desktop.getSelectedFrame();
717 public void internalFrameClosed(
718 javax.swing.event.InternalFrameEvent evt)
720 PaintRefresher.RemoveComponent(frame);
722 windowMenu.remove(menuItem);
723 JInternalFrame itf = desktop.getSelectedFrame();
732 menuItem.addActionListener(new ActionListener()
734 public void actionPerformed(ActionEvent e)
738 frame.setSelected(true);
739 frame.setIcon(false);
740 } catch (java.beans.PropertyVetoException ex)
746 menuItem.addMouseListener(new MouseListener()
750 public void mouseReleased(MouseEvent e)
755 public void mousePressed(MouseEvent e)
760 public void mouseExited(MouseEvent e)
764 frame.setSelected(false);
765 } catch (PropertyVetoException e1)
771 public void mouseEntered(MouseEvent e)
775 frame.setSelected(true);
776 } catch (PropertyVetoException e1)
782 public void mouseClicked(MouseEvent e)
788 windowMenu.add(menuItem);
794 frame.setSelected(true);
795 frame.requestFocus();
796 } catch (java.beans.PropertyVetoException ve)
798 } catch (java.lang.ClassCastException cex)
801 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
806 public void lostOwnership(Clipboard clipboard, Transferable contents)
810 Desktop.jalviewClipboard = null;
813 internalCopy = false;
816 public void dragEnter(DropTargetDragEvent evt)
820 public void dragExit(DropTargetEvent evt)
824 public void dragOver(DropTargetDragEvent evt)
828 public void dropActionChanged(DropTargetDragEvent evt)
838 public void drop(DropTargetDropEvent evt)
840 boolean success = true;
841 Transferable t = evt.getTransferable();
842 java.util.List files = null;
843 java.util.List protocols = null;
847 DataFlavor uriListFlavor = new DataFlavor(
848 "text/uri-list;class=java.lang.String");
849 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
851 // Works on Windows and MacOSX
852 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
853 files = (java.util.List) t
854 .getTransferData(DataFlavor.javaFileListFlavor);
856 else if (t.isDataFlavorSupported(uriListFlavor))
858 // This is used by Unix drag system
859 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
860 String data = (String) t.getTransferData(uriListFlavor);
861 files = new java.util.ArrayList(1);
862 protocols = new java.util.ArrayList(1);
863 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
864 data, "\r\n"); st.hasMoreTokens();)
866 String s = st.nextToken();
867 if (s.startsWith("#"))
869 // the line is a comment (as per the RFC 2483)
872 java.net.URI uri = new java.net.URI(s);
873 if (uri.getScheme().toLowerCase().startsWith("http"))
875 protocols.add(FormatAdapter.URL);
876 files.add(uri.toString());
880 // otherwise preserve old behaviour: catch all for file objects
881 java.io.File file = new java.io.File(uri);
882 protocols.add(FormatAdapter.FILE);
883 files.add(file.toString());
887 } catch (Exception e)
896 for (int i = 0; i < files.size(); i++)
898 String file = files.get(i).toString();
899 String protocol = (protocols == null) ? FormatAdapter.FILE
900 : (String) protocols.get(i);
901 String format = null;
903 if (file.endsWith(".jar"))
910 format = new IdentifyFile().Identify(file, protocol);
913 new FileLoader().LoadFile(file, protocol, format);
916 } catch (Exception ex)
921 evt.dropComplete(success); // need this to ensure input focus is properly
922 // transfered to any new windows created
931 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
933 JalviewFileChooser chooser = new JalviewFileChooser(
934 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
935 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
936 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
937 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
939 chooser.setFileView(new JalviewFileView());
940 chooser.setDialogTitle(MessageManager
941 .getString("label.open_local_file"));
942 chooser.setToolTipText(MessageManager.getString("action.open"));
944 int value = chooser.showOpenDialog(this);
946 if (value == JalviewFileChooser.APPROVE_OPTION)
948 String choice = chooser.getSelectedFile().getPath();
949 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
950 .getSelectedFile().getParent());
952 String format = null;
953 if (chooser.getSelectedFormat() != null
954 && chooser.getSelectedFormat().equals("Jalview"))
960 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
963 if (viewport != null)
965 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
970 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
981 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
983 // This construct allows us to have a wider textfield
985 JLabel label = new JLabel(
986 MessageManager.getString("label.input_file_url"));
987 final JComboBox history = new JComboBox();
989 JPanel panel = new JPanel(new GridLayout(2, 1));
992 history.setPreferredSize(new Dimension(400, 20));
993 history.setEditable(true);
994 history.addItem("http://www.");
996 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1000 if (historyItems != null)
1002 st = new StringTokenizer(historyItems, "\t");
1004 while (st.hasMoreTokens())
1006 history.addItem(st.nextElement());
1010 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1011 MessageManager.getString("label.input_alignment_from_url"),
1012 JOptionPane.OK_CANCEL_OPTION);
1014 if (reply != JOptionPane.OK_OPTION)
1019 String url = history.getSelectedItem().toString();
1021 if (url.toLowerCase().endsWith(".jar"))
1023 if (viewport != null)
1025 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1030 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1035 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1037 if (format.equals("URL NOT FOUND"))
1039 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1040 MessageManager.formatMessage("label.couldnt_locate", new String[]{url}), MessageManager.getString("label.url_not_found"),
1041 JOptionPane.WARNING_MESSAGE);
1046 if (viewport != null)
1048 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1052 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1063 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1065 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1066 cap.setForInput(viewport);
1067 Desktop.addInternalFrame(cap, MessageManager.getString("label.cut_paste_alignmen_file"), 600, 500);
1075 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1077 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1078 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1080 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1081 getBounds().y, getWidth(), getHeight()));
1083 if (jconsole != null)
1085 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1086 jconsole.stopConsole();
1090 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1093 if (dialogExecutor != null)
1095 dialogExecutor.shutdownNow();
1101 private void storeLastKnownDimensions(String string, Rectangle jc)
1103 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1104 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1105 + " height:" + jc.height);
1107 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1108 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1109 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1110 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1119 public void aboutMenuItem_actionPerformed(ActionEvent e)
1121 // StringBuffer message = getAboutMessage(false);
1122 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1124 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1125 new Thread(new Runnable()
1129 new SplashScreen(true);
1134 public StringBuffer getAboutMessage(boolean shortv)
1136 StringBuffer message = new StringBuffer();
1137 message.append("<html>");
1140 message.append("<h1><strong>Version: "
1141 + jalview.bin.Cache.getProperty("VERSION")
1142 + "</strong></h1>");
1143 message.append("<strong>Last Updated: <em>"
1144 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1145 + "</em></strong>");
1151 message.append("<strong>Version "
1152 + jalview.bin.Cache.getProperty("VERSION")
1153 + "; last updated: "
1154 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1157 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1160 message.append("<br>...Checking latest version...</br>");
1162 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1163 .equals(jalview.bin.Cache.getProperty("VERSION")))
1165 boolean red = false;
1166 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1167 .indexOf("automated build") == -1)
1170 // Displayed when code version and jnlp version do not match and code
1171 // version is not a development build
1172 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1175 message.append("<br>!! Version "
1176 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1178 + " is available for download from "
1179 + jalview.bin.Cache.getDefault("www.jalview.org",
1180 "http://www.jalview.org") + " !!");
1183 message.append("</div>");
1186 message.append("<br>Authors: "
1190 "The Jalview Authors (See AUTHORS file for current list)")
1191 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1192 + "<br><br>For help, see the FAQ at <a href=\"http://www.jalview.org/faq\">www.jalview.org/faq</a> and/or join the jalview-discuss@jalview.org mailing list"
1193 + "<br><br>If you use Jalview, please cite:"
1194 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1195 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1196 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1207 public void documentationMenuItem_actionPerformed(ActionEvent e)
1211 Help.showHelpWindow();
1212 } catch (Exception ex)
1217 public void closeAll_actionPerformed(ActionEvent e)
1219 JInternalFrame[] frames = desktop.getAllFrames();
1220 for (int i = 0; i < frames.length; i++)
1224 frames[i].setClosed(true);
1225 } catch (java.beans.PropertyVetoException ex)
1229 System.out.println("ALL CLOSED");
1230 if (v_client != null)
1232 // TODO clear binding to vamsas document objects on close_all
1237 public void raiseRelated_actionPerformed(ActionEvent e)
1239 reorderAssociatedWindows(false, false);
1242 public void minimizeAssociated_actionPerformed(ActionEvent e)
1244 reorderAssociatedWindows(true, false);
1247 void closeAssociatedWindows()
1249 reorderAssociatedWindows(false, true);
1255 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1258 protected void garbageCollect_actionPerformed(ActionEvent e)
1260 // We simply collect the garbage
1261 jalview.bin.Cache.log.debug("Collecting garbage...");
1263 jalview.bin.Cache.log.debug("Finished garbage collection.");
1270 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1273 protected void showMemusage_actionPerformed(ActionEvent e)
1275 desktop.showMemoryUsage(showMemusage.isSelected());
1282 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1285 protected void showConsole_actionPerformed(ActionEvent e)
1287 showConsole(showConsole.isSelected());
1290 Console jconsole = null;
1293 * control whether the java console is visible or not
1297 void showConsole(boolean selected)
1299 showConsole.setSelected(selected);
1300 // TODO: decide if we should update properties file
1301 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1303 jconsole.setVisible(selected);
1306 void reorderAssociatedWindows(boolean minimize, boolean close)
1308 JInternalFrame[] frames = desktop.getAllFrames();
1309 if (frames == null || frames.length < 1)
1314 AlignViewport source = null, target = null;
1315 if (frames[0] instanceof AlignFrame)
1317 source = ((AlignFrame) frames[0]).getCurrentView();
1319 else if (frames[0] instanceof TreePanel)
1321 source = ((TreePanel) frames[0]).getViewPort();
1323 else if (frames[0] instanceof PCAPanel)
1325 source = ((PCAPanel) frames[0]).av;
1327 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1329 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1334 for (int i = 0; i < frames.length; i++)
1337 if (frames[i] == null)
1341 if (frames[i] instanceof AlignFrame)
1343 target = ((AlignFrame) frames[i]).getCurrentView();
1345 else if (frames[i] instanceof TreePanel)
1347 target = ((TreePanel) frames[i]).getViewPort();
1349 else if (frames[i] instanceof PCAPanel)
1351 target = ((PCAPanel) frames[i]).av;
1353 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1355 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1358 if (source == target)
1364 frames[i].setClosed(true);
1368 frames[i].setIcon(minimize);
1371 frames[i].toFront();
1375 } catch (java.beans.PropertyVetoException ex)
1389 protected void preferences_actionPerformed(ActionEvent e)
1400 public void saveState_actionPerformed(ActionEvent e)
1402 JalviewFileChooser chooser = new JalviewFileChooser(
1403 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1404 { "jvp" }, new String[]
1405 { "Jalview Project" }, "Jalview Project");
1407 chooser.setFileView(new JalviewFileView());
1408 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1410 int value = chooser.showSaveDialog(this);
1412 if (value == JalviewFileChooser.APPROVE_OPTION)
1414 final Desktop me = this;
1415 final java.io.File choice = chooser.getSelectedFile();
1416 new Thread(new Runnable()
1421 setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new String[]{choice.getName()}),
1423 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1424 choice.getParent());
1425 // TODO catch and handle errors for savestate
1426 // TODO prevent user from messing with the Desktop whilst we're saving
1429 new Jalview2XML().SaveState(choice);
1430 } catch (OutOfMemoryError oom)
1432 new OOMWarning("Whilst saving current state to "
1433 + choice.getName(), oom);
1434 } catch (Exception ex)
1437 "Problems whilst trying to save to " + choice.getName(),
1439 JOptionPane.showMessageDialog(
1441 MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new String[]{ choice.getName()}),
1442 MessageManager.getString("label.couldnt_save_project"),
1443 JOptionPane.WARNING_MESSAGE);
1445 setProgressBar(null, choice.hashCode());
1457 public void loadState_actionPerformed(ActionEvent e)
1459 JalviewFileChooser chooser = new JalviewFileChooser(
1460 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1461 { "jvp", "jar" }, new String[]
1462 { "Jalview Project", "Jalview Project (old)" },
1464 chooser.setFileView(new JalviewFileView());
1465 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1467 int value = chooser.showOpenDialog(this);
1469 if (value == JalviewFileChooser.APPROVE_OPTION)
1471 final String choice = chooser.getSelectedFile().getAbsolutePath();
1472 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1473 .getSelectedFile().getParent());
1474 new Thread(new Runnable()
1478 setProgressBar(MessageManager.formatMessage("label.loading_jalview_project", new String[]{choice}),
1482 new Jalview2XML().LoadJalviewAlign(choice);
1483 } catch (OutOfMemoryError oom)
1485 new OOMWarning("Whilst loading project from " + choice, oom);
1486 } catch (Exception ex)
1488 Cache.log.error("Problems whilst loading project from "
1490 JOptionPane.showMessageDialog(Desktop.desktop,
1491 MessageManager.formatMessage("label.error_whilst_loading_project_from", new String[]{choice}),
1492 MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE);
1494 setProgressBar(null, choice.hashCode());
1500 public void inputSequence_actionPerformed(ActionEvent e)
1502 new SequenceFetcher(this);
1505 JPanel progressPanel;
1507 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1509 public void startLoading(final String fileName)
1511 if (fileLoadingCount == 0)
1513 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage("label.loading_file", new String[]{fileName})));
1518 private JPanel addProgressPanel(String string)
1520 if (progressPanel == null)
1522 progressPanel = new JPanel(new GridLayout(1, 1));
1523 totalProgressCount = 0;
1524 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1526 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1527 JProgressBar progressBar = new JProgressBar();
1528 progressBar.setIndeterminate(true);
1530 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1532 thisprogress.add(progressBar, BorderLayout.CENTER);
1533 progressPanel.add(thisprogress);
1534 ((GridLayout) progressPanel.getLayout())
1535 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1536 ++totalProgressCount;
1537 instance.validate();
1538 return thisprogress;
1541 int totalProgressCount = 0;
1543 private void removeProgressPanel(JPanel progbar)
1545 if (progressPanel != null)
1547 synchronized (progressPanel)
1549 progressPanel.remove(progbar);
1550 GridLayout gl = (GridLayout) progressPanel.getLayout();
1551 gl.setRows(gl.getRows() - 1);
1552 if (--totalProgressCount < 1)
1554 this.getContentPane().remove(progressPanel);
1555 progressPanel = null;
1562 public void stopLoading()
1565 if (fileLoadingCount < 1)
1567 while (fileLoadingPanels.size() > 0)
1569 removeProgressPanel(fileLoadingPanels.remove(0));
1571 fileLoadingPanels.clear();
1572 fileLoadingCount = 0;
1577 public static int getViewCount(String alignmentId)
1579 AlignViewport[] aps = getViewports(alignmentId);
1580 return (aps == null) ? 0 : aps.length;
1585 * @param alignmentId
1586 * @return all AlignmentPanels concerning the alignmentId sequence set
1588 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1591 if (Desktop.desktop == null)
1593 // no frames created and in headless mode
1594 // TODO: verify that frames are recoverable when in headless mode
1597 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1598 ArrayList aps = new ArrayList();
1599 for (int t = 0; t < frames.length; t++)
1601 if (frames[t] instanceof AlignFrame)
1603 AlignFrame af = (AlignFrame) frames[t];
1604 for (int a = 0; a < af.alignPanels.size(); a++)
1606 if (alignmentId.equals(((AlignmentPanel) af.alignPanels
1607 .elementAt(a)).av.getSequenceSetId()))
1609 aps.add(af.alignPanels.elementAt(a));
1614 if (aps.size() == 0)
1618 AlignmentPanel[] vap = new AlignmentPanel[aps.size()];
1619 for (int t = 0; t < vap.length; t++)
1621 vap[t] = (AlignmentPanel) aps.get(t);
1627 * get all the viewports on an alignment.
1629 * @param sequenceSetId
1630 * unique alignment id
1631 * @return all viewports on the alignment bound to sequenceSetId
1633 public static AlignViewport[] getViewports(String sequenceSetId)
1635 Vector viewp = new Vector();
1636 if (desktop != null)
1638 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1640 for (int t = 0; t < frames.length; t++)
1642 if (frames[t] instanceof AlignFrame)
1644 AlignFrame afr = ((AlignFrame) frames[t]);
1645 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1647 if (afr.alignPanels != null)
1649 for (int a = 0; a < afr.alignPanels.size(); a++)
1651 if (sequenceSetId.equals(((AlignmentPanel) afr.alignPanels
1652 .elementAt(a)).av.getSequenceSetId()))
1654 viewp.addElement(((AlignmentPanel) afr.alignPanels
1661 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1666 if (viewp.size() > 0)
1668 AlignViewport[] vp = new AlignViewport[viewp.size()];
1676 public void explodeViews(AlignFrame af)
1678 int size = af.alignPanels.size();
1684 for (int i = 0; i < size; i++)
1686 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(i);
1687 AlignFrame newaf = new AlignFrame(ap);
1688 if (ap.av.explodedPosition != null
1689 && !ap.av.explodedPosition.equals(af.getBounds()))
1691 newaf.setBounds(ap.av.explodedPosition);
1694 ap.av.gatherViewsHere = false;
1696 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1697 AlignFrame.DEFAULT_HEIGHT);
1700 af.alignPanels.clear();
1701 af.closeMenuItem_actionPerformed(true);
1705 public void gatherViews(AlignFrame source)
1707 source.viewport.gatherViewsHere = true;
1708 source.viewport.explodedPosition = source.getBounds();
1709 JInternalFrame[] frames = desktop.getAllFrames();
1710 String viewId = source.viewport.getSequenceSetId();
1712 for (int t = 0; t < frames.length; t++)
1714 if (frames[t] instanceof AlignFrame && frames[t] != source)
1716 AlignFrame af = (AlignFrame) frames[t];
1717 boolean gatherThis = false;
1718 for (int a = 0; a < af.alignPanels.size(); a++)
1720 AlignmentPanel ap = (AlignmentPanel) af.alignPanels.elementAt(a);
1721 if (viewId.equals(ap.av.getSequenceSetId()))
1724 ap.av.gatherViewsHere = false;
1725 ap.av.explodedPosition = af.getBounds();
1726 source.addAlignmentPanel(ap, false);
1732 af.alignPanels.clear();
1733 af.closeMenuItem_actionPerformed(true);
1740 jalview.gui.VamsasApplication v_client = null;
1742 public void vamsasImport_actionPerformed(ActionEvent e)
1744 if (v_client == null)
1746 // Load and try to start a session.
1747 JalviewFileChooser chooser = new JalviewFileChooser(
1748 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1750 chooser.setFileView(new JalviewFileView());
1751 chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
1752 chooser.setToolTipText(MessageManager
1753 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1755 int value = chooser.showOpenDialog(this);
1757 if (value == JalviewFileChooser.APPROVE_OPTION)
1759 String fle = chooser.getSelectedFile().toString();
1760 if (!vamsasImport(chooser.getSelectedFile()))
1763 .showInternalMessageDialog(
1765 MessageManager.formatMessage(
1766 "label.couldnt_import_as_vamsas_session",
1770 .getString("label.vamsas_document_import_failed"),
1771 JOptionPane.ERROR_MESSAGE);
1777 jalview.bin.Cache.log
1778 .error("Implementation error - load session from a running session is not supported.");
1783 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1786 * @return true if import was a success and a session was started.
1788 public boolean vamsasImport(URL url)
1790 // TODO: create progress bar
1791 if (v_client != null)
1794 jalview.bin.Cache.log
1795 .error("Implementation error - load session from a running session is not supported.");
1801 // copy the URL content to a temporary local file
1802 // TODO: be a bit cleverer here with nio (?!)
1803 File file = File.createTempFile("vdocfromurl", ".vdj");
1804 FileOutputStream fos = new FileOutputStream(file);
1805 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1806 byte[] buffer = new byte[2048];
1808 while ((ln = bis.read(buffer)) > -1)
1810 fos.write(buffer, 0, ln);
1814 v_client = new jalview.gui.VamsasApplication(this, file,
1815 url.toExternalForm());
1816 } catch (Exception ex)
1818 jalview.bin.Cache.log.error(
1819 "Failed to create new vamsas session from contents of URL "
1823 setupVamsasConnectedGui();
1824 v_client.initial_update(); // TODO: thread ?
1825 return v_client.inSession();
1829 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1832 * @return true if import was a success and a session was started.
1834 public boolean vamsasImport(File file)
1836 if (v_client != null)
1839 jalview.bin.Cache.log
1840 .error("Implementation error - load session from a running session is not supported.");
1844 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1848 v_client = new jalview.gui.VamsasApplication(this, file, null);
1849 } catch (Exception ex)
1851 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1853 jalview.bin.Cache.log.error(
1854 "New vamsas session from existing session file failed:", ex);
1857 setupVamsasConnectedGui();
1858 v_client.initial_update(); // TODO: thread ?
1859 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1861 return v_client.inSession();
1864 public boolean joinVamsasSession(String mysesid)
1866 if (v_client != null)
1868 throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
1870 if (mysesid == null)
1872 throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
1874 v_client = new VamsasApplication(this, mysesid);
1875 setupVamsasConnectedGui();
1876 v_client.initial_update();
1877 return (v_client.inSession());
1880 public void vamsasStart_actionPerformed(ActionEvent e)
1882 if (v_client == null)
1885 // we just start a default session for moment.
1887 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1888 * getProperty("LAST_DIRECTORY"));
1890 * chooser.setFileView(new JalviewFileView());
1891 * chooser.setDialogTitle("Load Vamsas file");
1892 * chooser.setToolTipText("Import");
1894 * int value = chooser.showOpenDialog(this);
1896 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1897 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1899 v_client = new VamsasApplication(this);
1900 setupVamsasConnectedGui();
1901 v_client.initial_update(); // TODO: thread ?
1905 // store current data in session.
1906 v_client.push_update(); // TODO: thread
1910 protected void setupVamsasConnectedGui()
1912 vamsasStart.setText(MessageManager.getString("label.session_update"));
1913 vamsasSave.setVisible(true);
1914 vamsasStop.setVisible(true);
1915 vamsasImport.setVisible(false); // Document import to existing session is
1916 // not possible for vamsas-client-1.0.
1919 protected void setupVamsasDisconnectedGui()
1921 vamsasSave.setVisible(false);
1922 vamsasStop.setVisible(false);
1923 vamsasImport.setVisible(true);
1924 vamsasStart.setText(MessageManager
1925 .getString("label.new_vamsas_session"));
1928 public void vamsasStop_actionPerformed(ActionEvent e)
1930 if (v_client != null)
1932 v_client.end_session();
1934 setupVamsasDisconnectedGui();
1938 protected void buildVamsasStMenu()
1940 if (v_client == null)
1942 String[] sess = null;
1945 sess = VamsasApplication.getSessionList();
1946 } catch (Exception e)
1948 jalview.bin.Cache.log.warn(
1949 "Problem getting current sessions list.", e);
1954 jalview.bin.Cache.log.debug("Got current sessions list: "
1955 + sess.length + " entries.");
1956 VamsasStMenu.removeAll();
1957 for (int i = 0; i < sess.length; i++)
1959 JMenuItem sessit = new JMenuItem();
1960 sessit.setText(sess[i]);
1961 sessit.setToolTipText(MessageManager.formatMessage(
1962 "label.connect_to_session", new String[]
1964 final Desktop dsktp = this;
1965 final String mysesid = sess[i];
1966 sessit.addActionListener(new ActionListener()
1969 public void actionPerformed(ActionEvent e)
1971 if (dsktp.v_client == null)
1973 Thread rthr = new Thread(new Runnable()
1978 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
1979 dsktp.setupVamsasConnectedGui();
1980 dsktp.v_client.initial_update();
1988 VamsasStMenu.add(sessit);
1990 // don't show an empty menu.
1991 VamsasStMenu.setVisible(sess.length > 0);
1996 jalview.bin.Cache.log.debug("No current vamsas sessions.");
1997 VamsasStMenu.removeAll();
1998 VamsasStMenu.setVisible(false);
2003 // Not interested in the content. Just hide ourselves.
2004 VamsasStMenu.setVisible(false);
2008 public void vamsasSave_actionPerformed(ActionEvent e)
2010 if (v_client != null)
2012 JalviewFileChooser chooser = new JalviewFileChooser(
2013 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2014 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2016 { "Vamsas Document" }, "Vamsas Document");
2018 chooser.setFileView(new JalviewFileView());
2019 chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
2021 int value = chooser.showSaveDialog(this);
2023 if (value == JalviewFileChooser.APPROVE_OPTION)
2025 java.io.File choice = chooser.getSelectedFile();
2026 JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new String[]{choice.getName()}));
2027 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2028 String warnmsg = null;
2029 String warnttl = null;
2032 v_client.vclient.storeDocument(choice);
2035 warnttl = "Serious Problem saving Vamsas Document";
2036 warnmsg = ex.toString();
2037 jalview.bin.Cache.log.error("Error Whilst saving document to "
2040 } catch (Exception ex)
2042 warnttl = "Problem saving Vamsas Document.";
2043 warnmsg = ex.toString();
2044 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2048 removeProgressPanel(progpanel);
2049 if (warnmsg != null)
2051 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2053 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2059 JPanel vamUpdate = null;
2062 * hide vamsas user gui bits when a vamsas document event is being handled.
2065 * true to hide gui, false to reveal gui
2067 public void setVamsasUpdate(boolean b)
2069 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2070 + (b ? "in progress" : "finished"));
2072 if (vamUpdate != null)
2074 this.removeProgressPanel(vamUpdate);
2078 vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
2080 vamsasStart.setVisible(!b);
2081 vamsasStop.setVisible(!b);
2082 vamsasSave.setVisible(!b);
2085 public JInternalFrame[] getAllFrames()
2087 return desktop.getAllFrames();
2091 * Checks the given url to see if it gives a response indicating that the user
2092 * should be informed of a new questionnaire.
2096 public void checkForQuestionnaire(String url)
2098 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2099 // javax.swing.SwingUtilities.invokeLater(jvq);
2100 new Thread(jvq).start();
2104 * Proxy class for JDesktopPane which optionally displays the current memory
2105 * usage and highlights the desktop area with a red bar if free memory runs
2110 public class MyDesktopPane extends JDesktopPane implements Runnable
2113 boolean showMemoryUsage = false;
2117 java.text.NumberFormat df;
2119 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2122 public MyDesktopPane(boolean showMemoryUsage)
2124 showMemoryUsage(showMemoryUsage);
2127 public void showMemoryUsage(boolean showMemoryUsage)
2129 this.showMemoryUsage = showMemoryUsage;
2130 if (showMemoryUsage)
2132 Thread worker = new Thread(this);
2137 public boolean isShowMemoryUsage()
2139 return showMemoryUsage;
2144 df = java.text.NumberFormat.getNumberInstance();
2145 df.setMaximumFractionDigits(2);
2146 runtime = Runtime.getRuntime();
2148 while (showMemoryUsage)
2152 maxMemory = runtime.maxMemory() / 1048576f;
2153 allocatedMemory = runtime.totalMemory() / 1048576f;
2154 freeMemory = runtime.freeMemory() / 1048576f;
2155 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2157 percentUsage = (totalFreeMemory / maxMemory) * 100;
2159 // if (percentUsage < 20)
2161 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2163 // instance.set.setBorder(border1);
2166 // sleep after showing usage
2168 } catch (Exception ex)
2170 ex.printStackTrace();
2175 public void paintComponent(Graphics g)
2177 if (showMemoryUsage && g != null && df != null)
2179 if (percentUsage < 20)
2181 g.setColor(Color.red);
2183 FontMetrics fm = g.getFontMetrics();
2186 g.drawString(MessageManager.formatMessage(
2187 "label.memory_stats",
2189 { df.format(totalFreeMemory), df.format(maxMemory),
2190 df.format(percentUsage) }), 10,
2191 getHeight() - fm.getHeight());
2198 * fixes stacking order after a modal dialog to ensure windows that should be
2199 * on top actually are
2201 public void relayerWindows()
2206 protected JMenuItem groovyShell;
2208 public void doGroovyCheck()
2210 if (jalview.bin.Cache.groovyJarsPresent())
2212 groovyShell = new JMenuItem();
2213 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2214 groovyShell.addActionListener(new ActionListener()
2216 public void actionPerformed(ActionEvent e)
2218 groovyShell_actionPerformed(e);
2221 toolsMenu.add(groovyShell);
2222 groovyShell.setVisible(true);
2227 * Accessor method to quickly get all the AlignmentFrames loaded.
2229 public static AlignFrame[] getAlignframes()
2231 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2237 Vector avp = new Vector();
2241 for (int i = frames.length - 1; i > -1; i--)
2243 if (frames[i] instanceof AlignFrame)
2245 AlignFrame af = (AlignFrame) frames[i];
2249 } catch (Exception ex)
2251 ex.printStackTrace();
2253 if (avp.size() == 0)
2257 AlignFrame afs[] = new AlignFrame[avp.size()];
2258 for (int i = 0, j = avp.size(); i < j; i++)
2260 afs[i] = (AlignFrame) avp.elementAt(i);
2266 public AppJmol[] getJmols()
2268 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2274 Vector avp = new Vector();
2278 for (int i = frames.length - 1; i > -1; i--)
2280 if (frames[i] instanceof AppJmol)
2282 AppJmol af = (AppJmol) frames[i];
2286 } catch (Exception ex)
2288 ex.printStackTrace();
2290 if (avp.size() == 0)
2294 AppJmol afs[] = new AppJmol[avp.size()];
2295 for (int i = 0, j = avp.size(); i < j; i++)
2297 afs[i] = (AppJmol) avp.elementAt(i);
2304 * Add Groovy Support to Jalview
2306 public void groovyShell_actionPerformed(ActionEvent e)
2308 // use reflection to avoid creating compilation dependency.
2309 if (!jalview.bin.Cache.groovyJarsPresent())
2311 throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
2315 Class gcClass = Desktop.class.getClassLoader().loadClass(
2316 "groovy.ui.Console");
2317 Constructor gccons = gcClass.getConstructor(null);
2318 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2320 { String.class, Object.class });
2321 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2322 Object gc = gccons.newInstance(null);
2323 setvar.invoke(gc, new Object[]
2324 { "Jalview", this });
2325 run.invoke(gc, null);
2326 } catch (Exception ex)
2328 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2330 .showInternalMessageDialog(
2333 MessageManager.getString("label.couldnt_create_groovy_shell"),
2334 MessageManager.getString("label.groovy_support_failed"),
2335 JOptionPane.ERROR_MESSAGE);
2340 * Progress bars managed by the IProgressIndicator method.
2342 private Hashtable<Long, JPanel> progressBars;
2344 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2349 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2351 public void setProgressBar(String message, long id)
2353 if (progressBars == null)
2355 progressBars = new Hashtable<Long, JPanel>();
2356 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2359 if (progressBars.get(new Long(id)) != null)
2361 JPanel progressPanel = progressBars.remove(new Long(id));
2362 if (progressBarHandlers.contains(new Long(id)))
2364 progressBarHandlers.remove(new Long(id));
2366 removeProgressPanel(progressPanel);
2370 progressBars.put(new Long(id), addProgressPanel(message));
2377 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2378 * jalview.gui.IProgressIndicatorHandler)
2380 public void registerHandler(final long id,
2381 final IProgressIndicatorHandler handler)
2383 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2385 throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
2387 progressBarHandlers.put(new Long(id), handler);
2388 final JPanel progressPanel = progressBars.get(new Long(id));
2389 if (handler.canCancel())
2391 JButton cancel = new JButton(
2392 MessageManager.getString("action.cancel"));
2393 final IProgressIndicator us = this;
2394 cancel.addActionListener(new ActionListener()
2397 public void actionPerformed(ActionEvent e)
2399 handler.cancelActivity(id);
2400 us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
2403 progressPanel.add(cancel, BorderLayout.EAST);
2409 * @return true if any progress bars are still active
2412 public boolean operationInProgress()
2414 if (progressBars != null && progressBars.size() > 0)
2422 * This will return the first AlignFrame viewing AlignViewport av. It will
2423 * break if there are more than one AlignFrames viewing a particular av. This
2426 * @return alignFrame for av
2428 public static AlignFrame getAlignFrameFor(AlignViewport av)
2430 if (desktop != null)
2432 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2433 for (int panel = 0; aps != null && panel < aps.length; panel++)
2435 if (aps[panel] != null && aps[panel].av == av)
2437 return aps[panel].alignFrame;
2444 public VamsasApplication getVamsasApplication()
2451 * flag set if jalview GUI is being operated programmatically
2453 private boolean inBatchMode = false;
2456 * check if jalview GUI is being operated programmatically
2458 * @return inBatchMode
2460 public boolean isInBatchMode()
2466 * set flag if jalview GUI is being operated programmatically
2468 * @param inBatchMode
2470 public void setInBatchMode(boolean inBatchMode)
2472 this.inBatchMode = inBatchMode;
2475 public void startServiceDiscovery()
2477 startServiceDiscovery(false);
2480 public void startServiceDiscovery(boolean blocking)
2482 boolean alive = true;
2483 Thread t0 = null, t1 = null, t2 = null;
2484 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2487 // todo: changesupport handlers need to be transferred
2488 if (discoverer == null)
2490 discoverer = new jalview.ws.jws1.Discoverer();
2491 // register PCS handler for desktop.
2492 discoverer.addPropertyChangeListener(changeSupport);
2494 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2495 // until we phase out completely
2496 (t0 = new Thread(discoverer)).start();
2499 // ENFIN services are EOLed as of Jalview 2.8.1 release
2504 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2506 // EnfinEnvision web service menu entries are rebuild every time the
2507 // menu is shown, so no changeSupport events are needed.
2508 jalview.ws.EnfinEnvision2OneWay.getInstance();
2509 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2512 } catch (Exception e)
2515 .info("Exception when trying to launch Envision2 workflow discovery.",
2517 Cache.log.info(e.getStackTrace());
2521 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2523 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2525 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2527 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2533 // TODO: do rest service discovery
2542 } catch (Exception e)
2545 alive = (t1 != null && t1.isAlive())
2546 || (t2 != null && t2.isAlive())
2547 || (t3 != null && t3.isAlive())
2548 || (t0 != null && t0.isAlive());
2554 * called to check if the service discovery process completed successfully.
2558 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2560 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2562 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2563 .getErrorMessages();
2566 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2568 if (serviceChangedDialog == null)
2570 // only run if we aren't already displaying one of these.
2571 addDialogThread(serviceChangedDialog = new Runnable()
2577 * JalviewDialog jd =new JalviewDialog() {
2579 * @Override protected void cancelPressed() { // TODO
2580 * Auto-generated method stub
2582 * }@Override protected void okPressed() { // TODO
2583 * Auto-generated method stub
2585 * }@Override protected void raiseClosed() { // TODO
2586 * Auto-generated method stub
2588 * } }; jd.initDialogFrame(new
2589 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2590 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2591 * + " or mis-configured HTTP proxy settings.<br/>" +
2592 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2594 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2595 * ), true, true, "Web Service Configuration Problem", 450,
2598 * jd.waitForInput();
2604 "<html><table width=\"450\"><tr><td>"
2606 + "</td></tr></table>"
2607 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2608 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2609 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2610 + " Tools->Preferences dialog box to change them.</p></html>"),
2611 "Web Service Configuration Problem",
2612 JOptionPane.DEFAULT_OPTION,
2613 JOptionPane.ERROR_MESSAGE);
2614 serviceChangedDialog = null;
2623 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2630 private Runnable serviceChangedDialog = null;
2633 * start a thread to open a URL in the configured browser. Pops up a warning
2634 * dialog to the user if there is an exception when calling out to the browser
2639 public static void showUrl(final String url)
2641 showUrl(url, Desktop.instance);
2645 * Like showUrl but allows progress handler to be specified
2649 * (null) or object implementing IProgressIndicator
2651 public static void showUrl(final String url,
2652 final IProgressIndicator progress)
2654 new Thread(new Runnable()
2660 if (progress != null)
2662 progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new String[]{url}), this.hashCode());
2664 jalview.util.BrowserLauncher.openURL(url);
2665 } catch (Exception ex)
2668 .showInternalMessageDialog(
2670 MessageManager.getString("label.web_browser_not_found_unix"),
2671 MessageManager.getString("label.web_browser_not_found"),
2672 JOptionPane.WARNING_MESSAGE);
2674 ex.printStackTrace();
2676 if (progress != null)
2678 progress.setProgressBar(null, this.hashCode());
2684 public static WsParamSetManager wsparamManager = null;
2686 public static ParamManager getUserParameterStore()
2688 if (wsparamManager == null)
2690 wsparamManager = new WsParamSetManager();
2692 return wsparamManager;
2696 * static hyperlink handler proxy method for use by Jalview's internal windows
2700 public static void hyperlinkUpdate(HyperlinkEvent e)
2702 if (e.getEventType() == EventType.ACTIVATED)
2707 url = e.getURL().toString();
2708 Desktop.showUrl(url);
2709 } catch (Exception x)
2713 if (Cache.log != null)
2715 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2719 System.err.println("Couldn't handle string " + url
2723 // ignore any exceptions due to dud links.
2730 * single thread that handles display of dialogs to user.
2732 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2735 * flag indicating if dialogExecutor should try to acquire a permit
2737 private volatile boolean dialogPause = true;
2742 private java.util.concurrent.Semaphore block = new Semaphore(0);
2745 * add another dialog thread to the queue
2749 public void addDialogThread(final Runnable prompter)
2751 dialogExecutor.submit(new Runnable()
2760 } catch (InterruptedException x)
2765 if (instance == null)
2771 SwingUtilities.invokeAndWait(prompter);
2772 } catch (Exception q)
2774 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2780 public void startDialogQueue()
2782 // set the flag so we don't pause waiting for another permit and semaphore
2783 // the current task to begin
2784 dialogPause = false;
2788 protected void snapShotWindow_actionPerformed(ActionEvent e)
2792 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2793 "View of Desktop", getWidth(), getHeight(), of = new File(
2794 "Jalview_snapshot" + System.currentTimeMillis()
2795 + ".eps"), "View of desktop");
2797 paintAll(im.getGraphics());
2799 } catch (Exception q)
2801 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2804 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());