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.viewmodel.AlignmentViewport;
33 import jalview.ws.params.ParamManager;
35 import java.awt.BorderLayout;
36 import java.awt.Color;
37 import java.awt.Dimension;
38 import java.awt.FontMetrics;
39 import java.awt.Graphics;
40 import java.awt.GridLayout;
41 import java.awt.Point;
42 import java.awt.Rectangle;
43 import java.awt.Toolkit;
44 import java.awt.datatransfer.Clipboard;
45 import java.awt.datatransfer.ClipboardOwner;
46 import java.awt.datatransfer.DataFlavor;
47 import java.awt.datatransfer.Transferable;
48 import java.awt.dnd.DnDConstants;
49 import java.awt.dnd.DropTargetDragEvent;
50 import java.awt.dnd.DropTargetDropEvent;
51 import java.awt.dnd.DropTargetEvent;
52 import java.awt.dnd.DropTargetListener;
53 import java.awt.event.ActionEvent;
54 import java.awt.event.ActionListener;
55 import java.awt.event.FocusEvent;
56 import java.awt.event.FocusListener;
57 import java.awt.event.MouseAdapter;
58 import java.awt.event.MouseEvent;
59 import java.awt.event.MouseListener;
60 import java.awt.event.WindowAdapter;
61 import java.awt.event.WindowEvent;
62 import java.beans.PropertyChangeEvent;
63 import java.beans.PropertyChangeListener;
64 import java.beans.PropertyVetoException;
65 import java.io.BufferedInputStream;
67 import java.io.FileOutputStream;
68 import java.lang.reflect.Constructor;
70 import java.util.ArrayList;
71 import java.util.Hashtable;
72 import java.util.List;
73 import java.util.StringTokenizer;
74 import java.util.Vector;
75 import java.util.concurrent.ExecutorService;
76 import java.util.concurrent.Executors;
77 import java.util.concurrent.Semaphore;
79 import javax.swing.DefaultDesktopManager;
80 import javax.swing.DesktopManager;
81 import javax.swing.JButton;
82 import javax.swing.JComboBox;
83 import javax.swing.JComponent;
84 import javax.swing.JDesktopPane;
85 import javax.swing.JFrame;
86 import javax.swing.JInternalFrame;
87 import javax.swing.JLabel;
88 import javax.swing.JMenuItem;
89 import javax.swing.JOptionPane;
90 import javax.swing.JPanel;
91 import javax.swing.JPopupMenu;
92 import javax.swing.JProgressBar;
93 import javax.swing.SwingUtilities;
94 import javax.swing.event.HyperlinkEvent;
95 import javax.swing.event.HyperlinkEvent.EventType;
96 import javax.swing.event.MenuEvent;
97 import javax.swing.event.MenuListener;
104 * @version $Revision: 1.155 $
106 public class Desktop extends jalview.jbgui.GDesktop implements
107 DropTargetListener, ClipboardOwner, IProgressIndicator,
108 jalview.api.StructureSelectionManagerProvider
111 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
114 * news reader - null if it was never started.
116 private BlogReader jvnews = null;
120 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
122 public void addJalviewPropertyChangeListener(
123 PropertyChangeListener listener)
125 changeSupport.addJalviewPropertyChangeListener(listener);
129 * @param propertyName
131 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
132 * java.beans.PropertyChangeListener)
134 public void addJalviewPropertyChangeListener(String propertyName,
135 PropertyChangeListener listener)
137 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
141 * @param propertyName
143 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
144 * java.beans.PropertyChangeListener)
146 public void removeJalviewPropertyChangeListener(String propertyName,
147 PropertyChangeListener listener)
149 changeSupport.removeJalviewPropertyChangeListener(propertyName,
153 /** Singleton Desktop instance */
154 public static Desktop instance;
156 public static MyDesktopPane desktop;
158 static int openFrameCount = 0;
160 static final int xOffset = 30;
162 static final int yOffset = 30;
164 private static final int THREE = 3;
166 public static jalview.ws.jws1.Discoverer discoverer;
168 public static Object[] jalviewClipboard;
170 public static boolean internalCopy = false;
172 static int fileLoadingCount = 0;
174 class MyDesktopManager implements DesktopManager
177 private DesktopManager delegate;
179 public MyDesktopManager(DesktopManager delegate)
181 this.delegate = delegate;
184 public void activateFrame(JInternalFrame f)
188 delegate.activateFrame(f);
189 } catch (NullPointerException npe)
191 Point p = getMousePosition();
192 instance.showPasteMenu(p.x, p.y);
196 public void beginDraggingFrame(JComponent f)
198 delegate.beginDraggingFrame(f);
201 public void beginResizingFrame(JComponent f, int direction)
203 delegate.beginResizingFrame(f, direction);
206 public void closeFrame(JInternalFrame f)
208 delegate.closeFrame(f);
211 public void deactivateFrame(JInternalFrame f)
213 delegate.deactivateFrame(f);
216 public void deiconifyFrame(JInternalFrame f)
218 delegate.deiconifyFrame(f);
221 public void dragFrame(JComponent f, int newX, int newY)
227 delegate.dragFrame(f, newX, newY);
230 public void endDraggingFrame(JComponent f)
232 delegate.endDraggingFrame(f);
235 public void endResizingFrame(JComponent f)
237 delegate.endResizingFrame(f);
240 public void iconifyFrame(JInternalFrame f)
242 delegate.iconifyFrame(f);
245 public void maximizeFrame(JInternalFrame f)
247 delegate.maximizeFrame(f);
250 public void minimizeFrame(JInternalFrame f)
252 delegate.minimizeFrame(f);
255 public void openFrame(JInternalFrame f)
257 delegate.openFrame(f);
260 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
263 Rectangle b = desktop.getBounds();
268 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
271 public void setBoundsForFrame(JComponent f, int newX, int newY,
272 int newWidth, int newHeight)
274 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
277 // All other methods, simply delegate
282 * Creates a new Desktop object.
287 * A note to implementors. It is ESSENTIAL that any activities that might
288 * block are spawned off as threads rather than waited for during this
292 doVamsasClientCheck();
294 doConfigureStructurePrefs();
295 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
296 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
297 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
299 boolean showjconsole = jalview.bin.Cache.getDefault(
300 "SHOW_JAVA_CONSOLE", false);
301 desktop = new MyDesktopPane(selmemusage);
302 showMemusage.setSelected(selmemusage);
303 desktop.setBackground(Color.white);
304 getContentPane().setLayout(new BorderLayout());
305 // alternate config - have scrollbars - see notes in JAL-153
306 // JScrollPane sp = new JScrollPane();
307 // sp.getViewport().setView(desktop);
308 // getContentPane().add(sp, BorderLayout.CENTER);
309 getContentPane().add(desktop, BorderLayout.CENTER);
310 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
312 // This line prevents Windows Look&Feel resizing all new windows to maximum
313 // if previous window was maximised
314 desktop.setDesktopManager(new MyDesktopManager(
315 new DefaultDesktopManager()));
317 Rectangle dims = getLastKnownDimensions("");
324 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
325 setBounds((screenSize.width - 900) / 2,
326 (screenSize.height - 650) / 2, 900, 650);
328 jconsole = new Console(this, showjconsole);
329 // add essential build information
330 jconsole.setHeader("Jalview Version: "
331 + jalview.bin.Cache.getProperty("VERSION") + "\n"
332 + "Jalview Installation: "
333 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
336 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
337 + "Java version: " + System.getProperty("java.version") + "\n"
338 + System.getProperty("os.arch") + " "
339 + System.getProperty("os.name") + " "
340 + System.getProperty("os.version"));
342 showConsole(showjconsole);
344 showNews.setVisible(false);
346 this.addWindowListener(new WindowAdapter()
348 public void windowClosing(WindowEvent evt)
355 this.addMouseListener(ma = new MouseAdapter()
357 public void mousePressed(MouseEvent evt)
359 if (SwingUtilities.isRightMouseButton(evt))
361 showPasteMenu(evt.getX(), evt.getY());
365 desktop.addMouseListener(ma);
367 this.addFocusListener(new FocusListener()
371 public void focusLost(FocusEvent e)
373 // TODO Auto-generated method stub
378 public void focusGained(FocusEvent e)
380 Cache.log.debug("Relaying windows after focus gain");
381 // make sure that we sort windows properly after we gain focus
382 instance.relayerWindows();
385 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
386 // Spawn a thread that shows the splashscreen
387 SwingUtilities.invokeLater(new Runnable()
396 // Thread off a new instance of the file chooser - this reduces the time it
397 // takes to open it later on.
398 new Thread(new Runnable()
402 Cache.log.debug("Filechooser init thread started.");
403 JalviewFileChooser chooser = new JalviewFileChooser(
404 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
405 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
406 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
407 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
408 Cache.log.debug("Filechooser init thread finished.");
411 // Add the service change listener
412 changeSupport.addJalviewPropertyChangeListener("services",
413 new PropertyChangeListener()
417 public void propertyChange(PropertyChangeEvent evt)
419 Cache.log.debug("Firing service changed event for "
420 + evt.getNewValue());
421 JalviewServicesChanged(evt);
427 public void doConfigureStructurePrefs()
429 // configure services
430 StructureSelectionManager ssm = StructureSelectionManager
431 .getStructureSelectionManager(this);
432 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
434 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
435 Preferences.ADD_TEMPFACT_ANN, true));
436 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(Preferences.STRUCT_FROM_PDB, true));
437 ssm.setSecStructServices(jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW,
442 ssm.setAddTempFacAnnot(false);
443 ssm.setProcessSecondaryStructure(false);
444 ssm.setSecStructServices(false);
448 public void checkForNews()
450 final Desktop me = this;
451 // Thread off the news reader, in case there are connection problems.
452 addDialogThread(new Runnable()
457 Cache.log.debug("Starting news thread.");
459 jvnews = new BlogReader(me);
460 showNews.setVisible(true);
461 Cache.log.debug("Completed news thread.");
466 protected void showNews_actionPerformed(ActionEvent e)
468 showNews(showNews.isSelected());
471 void showNews(boolean visible)
474 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
475 showNews.setSelected(visible);
476 if (visible && !jvnews.isVisible())
478 new Thread(new Runnable()
483 long instance = System.currentTimeMillis();
484 Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_news"), instance);
485 jvnews.refreshNews();
486 Desktop.instance.setProgressBar(null, instance);
495 * recover the last known dimensions for a jalview window
498 * - empty string is desktop, all other windows have unique prefix
499 * @return null or last known dimensions scaled to current geometry (if last
500 * window geom was known)
502 Rectangle getLastKnownDimensions(String windowName)
504 // TODO: lock aspect ratio for scaling desktop Bug #0058199
505 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
506 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
507 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
508 String width = jalview.bin.Cache.getProperty(windowName
510 String height = jalview.bin.Cache.getProperty(windowName
512 if ((x != null) && (y != null) && (width != null) && (height != null))
514 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
515 .parseInt(width), ih = Integer.parseInt(height);
516 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
518 // attempt #1 - try to cope with change in screen geometry - this
519 // version doesn't preserve original jv aspect ratio.
520 // take ratio of current screen size vs original screen size.
521 double sw = ((1f * screenSize.width) / (1f * Integer
522 .parseInt(jalview.bin.Cache
523 .getProperty("SCREENGEOMETRY_WIDTH"))));
524 double sh = ((1f * screenSize.height) / (1f * Integer
525 .parseInt(jalview.bin.Cache
526 .getProperty("SCREENGEOMETRY_HEIGHT"))));
527 // rescale the bounds depending upon the current screen geometry.
528 ix = (int) (ix * sw);
529 iw = (int) (iw * sw);
530 iy = (int) (iy * sh);
531 ih = (int) (ih * sh);
532 while (ix >= screenSize.width)
534 jalview.bin.Cache.log
535 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
536 ix -= screenSize.width;
538 while (iy >= screenSize.height)
540 jalview.bin.Cache.log
541 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
542 iy -= screenSize.height;
544 jalview.bin.Cache.log.debug("Got last known dimensions for "
545 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
548 // return dimensions for new instance
549 return new Rectangle(ix, iy, iw, ih);
554 private void doVamsasClientCheck()
556 if (jalview.bin.Cache.vamsasJarsPresent())
558 setupVamsasDisconnectedGui();
559 VamsasMenu.setVisible(true);
560 final Desktop us = this;
561 VamsasMenu.addMenuListener(new MenuListener()
563 // this listener remembers when the menu was first selected, and
564 // doesn't rebuild the session list until it has been cleared and
566 boolean refresh = true;
568 public void menuCanceled(MenuEvent e)
573 public void menuDeselected(MenuEvent e)
578 public void menuSelected(MenuEvent e)
582 us.buildVamsasStMenu();
587 vamsasStart.setVisible(true);
591 void showPasteMenu(int x, int y)
593 JPopupMenu popup = new JPopupMenu();
594 JMenuItem item = new JMenuItem(
595 MessageManager.getString("label.paste_new_window"));
596 item.addActionListener(new ActionListener()
598 public void actionPerformed(ActionEvent evt)
605 popup.show(this, x, y);
612 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
613 Transferable contents = c.getContents(this);
615 if (contents != null)
617 String file = (String) contents
618 .getTransferData(DataFlavor.stringFlavor);
620 String format = new IdentifyFile().Identify(file,
621 FormatAdapter.PASTE);
623 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
626 } catch (Exception ex)
629 .println("Unable to paste alignment from system clipboard:\n"
635 * Adds and opens the given frame to the desktop
646 public static synchronized void addInternalFrame(
647 final JInternalFrame frame, String title, int w, int h)
649 addInternalFrame(frame, title, true, w, h, true);
654 * Add an internal frame to the Jalview desktop
661 * When true, display frame immediately, otherwise, caller must call
662 * setVisible themselves.
668 public static synchronized void addInternalFrame(
669 final JInternalFrame frame, String title, boolean makeVisible,
672 addInternalFrame(frame, title, makeVisible, w, h, true);
676 * Add an internal frame to the Jalview desktop and make it visible
689 public static synchronized void addInternalFrame(
690 final JInternalFrame frame, String title, int w, int h,
693 addInternalFrame(frame, title, true, w, h, resizable);
697 * Add an internal frame to the Jalview desktop
704 * When true, display frame immediately, otherwise, caller must call
705 * setVisible themselves.
713 public static synchronized void addInternalFrame(
714 final JInternalFrame frame, String title, boolean makeVisible,
715 int w, int h, boolean resizable)
718 // TODO: allow callers to determine X and Y position of frame (eg. via
720 // TODO: consider fixing method to update entries in the window submenu with
721 // the current window title
723 frame.setTitle(title);
724 if (frame.getWidth() < 1 || frame.getHeight() < 1)
728 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
729 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
730 // IF JALVIEW IS RUNNING HEADLESS
731 // ///////////////////////////////////////////////
733 || (System.getProperty("java.awt.headless") != null && System
734 .getProperty("java.awt.headless").equals("true")))
741 frame.setVisible(makeVisible);
742 frame.setClosable(true);
743 frame.setResizable(resizable);
744 frame.setMaximizable(resizable);
745 frame.setIconifiable(resizable);
746 frame.setFrameIcon(null);
748 if (frame.getX() < 1 && frame.getY() < 1)
750 frame.setLocation(xOffset * openFrameCount, yOffset
751 * ((openFrameCount - 1) % 10) + yOffset);
754 final JMenuItem menuItem = new JMenuItem(title);
755 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
757 public void internalFrameActivated(
758 javax.swing.event.InternalFrameEvent evt)
760 JInternalFrame itf = desktop.getSelectedFrame();
768 public void internalFrameClosed(
769 javax.swing.event.InternalFrameEvent evt)
771 PaintRefresher.RemoveComponent(frame);
773 windowMenu.remove(menuItem);
774 JInternalFrame itf = desktop.getSelectedFrame();
783 menuItem.addActionListener(new ActionListener()
785 public void actionPerformed(ActionEvent e)
789 frame.setSelected(true);
790 frame.setIcon(false);
791 } catch (java.beans.PropertyVetoException ex)
797 menuItem.addMouseListener(new MouseListener()
801 public void mouseReleased(MouseEvent e)
806 public void mousePressed(MouseEvent e)
811 public void mouseExited(MouseEvent e)
815 frame.setSelected(false);
816 } catch (PropertyVetoException e1)
822 public void mouseEntered(MouseEvent e)
826 frame.setSelected(true);
827 } catch (PropertyVetoException e1)
833 public void mouseClicked(MouseEvent e)
839 windowMenu.add(menuItem);
845 frame.setSelected(true);
846 frame.requestFocus();
847 } catch (java.beans.PropertyVetoException ve)
849 } catch (java.lang.ClassCastException cex)
852 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
857 public void lostOwnership(Clipboard clipboard, Transferable contents)
861 Desktop.jalviewClipboard = null;
864 internalCopy = false;
867 public void dragEnter(DropTargetDragEvent evt)
871 public void dragExit(DropTargetEvent evt)
875 public void dragOver(DropTargetDragEvent evt)
879 public void dropActionChanged(DropTargetDragEvent evt)
889 public void drop(DropTargetDropEvent evt)
891 boolean success = true;
892 Transferable t = evt.getTransferable();
893 java.util.List files = null;
894 java.util.List protocols = null;
898 DataFlavor uriListFlavor = new DataFlavor(
899 "text/uri-list;class=java.lang.String");
900 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
902 // Works on Windows and MacOSX
903 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
904 files = (java.util.List) t
905 .getTransferData(DataFlavor.javaFileListFlavor);
907 else if (t.isDataFlavorSupported(uriListFlavor))
909 // This is used by Unix drag system
910 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
911 String data = (String) t.getTransferData(uriListFlavor);
912 files = new java.util.ArrayList(1);
913 protocols = new java.util.ArrayList(1);
914 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
915 data, "\r\n"); st.hasMoreTokens();)
917 String s = st.nextToken();
918 if (s.startsWith("#"))
920 // the line is a comment (as per the RFC 2483)
923 java.net.URI uri = new java.net.URI(s);
924 if (uri.getScheme().toLowerCase().startsWith("http"))
926 protocols.add(FormatAdapter.URL);
927 files.add(uri.toString());
931 // otherwise preserve old behaviour: catch all for file objects
932 java.io.File file = new java.io.File(uri);
933 protocols.add(FormatAdapter.FILE);
934 files.add(file.toString());
938 } catch (Exception e)
947 for (int i = 0; i < files.size(); i++)
949 String file = files.get(i).toString();
950 String protocol = (protocols == null) ? FormatAdapter.FILE
951 : (String) protocols.get(i);
952 String format = null;
954 if (file.endsWith(".jar"))
961 format = new IdentifyFile().Identify(file, protocol);
964 new FileLoader().LoadFile(file, protocol, format);
967 } catch (Exception ex)
972 evt.dropComplete(success); // need this to ensure input focus is properly
973 // transfered to any new windows created
982 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
984 JalviewFileChooser chooser = new JalviewFileChooser(
985 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
986 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
987 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
988 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
990 chooser.setFileView(new JalviewFileView());
991 chooser.setDialogTitle(MessageManager
992 .getString("label.open_local_file"));
993 chooser.setToolTipText(MessageManager.getString("action.open"));
995 int value = chooser.showOpenDialog(this);
997 if (value == JalviewFileChooser.APPROVE_OPTION)
999 String choice = chooser.getSelectedFile().getPath();
1000 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1001 .getSelectedFile().getParent());
1003 String format = null;
1004 if (chooser.getSelectedFormat() != null
1005 && chooser.getSelectedFormat().equals("Jalview"))
1011 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1014 if (viewport != null)
1016 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1021 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1032 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1034 // This construct allows us to have a wider textfield
1036 JLabel label = new JLabel(
1037 MessageManager.getString("label.input_file_url"));
1038 final JComboBox history = new JComboBox();
1040 JPanel panel = new JPanel(new GridLayout(2, 1));
1043 history.setPreferredSize(new Dimension(400, 20));
1044 history.setEditable(true);
1045 history.addItem("http://www.");
1047 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1051 if (historyItems != null)
1053 st = new StringTokenizer(historyItems, "\t");
1055 while (st.hasMoreTokens())
1057 history.addItem(st.nextElement());
1061 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1062 MessageManager.getString("label.input_alignment_from_url"),
1063 JOptionPane.OK_CANCEL_OPTION);
1065 if (reply != JOptionPane.OK_OPTION)
1070 String url = history.getSelectedItem().toString();
1072 if (url.toLowerCase().endsWith(".jar"))
1074 if (viewport != null)
1076 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1081 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1086 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1088 if (format.equals("URL NOT FOUND"))
1090 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1091 MessageManager.formatMessage("label.couldnt_locate", new String[]{url}), MessageManager.getString("label.url_not_found"),
1092 JOptionPane.WARNING_MESSAGE);
1097 if (viewport != null)
1099 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1103 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1114 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1116 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1117 cap.setForInput(viewport);
1118 Desktop.addInternalFrame(cap,
1119 MessageManager.getString("label.cut_paste_alignmen_file"),
1128 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1130 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1131 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1133 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1134 getBounds().y, getWidth(), getHeight()));
1136 if (jconsole != null)
1138 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1139 jconsole.stopConsole();
1143 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1146 if (dialogExecutor != null)
1148 dialogExecutor.shutdownNow();
1154 private void storeLastKnownDimensions(String string, Rectangle jc)
1156 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1157 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1158 + " height:" + jc.height);
1160 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1161 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1162 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1163 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1172 public void aboutMenuItem_actionPerformed(ActionEvent e)
1174 // StringBuffer message = getAboutMessage(false);
1175 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1177 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1178 new Thread(new Runnable()
1182 new SplashScreen(true);
1187 public StringBuffer getAboutMessage(boolean shortv)
1189 StringBuffer message = new StringBuffer();
1190 message.append("<html>");
1193 message.append("<h1><strong>Version: "
1194 + jalview.bin.Cache.getProperty("VERSION")
1195 + "</strong></h1>");
1196 message.append("<strong>Last Updated: <em>"
1197 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1198 + "</em></strong>");
1204 message.append("<strong>Version "
1205 + jalview.bin.Cache.getProperty("VERSION")
1206 + "; last updated: "
1207 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1210 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1213 message.append("<br>...Checking latest version...</br>");
1215 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1216 .equals(jalview.bin.Cache.getProperty("VERSION")))
1218 boolean red = false;
1219 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1220 .indexOf("automated build") == -1)
1223 // Displayed when code version and jnlp version do not match and code
1224 // version is not a development build
1225 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1228 message.append("<br>!! Version "
1229 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1231 + " is available for download from "
1232 + jalview.bin.Cache.getDefault("www.jalview.org",
1233 "http://www.jalview.org") + " !!");
1236 message.append("</div>");
1239 message.append("<br>Authors: "
1243 "The Jalview Authors (See AUTHORS file for current list)")
1244 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1245 + "<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"
1246 + "<br><br>If you use Jalview, please cite:"
1247 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1248 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1249 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1260 public void documentationMenuItem_actionPerformed(ActionEvent e)
1264 Help.showHelpWindow();
1265 } catch (Exception ex)
1270 public void closeAll_actionPerformed(ActionEvent e)
1272 JInternalFrame[] frames = desktop.getAllFrames();
1273 for (int i = 0; i < frames.length; i++)
1277 frames[i].setClosed(true);
1278 } catch (java.beans.PropertyVetoException ex)
1282 System.out.println("ALL CLOSED");
1283 if (v_client != null)
1285 // TODO clear binding to vamsas document objects on close_all
1290 public void raiseRelated_actionPerformed(ActionEvent e)
1292 reorderAssociatedWindows(false, false);
1295 public void minimizeAssociated_actionPerformed(ActionEvent e)
1297 reorderAssociatedWindows(true, false);
1300 void closeAssociatedWindows()
1302 reorderAssociatedWindows(false, true);
1308 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1311 protected void garbageCollect_actionPerformed(ActionEvent e)
1313 // We simply collect the garbage
1314 jalview.bin.Cache.log.debug("Collecting garbage...");
1316 jalview.bin.Cache.log.debug("Finished garbage collection.");
1323 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1326 protected void showMemusage_actionPerformed(ActionEvent e)
1328 desktop.showMemoryUsage(showMemusage.isSelected());
1335 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1338 protected void showConsole_actionPerformed(ActionEvent e)
1340 showConsole(showConsole.isSelected());
1343 Console jconsole = null;
1346 * control whether the java console is visible or not
1350 void showConsole(boolean selected)
1352 showConsole.setSelected(selected);
1353 // TODO: decide if we should update properties file
1354 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1356 jconsole.setVisible(selected);
1359 void reorderAssociatedWindows(boolean minimize, boolean close)
1361 JInternalFrame[] frames = desktop.getAllFrames();
1362 if (frames == null || frames.length < 1)
1367 AlignmentViewport source = null, target = null;
1368 if (frames[0] instanceof AlignFrame)
1370 source = ((AlignFrame) frames[0]).getCurrentView();
1372 else if (frames[0] instanceof TreePanel)
1374 source = ((TreePanel) frames[0]).getViewPort();
1376 else if (frames[0] instanceof PCAPanel)
1378 source = ((PCAPanel) frames[0]).av;
1380 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1382 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1387 for (int i = 0; i < frames.length; i++)
1390 if (frames[i] == null)
1394 if (frames[i] instanceof AlignFrame)
1396 target = ((AlignFrame) frames[i]).getCurrentView();
1398 else if (frames[i] instanceof TreePanel)
1400 target = ((TreePanel) frames[i]).getViewPort();
1402 else if (frames[i] instanceof PCAPanel)
1404 target = ((PCAPanel) frames[i]).av;
1406 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1408 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1411 if (source == target)
1417 frames[i].setClosed(true);
1421 frames[i].setIcon(minimize);
1424 frames[i].toFront();
1428 } catch (java.beans.PropertyVetoException ex)
1442 protected void preferences_actionPerformed(ActionEvent e)
1453 public void saveState_actionPerformed(ActionEvent e)
1455 JalviewFileChooser chooser = new JalviewFileChooser(
1456 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1457 { "jvp" }, new String[]
1458 { "Jalview Project" }, "Jalview Project");
1460 chooser.setFileView(new JalviewFileView());
1461 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1463 int value = chooser.showSaveDialog(this);
1465 if (value == JalviewFileChooser.APPROVE_OPTION)
1467 final Desktop me = this;
1468 final java.io.File choice = chooser.getSelectedFile();
1469 new Thread(new Runnable()
1474 setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new String[]{choice.getName()}),
1476 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1477 choice.getParent());
1478 // TODO catch and handle errors for savestate
1479 // TODO prevent user from messing with the Desktop whilst we're saving
1482 new Jalview2XML().SaveState(choice);
1483 } catch (OutOfMemoryError oom)
1485 new OOMWarning("Whilst saving current state to "
1486 + choice.getName(), oom);
1487 } catch (Exception ex)
1490 "Problems whilst trying to save to " + choice.getName(),
1492 JOptionPane.showMessageDialog(
1494 MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new String[]{ choice.getName()}),
1495 MessageManager.getString("label.couldnt_save_project"),
1496 JOptionPane.WARNING_MESSAGE);
1498 setProgressBar(null, choice.hashCode());
1510 public void loadState_actionPerformed(ActionEvent e)
1512 JalviewFileChooser chooser = new JalviewFileChooser(
1513 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1514 { "jvp", "jar" }, new String[]
1515 { "Jalview Project", "Jalview Project (old)" },
1517 chooser.setFileView(new JalviewFileView());
1518 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1520 int value = chooser.showOpenDialog(this);
1522 if (value == JalviewFileChooser.APPROVE_OPTION)
1524 final String choice = chooser.getSelectedFile().getAbsolutePath();
1525 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1526 .getSelectedFile().getParent());
1527 new Thread(new Runnable()
1531 setProgressBar(MessageManager.formatMessage("label.loading_jalview_project", new String[]{choice}),
1535 new Jalview2XML().LoadJalviewAlign(choice);
1536 } catch (OutOfMemoryError oom)
1538 new OOMWarning("Whilst loading project from " + choice, oom);
1539 } catch (Exception ex)
1541 Cache.log.error("Problems whilst loading project from "
1543 JOptionPane.showMessageDialog(Desktop.desktop,
1544 MessageManager.formatMessage("label.error_whilst_loading_project_from", new String[]{choice}),
1545 MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE);
1547 setProgressBar(null, choice.hashCode());
1553 public void inputSequence_actionPerformed(ActionEvent e)
1555 new SequenceFetcher(this);
1558 JPanel progressPanel;
1560 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1562 public void startLoading(final String fileName)
1564 if (fileLoadingCount == 0)
1566 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage("label.loading_file", new String[]{fileName})));
1571 private JPanel addProgressPanel(String string)
1573 if (progressPanel == null)
1575 progressPanel = new JPanel(new GridLayout(1, 1));
1576 totalProgressCount = 0;
1577 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1579 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1580 JProgressBar progressBar = new JProgressBar();
1581 progressBar.setIndeterminate(true);
1583 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1585 thisprogress.add(progressBar, BorderLayout.CENTER);
1586 progressPanel.add(thisprogress);
1587 ((GridLayout) progressPanel.getLayout())
1588 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1589 ++totalProgressCount;
1590 instance.validate();
1591 return thisprogress;
1594 int totalProgressCount = 0;
1596 private void removeProgressPanel(JPanel progbar)
1598 if (progressPanel != null)
1600 synchronized (progressPanel)
1602 progressPanel.remove(progbar);
1603 GridLayout gl = (GridLayout) progressPanel.getLayout();
1604 gl.setRows(gl.getRows() - 1);
1605 if (--totalProgressCount < 1)
1607 this.getContentPane().remove(progressPanel);
1608 progressPanel = null;
1615 public void stopLoading()
1618 if (fileLoadingCount < 1)
1620 while (fileLoadingPanels.size() > 0)
1622 removeProgressPanel(fileLoadingPanels.remove(0));
1624 fileLoadingPanels.clear();
1625 fileLoadingCount = 0;
1630 public static int getViewCount(String alignmentId)
1632 AlignmentViewport[] aps = getViewports(alignmentId);
1633 return (aps == null) ? 0 : aps.length;
1638 * @param alignmentId
1639 * @return all AlignmentPanels concerning the alignmentId sequence set
1641 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1643 if (Desktop.desktop == null)
1645 // no frames created and in headless mode
1646 // TODO: verify that frames are recoverable when in headless mode
1649 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1650 AlignFrame[] frames = getAlignFrames();
1655 for (AlignFrame af : frames)
1657 for (AlignmentPanel ap : af.alignPanels)
1659 if (alignmentId.equals(ap.av.getSequenceSetId()))
1664 // for (int a = 0; a < af.alignPanels.size(); a++)
1666 // if (alignmentId.equals(af.alignPanels
1667 // .get(a).av.getSequenceSetId()))
1669 // aps.add(af.alignPanels.get(a));
1673 if (aps.size() == 0)
1677 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1682 * get all the viewports on an alignment.
1684 * @param sequenceSetId
1685 * unique alignment id
1686 * @return all viewports on the alignment bound to sequenceSetId
1688 public static AlignmentViewport[] getViewports(String sequenceSetId)
1690 Vector viewp = new Vector();
1691 if (desktop != null)
1693 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1695 for (int t = 0; t < frames.length; t++)
1697 if (frames[t] instanceof AlignFrame)
1699 AlignFrame afr = ((AlignFrame) frames[t]);
1700 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1702 if (afr.alignPanels != null)
1704 for (int a = 0; a < afr.alignPanels.size(); a++)
1706 if (sequenceSetId.equals(afr.alignPanels.get(a).av
1707 .getSequenceSetId()))
1709 viewp.addElement(afr.alignPanels.get(a).av);
1715 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1720 if (viewp.size() > 0)
1722 AlignmentViewport[] vp = new AlignmentViewport[viewp.size()];
1730 public void explodeViews(AlignFrame af)
1732 int size = af.alignPanels.size();
1738 for (int i = 0; i < size; i++)
1740 AlignmentPanel ap = af.alignPanels.get(i);
1741 AlignFrame newaf = new AlignFrame(ap);
1742 if (ap.av.explodedPosition != null
1743 && !ap.av.explodedPosition.equals(af.getBounds()))
1745 newaf.setBounds(ap.av.explodedPosition);
1748 ap.av.gatherViewsHere = false;
1750 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1751 AlignFrame.DEFAULT_HEIGHT);
1754 af.alignPanels.clear();
1755 af.closeMenuItem_actionPerformed(true);
1759 public void gatherViews(AlignFrame source)
1761 source.viewport.gatherViewsHere = true;
1762 source.viewport.explodedPosition = source.getBounds();
1763 JInternalFrame[] frames = desktop.getAllFrames();
1764 String viewId = source.viewport.getSequenceSetId();
1766 for (int t = 0; t < frames.length; t++)
1768 if (frames[t] instanceof AlignFrame && frames[t] != source)
1770 AlignFrame af = (AlignFrame) frames[t];
1771 boolean gatherThis = false;
1772 for (int a = 0; a < af.alignPanels.size(); a++)
1774 AlignmentPanel ap = af.alignPanels.get(a);
1775 if (viewId.equals(ap.av.getSequenceSetId()))
1778 ap.av.gatherViewsHere = false;
1779 ap.av.explodedPosition = af.getBounds();
1780 source.addAlignmentPanel(ap, false);
1786 af.alignPanels.clear();
1787 af.closeMenuItem_actionPerformed(true);
1794 jalview.gui.VamsasApplication v_client = null;
1796 public void vamsasImport_actionPerformed(ActionEvent e)
1798 if (v_client == null)
1800 // Load and try to start a session.
1801 JalviewFileChooser chooser = new JalviewFileChooser(
1802 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1804 chooser.setFileView(new JalviewFileView());
1805 chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
1806 chooser.setToolTipText(MessageManager
1807 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1809 int value = chooser.showOpenDialog(this);
1811 if (value == JalviewFileChooser.APPROVE_OPTION)
1813 String fle = chooser.getSelectedFile().toString();
1814 if (!vamsasImport(chooser.getSelectedFile()))
1817 .showInternalMessageDialog(
1819 MessageManager.formatMessage(
1820 "label.couldnt_import_as_vamsas_session",
1824 .getString("label.vamsas_document_import_failed"),
1825 JOptionPane.ERROR_MESSAGE);
1831 jalview.bin.Cache.log
1832 .error("Implementation error - load session from a running session is not supported.");
1837 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1840 * @return true if import was a success and a session was started.
1842 public boolean vamsasImport(URL url)
1844 // TODO: create progress bar
1845 if (v_client != null)
1848 jalview.bin.Cache.log
1849 .error("Implementation error - load session from a running session is not supported.");
1855 // copy the URL content to a temporary local file
1856 // TODO: be a bit cleverer here with nio (?!)
1857 File file = File.createTempFile("vdocfromurl", ".vdj");
1858 FileOutputStream fos = new FileOutputStream(file);
1859 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1860 byte[] buffer = new byte[2048];
1862 while ((ln = bis.read(buffer)) > -1)
1864 fos.write(buffer, 0, ln);
1868 v_client = new jalview.gui.VamsasApplication(this, file,
1869 url.toExternalForm());
1870 } catch (Exception ex)
1872 jalview.bin.Cache.log.error(
1873 "Failed to create new vamsas session from contents of URL "
1877 setupVamsasConnectedGui();
1878 v_client.initial_update(); // TODO: thread ?
1879 return v_client.inSession();
1883 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1886 * @return true if import was a success and a session was started.
1888 public boolean vamsasImport(File file)
1890 if (v_client != null)
1893 jalview.bin.Cache.log
1894 .error("Implementation error - load session from a running session is not supported.");
1898 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1902 v_client = new jalview.gui.VamsasApplication(this, file, null);
1903 } catch (Exception ex)
1905 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1907 jalview.bin.Cache.log.error(
1908 "New vamsas session from existing session file failed:", ex);
1911 setupVamsasConnectedGui();
1912 v_client.initial_update(); // TODO: thread ?
1913 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1915 return v_client.inSession();
1918 public boolean joinVamsasSession(String mysesid)
1920 if (v_client != null)
1922 throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
1924 if (mysesid == null)
1926 throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
1928 v_client = new VamsasApplication(this, mysesid);
1929 setupVamsasConnectedGui();
1930 v_client.initial_update();
1931 return (v_client.inSession());
1934 public void vamsasStart_actionPerformed(ActionEvent e)
1936 if (v_client == null)
1939 // we just start a default session for moment.
1941 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1942 * getProperty("LAST_DIRECTORY"));
1944 * chooser.setFileView(new JalviewFileView());
1945 * chooser.setDialogTitle("Load Vamsas file");
1946 * chooser.setToolTipText("Import");
1948 * int value = chooser.showOpenDialog(this);
1950 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1951 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1953 v_client = new VamsasApplication(this);
1954 setupVamsasConnectedGui();
1955 v_client.initial_update(); // TODO: thread ?
1959 // store current data in session.
1960 v_client.push_update(); // TODO: thread
1964 protected void setupVamsasConnectedGui()
1966 vamsasStart.setText(MessageManager.getString("label.session_update"));
1967 vamsasSave.setVisible(true);
1968 vamsasStop.setVisible(true);
1969 vamsasImport.setVisible(false); // Document import to existing session is
1970 // not possible for vamsas-client-1.0.
1973 protected void setupVamsasDisconnectedGui()
1975 vamsasSave.setVisible(false);
1976 vamsasStop.setVisible(false);
1977 vamsasImport.setVisible(true);
1978 vamsasStart.setText(MessageManager
1979 .getString("label.new_vamsas_session"));
1982 public void vamsasStop_actionPerformed(ActionEvent e)
1984 if (v_client != null)
1986 v_client.end_session();
1988 setupVamsasDisconnectedGui();
1992 protected void buildVamsasStMenu()
1994 if (v_client == null)
1996 String[] sess = null;
1999 sess = VamsasApplication.getSessionList();
2000 } catch (Exception e)
2002 jalview.bin.Cache.log.warn(
2003 "Problem getting current sessions list.", e);
2008 jalview.bin.Cache.log.debug("Got current sessions list: "
2009 + sess.length + " entries.");
2010 VamsasStMenu.removeAll();
2011 for (int i = 0; i < sess.length; i++)
2013 JMenuItem sessit = new JMenuItem();
2014 sessit.setText(sess[i]);
2015 sessit.setToolTipText(MessageManager.formatMessage(
2016 "label.connect_to_session", new String[]
2018 final Desktop dsktp = this;
2019 final String mysesid = sess[i];
2020 sessit.addActionListener(new ActionListener()
2023 public void actionPerformed(ActionEvent e)
2025 if (dsktp.v_client == null)
2027 Thread rthr = new Thread(new Runnable()
2032 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2033 dsktp.setupVamsasConnectedGui();
2034 dsktp.v_client.initial_update();
2042 VamsasStMenu.add(sessit);
2044 // don't show an empty menu.
2045 VamsasStMenu.setVisible(sess.length > 0);
2050 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2051 VamsasStMenu.removeAll();
2052 VamsasStMenu.setVisible(false);
2057 // Not interested in the content. Just hide ourselves.
2058 VamsasStMenu.setVisible(false);
2062 public void vamsasSave_actionPerformed(ActionEvent e)
2064 if (v_client != null)
2066 JalviewFileChooser chooser = new JalviewFileChooser(
2067 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2068 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2070 { "Vamsas Document" }, "Vamsas Document");
2072 chooser.setFileView(new JalviewFileView());
2073 chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
2075 int value = chooser.showSaveDialog(this);
2077 if (value == JalviewFileChooser.APPROVE_OPTION)
2079 java.io.File choice = chooser.getSelectedFile();
2080 JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new String[]{choice.getName()}));
2081 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2082 String warnmsg = null;
2083 String warnttl = null;
2086 v_client.vclient.storeDocument(choice);
2089 warnttl = "Serious Problem saving Vamsas Document";
2090 warnmsg = ex.toString();
2091 jalview.bin.Cache.log.error("Error Whilst saving document to "
2094 } catch (Exception ex)
2096 warnttl = "Problem saving Vamsas Document.";
2097 warnmsg = ex.toString();
2098 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2102 removeProgressPanel(progpanel);
2103 if (warnmsg != null)
2105 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2107 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2113 JPanel vamUpdate = null;
2116 * hide vamsas user gui bits when a vamsas document event is being handled.
2119 * true to hide gui, false to reveal gui
2121 public void setVamsasUpdate(boolean b)
2123 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2124 + (b ? "in progress" : "finished"));
2126 if (vamUpdate != null)
2128 this.removeProgressPanel(vamUpdate);
2132 vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
2134 vamsasStart.setVisible(!b);
2135 vamsasStop.setVisible(!b);
2136 vamsasSave.setVisible(!b);
2139 public JInternalFrame[] getAllFrames()
2141 return desktop.getAllFrames();
2145 * Checks the given url to see if it gives a response indicating that the user
2146 * should be informed of a new questionnaire.
2150 public void checkForQuestionnaire(String url)
2152 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2153 // javax.swing.SwingUtilities.invokeLater(jvq);
2154 new Thread(jvq).start();
2158 * Proxy class for JDesktopPane which optionally displays the current memory
2159 * usage and highlights the desktop area with a red bar if free memory runs
2164 public class MyDesktopPane extends JDesktopPane implements Runnable
2167 boolean showMemoryUsage = false;
2171 java.text.NumberFormat df;
2173 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2176 public MyDesktopPane(boolean showMemoryUsage)
2178 showMemoryUsage(showMemoryUsage);
2181 public void showMemoryUsage(boolean showMemoryUsage)
2183 this.showMemoryUsage = showMemoryUsage;
2184 if (showMemoryUsage)
2186 Thread worker = new Thread(this);
2191 public boolean isShowMemoryUsage()
2193 return showMemoryUsage;
2198 df = java.text.NumberFormat.getNumberInstance();
2199 df.setMaximumFractionDigits(2);
2200 runtime = Runtime.getRuntime();
2202 while (showMemoryUsage)
2206 maxMemory = runtime.maxMemory() / 1048576f;
2207 allocatedMemory = runtime.totalMemory() / 1048576f;
2208 freeMemory = runtime.freeMemory() / 1048576f;
2209 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2211 percentUsage = (totalFreeMemory / maxMemory) * 100;
2213 // if (percentUsage < 20)
2215 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2217 // instance.set.setBorder(border1);
2220 // sleep after showing usage
2222 } catch (Exception ex)
2224 ex.printStackTrace();
2229 public void paintComponent(Graphics g)
2231 if (showMemoryUsage && g != null && df != null)
2233 if (percentUsage < 20)
2235 g.setColor(Color.red);
2237 FontMetrics fm = g.getFontMetrics();
2240 g.drawString(MessageManager.formatMessage(
2241 "label.memory_stats",
2243 { df.format(totalFreeMemory), df.format(maxMemory),
2244 df.format(percentUsage) }), 10,
2245 getHeight() - fm.getHeight());
2252 * fixes stacking order after a modal dialog to ensure windows that should be
2253 * on top actually are
2255 public void relayerWindows()
2260 protected JMenuItem groovyShell;
2262 public void doGroovyCheck()
2264 if (jalview.bin.Cache.groovyJarsPresent())
2266 groovyShell = new JMenuItem();
2267 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2268 groovyShell.addActionListener(new ActionListener()
2270 public void actionPerformed(ActionEvent e)
2272 groovyShell_actionPerformed(e);
2275 toolsMenu.add(groovyShell);
2276 groovyShell.setVisible(true);
2281 * Accessor method to quickly get all the AlignmentFrames loaded.
2283 public static AlignFrame[] getAlignFrames()
2285 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2291 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2293 for (int i = frames.length - 1; i > -1; i--)
2295 if (frames[i] instanceof AlignFrame)
2297 avp.add((AlignFrame) frames[i]);
2299 else if (frames[i] instanceof SplitFrame)
2302 * Also check for a split frame containing an AlignFrame
2304 SplitFrame sf = (SplitFrame) frames[i];
2305 if (sf.getTopComponent() instanceof AlignFrame)
2307 avp.add((AlignFrame) sf.getTopComponent());
2309 if (sf.getBottomComponent() instanceof AlignFrame)
2311 avp.add((AlignFrame) sf.getBottomComponent());
2315 if (avp.size() == 0)
2319 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2324 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2328 public AppJmol[] getJmols()
2330 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2336 List<AppJmol> avp = new ArrayList<AppJmol>();
2338 for (int i = frames.length - 1; i > -1; i--)
2340 if (frames[i] instanceof AppJmol)
2342 AppJmol af = (AppJmol) frames[i];
2346 if (avp.size() == 0)
2350 AppJmol afs[] = avp.toArray(new AppJmol[avp.size()]);
2355 * Add Groovy Support to Jalview
2357 public void groovyShell_actionPerformed(ActionEvent e)
2359 // use reflection to avoid creating compilation dependency.
2360 if (!jalview.bin.Cache.groovyJarsPresent())
2362 throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
2366 Class gcClass = Desktop.class.getClassLoader().loadClass(
2367 "groovy.ui.Console");
2368 Constructor gccons = gcClass.getConstructor(null);
2369 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2371 { String.class, Object.class });
2372 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2373 Object gc = gccons.newInstance(null);
2374 setvar.invoke(gc, new Object[]
2375 { "Jalview", this });
2376 run.invoke(gc, null);
2377 } catch (Exception ex)
2379 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2381 .showInternalMessageDialog(
2384 MessageManager.getString("label.couldnt_create_groovy_shell"),
2385 MessageManager.getString("label.groovy_support_failed"),
2386 JOptionPane.ERROR_MESSAGE);
2391 * Progress bars managed by the IProgressIndicator method.
2393 private Hashtable<Long, JPanel> progressBars;
2395 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2400 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2402 public void setProgressBar(String message, long id)
2404 if (progressBars == null)
2406 progressBars = new Hashtable<Long, JPanel>();
2407 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2410 if (progressBars.get(new Long(id)) != null)
2412 JPanel progressPanel = progressBars.remove(new Long(id));
2413 if (progressBarHandlers.contains(new Long(id)))
2415 progressBarHandlers.remove(new Long(id));
2417 removeProgressPanel(progressPanel);
2421 progressBars.put(new Long(id), addProgressPanel(message));
2428 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2429 * jalview.gui.IProgressIndicatorHandler)
2431 public void registerHandler(final long id,
2432 final IProgressIndicatorHandler handler)
2434 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2436 throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
2438 progressBarHandlers.put(new Long(id), handler);
2439 final JPanel progressPanel = progressBars.get(new Long(id));
2440 if (handler.canCancel())
2442 JButton cancel = new JButton(
2443 MessageManager.getString("action.cancel"));
2444 final IProgressIndicator us = this;
2445 cancel.addActionListener(new ActionListener()
2448 public void actionPerformed(ActionEvent e)
2450 handler.cancelActivity(id);
2451 us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
2454 progressPanel.add(cancel, BorderLayout.EAST);
2460 * @return true if any progress bars are still active
2463 public boolean operationInProgress()
2465 if (progressBars != null && progressBars.size() > 0)
2473 * This will return the first AlignFrame viewing AlignViewport av. It will
2474 * break if there are more than one AlignFrames viewing a particular av.
2477 * @return alignFrame for av
2479 public static AlignFrame getAlignFrameFor(AlignmentViewport av)
2481 if (desktop != null)
2483 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2484 for (int panel = 0; aps != null && panel < aps.length; panel++)
2486 if (aps[panel] != null && aps[panel].av == av)
2488 return aps[panel].alignFrame;
2495 public VamsasApplication getVamsasApplication()
2502 * flag set if jalview GUI is being operated programmatically
2504 private boolean inBatchMode = false;
2507 * check if jalview GUI is being operated programmatically
2509 * @return inBatchMode
2511 public boolean isInBatchMode()
2517 * set flag if jalview GUI is being operated programmatically
2519 * @param inBatchMode
2521 public void setInBatchMode(boolean inBatchMode)
2523 this.inBatchMode = inBatchMode;
2526 public void startServiceDiscovery()
2528 startServiceDiscovery(false);
2531 public void startServiceDiscovery(boolean blocking)
2533 boolean alive = true;
2534 Thread t0 = null, t1 = null, t2 = null;
2535 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2538 // todo: changesupport handlers need to be transferred
2539 if (discoverer == null)
2541 discoverer = new jalview.ws.jws1.Discoverer();
2542 // register PCS handler for desktop.
2543 discoverer.addPropertyChangeListener(changeSupport);
2545 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2546 // until we phase out completely
2547 (t0 = new Thread(discoverer)).start();
2550 // ENFIN services are EOLed as of Jalview 2.8.1 release
2555 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2557 // EnfinEnvision web service menu entries are rebuild every time the
2558 // menu is shown, so no changeSupport events are needed.
2559 jalview.ws.EnfinEnvision2OneWay.getInstance();
2560 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2563 } catch (Exception e)
2566 .info("Exception when trying to launch Envision2 workflow discovery.",
2568 Cache.log.info(e.getStackTrace());
2572 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2574 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2576 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2578 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2584 // TODO: do rest service discovery
2593 } catch (Exception e)
2596 alive = (t1 != null && t1.isAlive())
2597 || (t2 != null && t2.isAlive())
2598 || (t3 != null && t3.isAlive())
2599 || (t0 != null && t0.isAlive());
2605 * called to check if the service discovery process completed successfully.
2609 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2611 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2613 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2614 .getErrorMessages();
2617 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2619 if (serviceChangedDialog == null)
2621 // only run if we aren't already displaying one of these.
2622 addDialogThread(serviceChangedDialog = new Runnable()
2628 * JalviewDialog jd =new JalviewDialog() {
2630 * @Override protected void cancelPressed() { // TODO
2631 * Auto-generated method stub
2633 * }@Override protected void okPressed() { // TODO
2634 * Auto-generated method stub
2636 * }@Override protected void raiseClosed() { // TODO
2637 * Auto-generated method stub
2639 * } }; jd.initDialogFrame(new
2640 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2641 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2642 * + " or mis-configured HTTP proxy settings.<br/>" +
2643 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2645 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2646 * ), true, true, "Web Service Configuration Problem", 450,
2649 * jd.waitForInput();
2655 "<html><table width=\"450\"><tr><td>"
2657 + "</td></tr></table>"
2658 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2659 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2660 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2661 + " Tools->Preferences dialog box to change them.</p></html>"),
2662 "Web Service Configuration Problem",
2663 JOptionPane.DEFAULT_OPTION,
2664 JOptionPane.ERROR_MESSAGE);
2665 serviceChangedDialog = null;
2674 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2681 private Runnable serviceChangedDialog = null;
2684 * start a thread to open a URL in the configured browser. Pops up a warning
2685 * dialog to the user if there is an exception when calling out to the browser
2690 public static void showUrl(final String url)
2692 showUrl(url, Desktop.instance);
2696 * Like showUrl but allows progress handler to be specified
2700 * (null) or object implementing IProgressIndicator
2702 public static void showUrl(final String url,
2703 final IProgressIndicator progress)
2705 new Thread(new Runnable()
2711 if (progress != null)
2713 progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new String[]{url}), this.hashCode());
2715 jalview.util.BrowserLauncher.openURL(url);
2716 } catch (Exception ex)
2719 .showInternalMessageDialog(
2721 MessageManager.getString("label.web_browser_not_found_unix"),
2722 MessageManager.getString("label.web_browser_not_found"),
2723 JOptionPane.WARNING_MESSAGE);
2725 ex.printStackTrace();
2727 if (progress != null)
2729 progress.setProgressBar(null, this.hashCode());
2735 public static WsParamSetManager wsparamManager = null;
2737 public static ParamManager getUserParameterStore()
2739 if (wsparamManager == null)
2741 wsparamManager = new WsParamSetManager();
2743 return wsparamManager;
2747 * static hyperlink handler proxy method for use by Jalview's internal windows
2751 public static void hyperlinkUpdate(HyperlinkEvent e)
2753 if (e.getEventType() == EventType.ACTIVATED)
2758 url = e.getURL().toString();
2759 Desktop.showUrl(url);
2760 } catch (Exception x)
2764 if (Cache.log != null)
2766 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2770 System.err.println("Couldn't handle string " + url
2774 // ignore any exceptions due to dud links.
2781 * single thread that handles display of dialogs to user.
2783 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2786 * flag indicating if dialogExecutor should try to acquire a permit
2788 private volatile boolean dialogPause = true;
2793 private java.util.concurrent.Semaphore block = new Semaphore(0);
2796 * add another dialog thread to the queue
2800 public void addDialogThread(final Runnable prompter)
2802 dialogExecutor.submit(new Runnable()
2811 } catch (InterruptedException x)
2816 if (instance == null)
2822 SwingUtilities.invokeAndWait(prompter);
2823 } catch (Exception q)
2825 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2831 public void startDialogQueue()
2833 // set the flag so we don't pause waiting for another permit and semaphore
2834 // the current task to begin
2835 dialogPause = false;
2839 protected void snapShotWindow_actionPerformed(ActionEvent e)
2843 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2844 "View of Desktop", getWidth(), getHeight(), of = new File(
2845 "Jalview_snapshot" + System.currentTimeMillis()
2846 + ".eps"), "View of desktop");
2848 paintAll(im.getGraphics());
2850 } catch (Exception q)
2852 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2855 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());