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.List;
72 import java.util.StringTokenizer;
73 import java.util.Vector;
74 import java.util.concurrent.ExecutorService;
75 import java.util.concurrent.Executors;
76 import java.util.concurrent.Semaphore;
78 import javax.swing.DefaultDesktopManager;
79 import javax.swing.DesktopManager;
80 import javax.swing.JButton;
81 import javax.swing.JComboBox;
82 import javax.swing.JComponent;
83 import javax.swing.JDesktopPane;
84 import javax.swing.JFrame;
85 import javax.swing.JInternalFrame;
86 import javax.swing.JLabel;
87 import javax.swing.JMenuItem;
88 import javax.swing.JOptionPane;
89 import javax.swing.JPanel;
90 import javax.swing.JPopupMenu;
91 import javax.swing.JProgressBar;
92 import javax.swing.SwingUtilities;
93 import javax.swing.event.HyperlinkEvent;
94 import javax.swing.event.HyperlinkEvent.EventType;
95 import javax.swing.event.MenuEvent;
96 import javax.swing.event.MenuListener;
103 * @version $Revision: 1.155 $
105 public class Desktop extends jalview.jbgui.GDesktop implements
106 DropTargetListener, ClipboardOwner, IProgressIndicator,
107 jalview.api.StructureSelectionManagerProvider
110 private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
113 * news reader - null if it was never started.
115 private BlogReader jvnews = null;
119 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
121 public void addJalviewPropertyChangeListener(
122 PropertyChangeListener listener)
124 changeSupport.addJalviewPropertyChangeListener(listener);
128 * @param propertyName
130 * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
131 * java.beans.PropertyChangeListener)
133 public void addJalviewPropertyChangeListener(String propertyName,
134 PropertyChangeListener listener)
136 changeSupport.addJalviewPropertyChangeListener(propertyName, listener);
140 * @param propertyName
142 * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
143 * java.beans.PropertyChangeListener)
145 public void removeJalviewPropertyChangeListener(String propertyName,
146 PropertyChangeListener listener)
148 changeSupport.removeJalviewPropertyChangeListener(propertyName,
152 /** Singleton Desktop instance */
153 public static Desktop instance;
155 public static MyDesktopPane desktop;
157 static int openFrameCount = 0;
159 static final int xOffset = 30;
161 static final int yOffset = 30;
163 private static final int THREE = 3;
165 public static jalview.ws.jws1.Discoverer discoverer;
167 public static Object[] jalviewClipboard;
169 public static boolean internalCopy = false;
171 static int fileLoadingCount = 0;
173 class MyDesktopManager implements DesktopManager
176 private DesktopManager delegate;
178 public MyDesktopManager(DesktopManager delegate)
180 this.delegate = delegate;
183 public void activateFrame(JInternalFrame f)
187 delegate.activateFrame(f);
188 } catch (NullPointerException npe)
190 Point p = getMousePosition();
191 instance.showPasteMenu(p.x, p.y);
195 public void beginDraggingFrame(JComponent f)
197 delegate.beginDraggingFrame(f);
200 public void beginResizingFrame(JComponent f, int direction)
202 delegate.beginResizingFrame(f, direction);
205 public void closeFrame(JInternalFrame f)
207 delegate.closeFrame(f);
210 public void deactivateFrame(JInternalFrame f)
212 delegate.deactivateFrame(f);
215 public void deiconifyFrame(JInternalFrame f)
217 delegate.deiconifyFrame(f);
220 public void dragFrame(JComponent f, int newX, int newY)
226 delegate.dragFrame(f, newX, newY);
229 public void endDraggingFrame(JComponent f)
231 delegate.endDraggingFrame(f);
234 public void endResizingFrame(JComponent f)
236 delegate.endResizingFrame(f);
239 public void iconifyFrame(JInternalFrame f)
241 delegate.iconifyFrame(f);
244 public void maximizeFrame(JInternalFrame f)
246 delegate.maximizeFrame(f);
249 public void minimizeFrame(JInternalFrame f)
251 delegate.minimizeFrame(f);
254 public void openFrame(JInternalFrame f)
256 delegate.openFrame(f);
259 public void resizeFrame(JComponent f, int newX, int newY, int newWidth,
262 Rectangle b = desktop.getBounds();
267 delegate.resizeFrame(f, newX, newY, newWidth, newHeight);
270 public void setBoundsForFrame(JComponent f, int newX, int newY,
271 int newWidth, int newHeight)
273 delegate.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
276 // All other methods, simply delegate
281 * Creates a new Desktop object.
286 * A note to implementors. It is ESSENTIAL that any activities that might
287 * block are spawned off as threads rather than waited for during this
291 doVamsasClientCheck();
293 doConfigureStructurePrefs();
294 setTitle("Jalview " + jalview.bin.Cache.getProperty("VERSION"));
295 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
296 boolean selmemusage = jalview.bin.Cache.getDefault("SHOW_MEMUSAGE",
298 boolean showjconsole = jalview.bin.Cache.getDefault(
299 "SHOW_JAVA_CONSOLE", false);
300 desktop = new MyDesktopPane(selmemusage);
301 showMemusage.setSelected(selmemusage);
302 desktop.setBackground(Color.white);
303 getContentPane().setLayout(new BorderLayout());
304 // alternate config - have scrollbars - see notes in JAL-153
305 // JScrollPane sp = new JScrollPane();
306 // sp.getViewport().setView(desktop);
307 // getContentPane().add(sp, BorderLayout.CENTER);
308 getContentPane().add(desktop, BorderLayout.CENTER);
309 desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
311 // This line prevents Windows Look&Feel resizing all new windows to maximum
312 // if previous window was maximised
313 desktop.setDesktopManager(new MyDesktopManager(
314 new DefaultDesktopManager()));
316 Rectangle dims = getLastKnownDimensions("");
323 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
324 setBounds((screenSize.width - 900) / 2,
325 (screenSize.height - 650) / 2, 900, 650);
327 jconsole = new Console(this, showjconsole);
328 // add essential build information
329 jconsole.setHeader("Jalview Version: "
330 + jalview.bin.Cache.getProperty("VERSION") + "\n"
331 + "Jalview Installation: "
332 + jalview.bin.Cache.getDefault("INSTALLATION", "unknown")
335 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown") + "\n"
336 + "Java version: " + System.getProperty("java.version") + "\n"
337 + System.getProperty("os.arch") + " "
338 + System.getProperty("os.name") + " "
339 + System.getProperty("os.version"));
341 showConsole(showjconsole);
343 showNews.setVisible(false);
345 this.addWindowListener(new WindowAdapter()
347 public void windowClosing(WindowEvent evt)
354 this.addMouseListener(ma = new MouseAdapter()
356 public void mousePressed(MouseEvent evt)
358 if (SwingUtilities.isRightMouseButton(evt))
360 showPasteMenu(evt.getX(), evt.getY());
364 desktop.addMouseListener(ma);
366 this.addFocusListener(new FocusListener()
370 public void focusLost(FocusEvent e)
372 // TODO Auto-generated method stub
377 public void focusGained(FocusEvent e)
379 Cache.log.debug("Relaying windows after focus gain");
380 // make sure that we sort windows properly after we gain focus
381 instance.relayerWindows();
384 this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
385 // Spawn a thread that shows the splashscreen
386 SwingUtilities.invokeLater(new Runnable()
395 // Thread off a new instance of the file chooser - this reduces the time it
396 // takes to open it later on.
397 new Thread(new Runnable()
401 Cache.log.debug("Filechooser init thread started.");
402 JalviewFileChooser chooser = new JalviewFileChooser(
403 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
404 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
405 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
406 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
407 Cache.log.debug("Filechooser init thread finished.");
410 // Add the service change listener
411 changeSupport.addJalviewPropertyChangeListener("services",
412 new PropertyChangeListener()
416 public void propertyChange(PropertyChangeEvent evt)
418 Cache.log.debug("Firing service changed event for "
419 + evt.getNewValue());
420 JalviewServicesChanged(evt);
426 public void doConfigureStructurePrefs()
428 // configure services
429 StructureSelectionManager ssm = StructureSelectionManager
430 .getStructureSelectionManager(this);
431 if (jalview.bin.Cache.getDefault(Preferences.ADD_SS_ANN, true))
433 ssm.setAddTempFacAnnot(jalview.bin.Cache.getDefault(
434 Preferences.ADD_TEMPFACT_ANN, true));
435 ssm.setProcessSecondaryStructure(jalview.bin.Cache.getDefault(Preferences.STRUCT_FROM_PDB, true));
436 ssm.setSecStructServices(jalview.bin.Cache.getDefault(Preferences.USE_RNAVIEW,
441 ssm.setAddTempFacAnnot(false);
442 ssm.setProcessSecondaryStructure(false);
443 ssm.setSecStructServices(false);
447 public void checkForNews()
449 final Desktop me = this;
450 // Thread off the news reader, in case there are connection problems.
451 addDialogThread(new Runnable()
456 Cache.log.debug("Starting news thread.");
458 jvnews = new BlogReader(me);
459 showNews.setVisible(true);
460 Cache.log.debug("Completed news thread.");
465 protected void showNews_actionPerformed(ActionEvent e)
467 showNews(showNews.isSelected());
470 void showNews(boolean visible)
473 Cache.log.debug((visible ? "Showing" : "Hiding") + " news.");
474 showNews.setSelected(visible);
475 if (visible && !jvnews.isVisible())
477 new Thread(new Runnable()
482 long instance = System.currentTimeMillis();
483 Desktop.instance.setProgressBar(MessageManager.getString("status.refreshing_news"), instance);
484 jvnews.refreshNews();
485 Desktop.instance.setProgressBar(null, instance);
494 * recover the last known dimensions for a jalview window
497 * - empty string is desktop, all other windows have unique prefix
498 * @return null or last known dimensions scaled to current geometry (if last
499 * window geom was known)
501 Rectangle getLastKnownDimensions(String windowName)
503 // TODO: lock aspect ratio for scaling desktop Bug #0058199
504 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
505 String x = jalview.bin.Cache.getProperty(windowName + "SCREEN_X");
506 String y = jalview.bin.Cache.getProperty(windowName + "SCREEN_Y");
507 String width = jalview.bin.Cache.getProperty(windowName
509 String height = jalview.bin.Cache.getProperty(windowName
511 if ((x != null) && (y != null) && (width != null) && (height != null))
513 int ix = Integer.parseInt(x), iy = Integer.parseInt(y), iw = Integer
514 .parseInt(width), ih = Integer.parseInt(height);
515 if (jalview.bin.Cache.getProperty("SCREENGEOMETRY_WIDTH") != null)
517 // attempt #1 - try to cope with change in screen geometry - this
518 // version doesn't preserve original jv aspect ratio.
519 // take ratio of current screen size vs original screen size.
520 double sw = ((1f * screenSize.width) / (1f * Integer
521 .parseInt(jalview.bin.Cache
522 .getProperty("SCREENGEOMETRY_WIDTH"))));
523 double sh = ((1f * screenSize.height) / (1f * Integer
524 .parseInt(jalview.bin.Cache
525 .getProperty("SCREENGEOMETRY_HEIGHT"))));
526 // rescale the bounds depending upon the current screen geometry.
527 ix = (int) (ix * sw);
528 iw = (int) (iw * sw);
529 iy = (int) (iy * sh);
530 ih = (int) (ih * sh);
531 while (ix >= screenSize.width)
533 jalview.bin.Cache.log
534 .debug("Window geometry location recall error: shifting horizontal to within screenbounds.");
535 ix -= screenSize.width;
537 while (iy >= screenSize.height)
539 jalview.bin.Cache.log
540 .debug("Window geometry location recall error: shifting vertical to within screenbounds.");
541 iy -= screenSize.height;
543 jalview.bin.Cache.log.debug("Got last known dimensions for "
544 + windowName + ": x:" + ix + " y:" + iy + " width:" + iw
547 // return dimensions for new instance
548 return new Rectangle(ix, iy, iw, ih);
553 private void doVamsasClientCheck()
555 if (jalview.bin.Cache.vamsasJarsPresent())
557 setupVamsasDisconnectedGui();
558 VamsasMenu.setVisible(true);
559 final Desktop us = this;
560 VamsasMenu.addMenuListener(new MenuListener()
562 // this listener remembers when the menu was first selected, and
563 // doesn't rebuild the session list until it has been cleared and
565 boolean refresh = true;
567 public void menuCanceled(MenuEvent e)
572 public void menuDeselected(MenuEvent e)
577 public void menuSelected(MenuEvent e)
581 us.buildVamsasStMenu();
586 vamsasStart.setVisible(true);
590 void showPasteMenu(int x, int y)
592 JPopupMenu popup = new JPopupMenu();
593 JMenuItem item = new JMenuItem(
594 MessageManager.getString("label.paste_new_window"));
595 item.addActionListener(new ActionListener()
597 public void actionPerformed(ActionEvent evt)
604 popup.show(this, x, y);
611 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
612 Transferable contents = c.getContents(this);
614 if (contents != null)
616 String file = (String) contents
617 .getTransferData(DataFlavor.stringFlavor);
619 String format = new IdentifyFile().Identify(file,
620 FormatAdapter.PASTE);
622 new FileLoader().LoadFile(file, FormatAdapter.PASTE, format);
625 } catch (Exception ex)
628 .println("Unable to paste alignment from system clipboard:\n"
634 * Adds and opens the given frame to the desktop
645 public static synchronized void addInternalFrame(
646 final JInternalFrame frame, String title, int w, int h)
648 addInternalFrame(frame, title, true, w, h, true);
653 * Add an internal frame to the Jalview desktop
660 * When true, display frame immediately, otherwise, caller must call
661 * setVisible themselves.
667 public static synchronized void addInternalFrame(
668 final JInternalFrame frame, String title, boolean makeVisible,
671 addInternalFrame(frame, title, makeVisible, w, h, true);
675 * Add an internal frame to the Jalview desktop and make it visible
688 public static synchronized void addInternalFrame(
689 final JInternalFrame frame, String title, int w, int h,
692 addInternalFrame(frame, title, true, w, h, resizable);
696 * Add an internal frame to the Jalview desktop
703 * When true, display frame immediately, otherwise, caller must call
704 * setVisible themselves.
712 public static synchronized void addInternalFrame(
713 final JInternalFrame frame, String title, boolean makeVisible,
714 int w, int h, boolean resizable)
717 // TODO: allow callers to determine X and Y position of frame (eg. via
719 // TODO: consider fixing method to update entries in the window submenu with
720 // the current window title
722 frame.setTitle(title);
723 if (frame.getWidth() < 1 || frame.getHeight() < 1)
727 // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
728 // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
729 // IF JALVIEW IS RUNNING HEADLESS
730 // ///////////////////////////////////////////////
732 || (System.getProperty("java.awt.headless") != null && System
733 .getProperty("java.awt.headless").equals("true")))
740 frame.setVisible(makeVisible);
741 frame.setClosable(true);
742 frame.setResizable(resizable);
743 frame.setMaximizable(resizable);
744 frame.setIconifiable(resizable);
745 frame.setFrameIcon(null);
747 if (frame.getX() < 1 && frame.getY() < 1)
749 frame.setLocation(xOffset * openFrameCount, yOffset
750 * ((openFrameCount - 1) % 10) + yOffset);
753 final JMenuItem menuItem = new JMenuItem(title);
754 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
756 public void internalFrameActivated(
757 javax.swing.event.InternalFrameEvent evt)
759 JInternalFrame itf = desktop.getSelectedFrame();
767 public void internalFrameClosed(
768 javax.swing.event.InternalFrameEvent evt)
770 PaintRefresher.RemoveComponent(frame);
772 windowMenu.remove(menuItem);
773 JInternalFrame itf = desktop.getSelectedFrame();
782 menuItem.addActionListener(new ActionListener()
784 public void actionPerformed(ActionEvent e)
788 frame.setSelected(true);
789 frame.setIcon(false);
790 } catch (java.beans.PropertyVetoException ex)
796 menuItem.addMouseListener(new MouseListener()
800 public void mouseReleased(MouseEvent e)
805 public void mousePressed(MouseEvent e)
810 public void mouseExited(MouseEvent e)
814 frame.setSelected(false);
815 } catch (PropertyVetoException e1)
821 public void mouseEntered(MouseEvent e)
825 frame.setSelected(true);
826 } catch (PropertyVetoException e1)
832 public void mouseClicked(MouseEvent e)
838 windowMenu.add(menuItem);
844 frame.setSelected(true);
845 frame.requestFocus();
846 } catch (java.beans.PropertyVetoException ve)
848 } catch (java.lang.ClassCastException cex)
851 .warn("Squashed a possible GUI implementation error. If you can recreate this, please look at http://issues.jalview.org/browse/JAL-869",
856 public void lostOwnership(Clipboard clipboard, Transferable contents)
860 Desktop.jalviewClipboard = null;
863 internalCopy = false;
866 public void dragEnter(DropTargetDragEvent evt)
870 public void dragExit(DropTargetEvent evt)
874 public void dragOver(DropTargetDragEvent evt)
878 public void dropActionChanged(DropTargetDragEvent evt)
888 public void drop(DropTargetDropEvent evt)
890 boolean success = true;
891 Transferable t = evt.getTransferable();
892 java.util.List files = null;
893 java.util.List protocols = null;
897 DataFlavor uriListFlavor = new DataFlavor(
898 "text/uri-list;class=java.lang.String");
899 if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
901 // Works on Windows and MacOSX
902 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
903 files = (java.util.List) t
904 .getTransferData(DataFlavor.javaFileListFlavor);
906 else if (t.isDataFlavorSupported(uriListFlavor))
908 // This is used by Unix drag system
909 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
910 String data = (String) t.getTransferData(uriListFlavor);
911 files = new java.util.ArrayList(1);
912 protocols = new java.util.ArrayList(1);
913 for (java.util.StringTokenizer st = new java.util.StringTokenizer(
914 data, "\r\n"); st.hasMoreTokens();)
916 String s = st.nextToken();
917 if (s.startsWith("#"))
919 // the line is a comment (as per the RFC 2483)
922 java.net.URI uri = new java.net.URI(s);
923 if (uri.getScheme().toLowerCase().startsWith("http"))
925 protocols.add(FormatAdapter.URL);
926 files.add(uri.toString());
930 // otherwise preserve old behaviour: catch all for file objects
931 java.io.File file = new java.io.File(uri);
932 protocols.add(FormatAdapter.FILE);
933 files.add(file.toString());
937 } catch (Exception e)
946 for (int i = 0; i < files.size(); i++)
948 String file = files.get(i).toString();
949 String protocol = (protocols == null) ? FormatAdapter.FILE
950 : (String) protocols.get(i);
951 String format = null;
953 if (file.endsWith(".jar"))
960 format = new IdentifyFile().Identify(file, protocol);
963 new FileLoader().LoadFile(file, protocol, format);
966 } catch (Exception ex)
971 evt.dropComplete(success); // need this to ensure input focus is properly
972 // transfered to any new windows created
981 public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
983 JalviewFileChooser chooser = new JalviewFileChooser(
984 jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
985 jalview.io.AppletFormatAdapter.READABLE_EXTENSIONS,
986 jalview.io.AppletFormatAdapter.READABLE_FNAMES,
987 jalview.bin.Cache.getProperty("DEFAULT_FILE_FORMAT"));
989 chooser.setFileView(new JalviewFileView());
990 chooser.setDialogTitle(MessageManager
991 .getString("label.open_local_file"));
992 chooser.setToolTipText(MessageManager.getString("action.open"));
994 int value = chooser.showOpenDialog(this);
996 if (value == JalviewFileChooser.APPROVE_OPTION)
998 String choice = chooser.getSelectedFile().getPath();
999 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1000 .getSelectedFile().getParent());
1002 String format = null;
1003 if (chooser.getSelectedFormat() != null
1004 && chooser.getSelectedFormat().equals("Jalview"))
1010 format = new IdentifyFile().Identify(choice, FormatAdapter.FILE);
1013 if (viewport != null)
1015 new FileLoader().LoadFile(viewport, choice, FormatAdapter.FILE,
1020 new FileLoader().LoadFile(choice, FormatAdapter.FILE, format);
1031 public void inputURLMenuItem_actionPerformed(AlignViewport viewport)
1033 // This construct allows us to have a wider textfield
1035 JLabel label = new JLabel(
1036 MessageManager.getString("label.input_file_url"));
1037 final JComboBox history = new JComboBox();
1039 JPanel panel = new JPanel(new GridLayout(2, 1));
1042 history.setPreferredSize(new Dimension(400, 20));
1043 history.setEditable(true);
1044 history.addItem("http://www.");
1046 String historyItems = jalview.bin.Cache.getProperty("RECENT_URL");
1050 if (historyItems != null)
1052 st = new StringTokenizer(historyItems, "\t");
1054 while (st.hasMoreTokens())
1056 history.addItem(st.nextElement());
1060 int reply = JOptionPane.showInternalConfirmDialog(desktop, panel,
1061 MessageManager.getString("label.input_alignment_from_url"),
1062 JOptionPane.OK_CANCEL_OPTION);
1064 if (reply != JOptionPane.OK_OPTION)
1069 String url = history.getSelectedItem().toString();
1071 if (url.toLowerCase().endsWith(".jar"))
1073 if (viewport != null)
1075 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL,
1080 new FileLoader().LoadFile(url, FormatAdapter.URL, "Jalview");
1085 String format = new IdentifyFile().Identify(url, FormatAdapter.URL);
1087 if (format.equals("URL NOT FOUND"))
1089 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1090 MessageManager.formatMessage("label.couldnt_locate", new String[]{url}), MessageManager.getString("label.url_not_found"),
1091 JOptionPane.WARNING_MESSAGE);
1096 if (viewport != null)
1098 new FileLoader().LoadFile(viewport, url, FormatAdapter.URL, format);
1102 new FileLoader().LoadFile(url, FormatAdapter.URL, format);
1113 public void inputTextboxMenuItem_actionPerformed(AlignViewport viewport)
1115 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1116 cap.setForInput(viewport);
1117 Desktop.addInternalFrame(cap,
1118 MessageManager.getString("label.cut_paste_alignmen_file"),
1127 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1129 .setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
1130 jalview.bin.Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height
1132 storeLastKnownDimensions("", new Rectangle(getBounds().x,
1133 getBounds().y, getWidth(), getHeight()));
1135 if (jconsole != null)
1137 storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
1138 jconsole.stopConsole();
1142 storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
1145 if (dialogExecutor != null)
1147 dialogExecutor.shutdownNow();
1153 private void storeLastKnownDimensions(String string, Rectangle jc)
1155 jalview.bin.Cache.log.debug("Storing last known dimensions for "
1156 + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
1157 + " height:" + jc.height);
1159 jalview.bin.Cache.setProperty(string + "SCREEN_X", jc.x + "");
1160 jalview.bin.Cache.setProperty(string + "SCREEN_Y", jc.y + "");
1161 jalview.bin.Cache.setProperty(string + "SCREEN_WIDTH", jc.width + "");
1162 jalview.bin.Cache.setProperty(string + "SCREEN_HEIGHT", jc.height + "");
1171 public void aboutMenuItem_actionPerformed(ActionEvent e)
1173 // StringBuffer message = getAboutMessage(false);
1174 // JOptionPane.showInternalMessageDialog(Desktop.desktop,
1176 // message.toString(), "About Jalview", JOptionPane.INFORMATION_MESSAGE);
1177 new Thread(new Runnable()
1181 new SplashScreen(true);
1186 public StringBuffer getAboutMessage(boolean shortv)
1188 StringBuffer message = new StringBuffer();
1189 message.append("<html>");
1192 message.append("<h1><strong>Version: "
1193 + jalview.bin.Cache.getProperty("VERSION")
1194 + "</strong></h1>");
1195 message.append("<strong>Last Updated: <em>"
1196 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown")
1197 + "</em></strong>");
1203 message.append("<strong>Version "
1204 + jalview.bin.Cache.getProperty("VERSION")
1205 + "; last updated: "
1206 + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
1209 if (jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking").equals(
1212 message.append("<br>...Checking latest version...</br>");
1214 else if (!jalview.bin.Cache.getDefault("LATEST_VERSION", "Checking")
1215 .equals(jalview.bin.Cache.getProperty("VERSION")))
1217 boolean red = false;
1218 if (jalview.bin.Cache.getProperty("VERSION").toLowerCase()
1219 .indexOf("automated build") == -1)
1222 // Displayed when code version and jnlp version do not match and code
1223 // version is not a development build
1224 message.append("<div style=\"color: #FF0000;font-style: bold;\">");
1227 message.append("<br>!! Version "
1228 + jalview.bin.Cache.getDefault("LATEST_VERSION",
1230 + " is available for download from "
1231 + jalview.bin.Cache.getDefault("www.jalview.org",
1232 "http://www.jalview.org") + " !!");
1235 message.append("</div>");
1238 message.append("<br>Authors: "
1242 "The Jalview Authors (See AUTHORS file for current list)")
1243 + "<br><br>Development managed by The Barton Group, University of Dundee, Scotland, UK.<br>"
1244 + "<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"
1245 + "<br><br>If you use Jalview, please cite:"
1246 + "<br>Waterhouse, A.M., Procter, J.B., Martin, D.M.A, Clamp, M. and Barton, G. J. (2009)"
1247 + "<br>Jalview Version 2 - a multiple sequence alignment editor and analysis workbench"
1248 + "<br>Bioinformatics doi: 10.1093/bioinformatics/btp033"
1259 public void documentationMenuItem_actionPerformed(ActionEvent e)
1263 Help.showHelpWindow();
1264 } catch (Exception ex)
1269 public void closeAll_actionPerformed(ActionEvent e)
1271 JInternalFrame[] frames = desktop.getAllFrames();
1272 for (int i = 0; i < frames.length; i++)
1276 frames[i].setClosed(true);
1277 } catch (java.beans.PropertyVetoException ex)
1281 System.out.println("ALL CLOSED");
1282 if (v_client != null)
1284 // TODO clear binding to vamsas document objects on close_all
1289 public void raiseRelated_actionPerformed(ActionEvent e)
1291 reorderAssociatedWindows(false, false);
1294 public void minimizeAssociated_actionPerformed(ActionEvent e)
1296 reorderAssociatedWindows(true, false);
1299 void closeAssociatedWindows()
1301 reorderAssociatedWindows(false, true);
1307 * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
1310 protected void garbageCollect_actionPerformed(ActionEvent e)
1312 // We simply collect the garbage
1313 jalview.bin.Cache.log.debug("Collecting garbage...");
1315 jalview.bin.Cache.log.debug("Finished garbage collection.");
1322 * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
1325 protected void showMemusage_actionPerformed(ActionEvent e)
1327 desktop.showMemoryUsage(showMemusage.isSelected());
1334 * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
1337 protected void showConsole_actionPerformed(ActionEvent e)
1339 showConsole(showConsole.isSelected());
1342 Console jconsole = null;
1345 * control whether the java console is visible or not
1349 void showConsole(boolean selected)
1351 showConsole.setSelected(selected);
1352 // TODO: decide if we should update properties file
1353 Cache.setProperty("SHOW_JAVA_CONSOLE", Boolean.valueOf(selected)
1355 jconsole.setVisible(selected);
1358 void reorderAssociatedWindows(boolean minimize, boolean close)
1360 JInternalFrame[] frames = desktop.getAllFrames();
1361 if (frames == null || frames.length < 1)
1366 AlignViewport source = null, target = null;
1367 if (frames[0] instanceof AlignFrame)
1369 source = ((AlignFrame) frames[0]).getCurrentView();
1371 else if (frames[0] instanceof TreePanel)
1373 source = ((TreePanel) frames[0]).getViewPort();
1375 else if (frames[0] instanceof PCAPanel)
1377 source = ((PCAPanel) frames[0]).av;
1379 else if (frames[0].getContentPane() instanceof PairwiseAlignPanel)
1381 source = ((PairwiseAlignPanel) frames[0].getContentPane()).av;
1386 for (int i = 0; i < frames.length; i++)
1389 if (frames[i] == null)
1393 if (frames[i] instanceof AlignFrame)
1395 target = ((AlignFrame) frames[i]).getCurrentView();
1397 else if (frames[i] instanceof TreePanel)
1399 target = ((TreePanel) frames[i]).getViewPort();
1401 else if (frames[i] instanceof PCAPanel)
1403 target = ((PCAPanel) frames[i]).av;
1405 else if (frames[i].getContentPane() instanceof PairwiseAlignPanel)
1407 target = ((PairwiseAlignPanel) frames[i].getContentPane()).av;
1410 if (source == target)
1416 frames[i].setClosed(true);
1420 frames[i].setIcon(minimize);
1423 frames[i].toFront();
1427 } catch (java.beans.PropertyVetoException ex)
1441 protected void preferences_actionPerformed(ActionEvent e)
1452 public void saveState_actionPerformed(ActionEvent e)
1454 JalviewFileChooser chooser = new JalviewFileChooser(
1455 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1456 { "jvp" }, new String[]
1457 { "Jalview Project" }, "Jalview Project");
1459 chooser.setFileView(new JalviewFileView());
1460 chooser.setDialogTitle(MessageManager.getString("label.save_state"));
1462 int value = chooser.showSaveDialog(this);
1464 if (value == JalviewFileChooser.APPROVE_OPTION)
1466 final Desktop me = this;
1467 final java.io.File choice = chooser.getSelectedFile();
1468 new Thread(new Runnable()
1473 setProgressBar(MessageManager.formatMessage("label.saving_jalview_project", new String[]{choice.getName()}),
1475 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
1476 choice.getParent());
1477 // TODO catch and handle errors for savestate
1478 // TODO prevent user from messing with the Desktop whilst we're saving
1481 new Jalview2XML().SaveState(choice);
1482 } catch (OutOfMemoryError oom)
1484 new OOMWarning("Whilst saving current state to "
1485 + choice.getName(), oom);
1486 } catch (Exception ex)
1489 "Problems whilst trying to save to " + choice.getName(),
1491 JOptionPane.showMessageDialog(
1493 MessageManager.formatMessage("label.error_whilst_saving_current_state_to", new String[]{ choice.getName()}),
1494 MessageManager.getString("label.couldnt_save_project"),
1495 JOptionPane.WARNING_MESSAGE);
1497 setProgressBar(null, choice.hashCode());
1509 public void loadState_actionPerformed(ActionEvent e)
1511 JalviewFileChooser chooser = new JalviewFileChooser(
1512 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
1513 { "jvp", "jar" }, new String[]
1514 { "Jalview Project", "Jalview Project (old)" },
1516 chooser.setFileView(new JalviewFileView());
1517 chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
1519 int value = chooser.showOpenDialog(this);
1521 if (value == JalviewFileChooser.APPROVE_OPTION)
1523 final String choice = chooser.getSelectedFile().getAbsolutePath();
1524 jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
1525 .getSelectedFile().getParent());
1526 new Thread(new Runnable()
1530 setProgressBar(MessageManager.formatMessage("label.loading_jalview_project", new String[]{choice}),
1534 new Jalview2XML().LoadJalviewAlign(choice);
1535 } catch (OutOfMemoryError oom)
1537 new OOMWarning("Whilst loading project from " + choice, oom);
1538 } catch (Exception ex)
1540 Cache.log.error("Problems whilst loading project from "
1542 JOptionPane.showMessageDialog(Desktop.desktop,
1543 MessageManager.formatMessage("label.error_whilst_loading_project_from", new String[]{choice}),
1544 MessageManager.getString("label.couldnt_load_project"), JOptionPane.WARNING_MESSAGE);
1546 setProgressBar(null, choice.hashCode());
1552 public void inputSequence_actionPerformed(ActionEvent e)
1554 new SequenceFetcher(this);
1557 JPanel progressPanel;
1559 ArrayList<JPanel> fileLoadingPanels = new ArrayList<JPanel>();
1561 public void startLoading(final String fileName)
1563 if (fileLoadingCount == 0)
1565 fileLoadingPanels.add(addProgressPanel(MessageManager.formatMessage("label.loading_file", new String[]{fileName})));
1570 private JPanel addProgressPanel(String string)
1572 if (progressPanel == null)
1574 progressPanel = new JPanel(new GridLayout(1, 1));
1575 totalProgressCount = 0;
1576 instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
1578 JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
1579 JProgressBar progressBar = new JProgressBar();
1580 progressBar.setIndeterminate(true);
1582 thisprogress.add(new JLabel(string), BorderLayout.WEST);
1584 thisprogress.add(progressBar, BorderLayout.CENTER);
1585 progressPanel.add(thisprogress);
1586 ((GridLayout) progressPanel.getLayout())
1587 .setRows(((GridLayout) progressPanel.getLayout()).getRows() + 1);
1588 ++totalProgressCount;
1589 instance.validate();
1590 return thisprogress;
1593 int totalProgressCount = 0;
1595 private void removeProgressPanel(JPanel progbar)
1597 if (progressPanel != null)
1599 synchronized (progressPanel)
1601 progressPanel.remove(progbar);
1602 GridLayout gl = (GridLayout) progressPanel.getLayout();
1603 gl.setRows(gl.getRows() - 1);
1604 if (--totalProgressCount < 1)
1606 this.getContentPane().remove(progressPanel);
1607 progressPanel = null;
1614 public void stopLoading()
1617 if (fileLoadingCount < 1)
1619 while (fileLoadingPanels.size() > 0)
1621 removeProgressPanel(fileLoadingPanels.remove(0));
1623 fileLoadingPanels.clear();
1624 fileLoadingCount = 0;
1629 public static int getViewCount(String alignmentId)
1631 AlignViewport[] aps = getViewports(alignmentId);
1632 return (aps == null) ? 0 : aps.length;
1637 * @param alignmentId
1638 * @return all AlignmentPanels concerning the alignmentId sequence set
1640 public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
1642 if (Desktop.desktop == null)
1644 // no frames created and in headless mode
1645 // TODO: verify that frames are recoverable when in headless mode
1648 List<AlignmentPanel> aps = new ArrayList<AlignmentPanel>();
1649 AlignFrame[] frames = getAlignFrames();
1654 for (AlignFrame af : frames)
1656 for (AlignmentPanel ap : af.alignPanels)
1658 if (alignmentId.equals(ap.av.getSequenceSetId()))
1663 // for (int a = 0; a < af.alignPanels.size(); a++)
1665 // if (alignmentId.equals(af.alignPanels
1666 // .get(a).av.getSequenceSetId()))
1668 // aps.add(af.alignPanels.get(a));
1672 if (aps.size() == 0)
1676 AlignmentPanel[] vap = aps.toArray(new AlignmentPanel[aps.size()]);
1681 * get all the viewports on an alignment.
1683 * @param sequenceSetId
1684 * unique alignment id
1685 * @return all viewports on the alignment bound to sequenceSetId
1687 public static AlignViewport[] getViewports(String sequenceSetId)
1689 Vector viewp = new Vector();
1690 if (desktop != null)
1692 javax.swing.JInternalFrame[] frames = instance.getAllFrames();
1694 for (int t = 0; t < frames.length; t++)
1696 if (frames[t] instanceof AlignFrame)
1698 AlignFrame afr = ((AlignFrame) frames[t]);
1699 if (afr.getViewport().getSequenceSetId().equals(sequenceSetId))
1701 if (afr.alignPanels != null)
1703 for (int a = 0; a < afr.alignPanels.size(); a++)
1705 if (sequenceSetId.equals(afr.alignPanels.get(a).av
1706 .getSequenceSetId()))
1708 viewp.addElement(afr.alignPanels.get(a).av);
1714 viewp.addElement(((AlignFrame) frames[t]).getViewport());
1719 if (viewp.size() > 0)
1721 AlignViewport[] vp = new AlignViewport[viewp.size()];
1729 public void explodeViews(AlignFrame af)
1731 int size = af.alignPanels.size();
1737 for (int i = 0; i < size; i++)
1739 AlignmentPanel ap = af.alignPanels.get(i);
1740 AlignFrame newaf = new AlignFrame(ap);
1741 if (ap.av.explodedPosition != null
1742 && !ap.av.explodedPosition.equals(af.getBounds()))
1744 newaf.setBounds(ap.av.explodedPosition);
1747 ap.av.gatherViewsHere = false;
1749 addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
1750 AlignFrame.DEFAULT_HEIGHT);
1753 af.alignPanels.clear();
1754 af.closeMenuItem_actionPerformed(true);
1758 public void gatherViews(AlignFrame source)
1760 source.viewport.gatherViewsHere = true;
1761 source.viewport.explodedPosition = source.getBounds();
1762 JInternalFrame[] frames = desktop.getAllFrames();
1763 String viewId = source.viewport.getSequenceSetId();
1765 for (int t = 0; t < frames.length; t++)
1767 if (frames[t] instanceof AlignFrame && frames[t] != source)
1769 AlignFrame af = (AlignFrame) frames[t];
1770 boolean gatherThis = false;
1771 for (int a = 0; a < af.alignPanels.size(); a++)
1773 AlignmentPanel ap = af.alignPanels.get(a);
1774 if (viewId.equals(ap.av.getSequenceSetId()))
1777 ap.av.gatherViewsHere = false;
1778 ap.av.explodedPosition = af.getBounds();
1779 source.addAlignmentPanel(ap, false);
1785 af.alignPanels.clear();
1786 af.closeMenuItem_actionPerformed(true);
1793 jalview.gui.VamsasApplication v_client = null;
1795 public void vamsasImport_actionPerformed(ActionEvent e)
1797 if (v_client == null)
1799 // Load and try to start a session.
1800 JalviewFileChooser chooser = new JalviewFileChooser(
1801 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1803 chooser.setFileView(new JalviewFileView());
1804 chooser.setDialogTitle(MessageManager.getString("label.open_saved_vamsas_session"));
1805 chooser.setToolTipText(MessageManager
1806 .getString("label.select_vamsas_session_opened_as_new_vamsas_session"));
1808 int value = chooser.showOpenDialog(this);
1810 if (value == JalviewFileChooser.APPROVE_OPTION)
1812 String fle = chooser.getSelectedFile().toString();
1813 if (!vamsasImport(chooser.getSelectedFile()))
1816 .showInternalMessageDialog(
1818 MessageManager.formatMessage(
1819 "label.couldnt_import_as_vamsas_session",
1823 .getString("label.vamsas_document_import_failed"),
1824 JOptionPane.ERROR_MESSAGE);
1830 jalview.bin.Cache.log
1831 .error("Implementation error - load session from a running session is not supported.");
1836 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1839 * @return true if import was a success and a session was started.
1841 public boolean vamsasImport(URL url)
1843 // TODO: create progress bar
1844 if (v_client != null)
1847 jalview.bin.Cache.log
1848 .error("Implementation error - load session from a running session is not supported.");
1854 // copy the URL content to a temporary local file
1855 // TODO: be a bit cleverer here with nio (?!)
1856 File file = File.createTempFile("vdocfromurl", ".vdj");
1857 FileOutputStream fos = new FileOutputStream(file);
1858 BufferedInputStream bis = new BufferedInputStream(url.openStream());
1859 byte[] buffer = new byte[2048];
1861 while ((ln = bis.read(buffer)) > -1)
1863 fos.write(buffer, 0, ln);
1867 v_client = new jalview.gui.VamsasApplication(this, file,
1868 url.toExternalForm());
1869 } catch (Exception ex)
1871 jalview.bin.Cache.log.error(
1872 "Failed to create new vamsas session from contents of URL "
1876 setupVamsasConnectedGui();
1877 v_client.initial_update(); // TODO: thread ?
1878 return v_client.inSession();
1882 * import file into a new vamsas session (uses jalview.gui.VamsasApplication)
1885 * @return true if import was a success and a session was started.
1887 public boolean vamsasImport(File file)
1889 if (v_client != null)
1892 jalview.bin.Cache.log
1893 .error("Implementation error - load session from a running session is not supported.");
1897 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1901 v_client = new jalview.gui.VamsasApplication(this, file, null);
1902 } catch (Exception ex)
1904 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1906 jalview.bin.Cache.log.error(
1907 "New vamsas session from existing session file failed:", ex);
1910 setupVamsasConnectedGui();
1911 v_client.initial_update(); // TODO: thread ?
1912 setProgressBar(MessageManager.formatMessage("status.importing_vamsas_session_from", new String[]{file.getName()}),
1914 return v_client.inSession();
1917 public boolean joinVamsasSession(String mysesid)
1919 if (v_client != null)
1921 throw new Error(MessageManager.getString("error.try_join_vamsas_session_another"));
1923 if (mysesid == null)
1925 throw new Error(MessageManager.getString("error.invalid_vamsas_session_id"));
1927 v_client = new VamsasApplication(this, mysesid);
1928 setupVamsasConnectedGui();
1929 v_client.initial_update();
1930 return (v_client.inSession());
1933 public void vamsasStart_actionPerformed(ActionEvent e)
1935 if (v_client == null)
1938 // we just start a default session for moment.
1940 * JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.
1941 * getProperty("LAST_DIRECTORY"));
1943 * chooser.setFileView(new JalviewFileView());
1944 * chooser.setDialogTitle("Load Vamsas file");
1945 * chooser.setToolTipText("Import");
1947 * int value = chooser.showOpenDialog(this);
1949 * if (value == JalviewFileChooser.APPROVE_OPTION) { v_client = new
1950 * jalview.gui.VamsasApplication(this, chooser.getSelectedFile());
1952 v_client = new VamsasApplication(this);
1953 setupVamsasConnectedGui();
1954 v_client.initial_update(); // TODO: thread ?
1958 // store current data in session.
1959 v_client.push_update(); // TODO: thread
1963 protected void setupVamsasConnectedGui()
1965 vamsasStart.setText(MessageManager.getString("label.session_update"));
1966 vamsasSave.setVisible(true);
1967 vamsasStop.setVisible(true);
1968 vamsasImport.setVisible(false); // Document import to existing session is
1969 // not possible for vamsas-client-1.0.
1972 protected void setupVamsasDisconnectedGui()
1974 vamsasSave.setVisible(false);
1975 vamsasStop.setVisible(false);
1976 vamsasImport.setVisible(true);
1977 vamsasStart.setText(MessageManager
1978 .getString("label.new_vamsas_session"));
1981 public void vamsasStop_actionPerformed(ActionEvent e)
1983 if (v_client != null)
1985 v_client.end_session();
1987 setupVamsasDisconnectedGui();
1991 protected void buildVamsasStMenu()
1993 if (v_client == null)
1995 String[] sess = null;
1998 sess = VamsasApplication.getSessionList();
1999 } catch (Exception e)
2001 jalview.bin.Cache.log.warn(
2002 "Problem getting current sessions list.", e);
2007 jalview.bin.Cache.log.debug("Got current sessions list: "
2008 + sess.length + " entries.");
2009 VamsasStMenu.removeAll();
2010 for (int i = 0; i < sess.length; i++)
2012 JMenuItem sessit = new JMenuItem();
2013 sessit.setText(sess[i]);
2014 sessit.setToolTipText(MessageManager.formatMessage(
2015 "label.connect_to_session", new String[]
2017 final Desktop dsktp = this;
2018 final String mysesid = sess[i];
2019 sessit.addActionListener(new ActionListener()
2022 public void actionPerformed(ActionEvent e)
2024 if (dsktp.v_client == null)
2026 Thread rthr = new Thread(new Runnable()
2031 dsktp.v_client = new VamsasApplication(dsktp, mysesid);
2032 dsktp.setupVamsasConnectedGui();
2033 dsktp.v_client.initial_update();
2041 VamsasStMenu.add(sessit);
2043 // don't show an empty menu.
2044 VamsasStMenu.setVisible(sess.length > 0);
2049 jalview.bin.Cache.log.debug("No current vamsas sessions.");
2050 VamsasStMenu.removeAll();
2051 VamsasStMenu.setVisible(false);
2056 // Not interested in the content. Just hide ourselves.
2057 VamsasStMenu.setVisible(false);
2061 public void vamsasSave_actionPerformed(ActionEvent e)
2063 if (v_client != null)
2065 JalviewFileChooser chooser = new JalviewFileChooser(
2066 jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
2067 { "vdj" }, // TODO: VAMSAS DOCUMENT EXTENSION is VDJ
2069 { "Vamsas Document" }, "Vamsas Document");
2071 chooser.setFileView(new JalviewFileView());
2072 chooser.setDialogTitle(MessageManager.getString("label.save_vamsas_document_archive"));
2074 int value = chooser.showSaveDialog(this);
2076 if (value == JalviewFileChooser.APPROVE_OPTION)
2078 java.io.File choice = chooser.getSelectedFile();
2079 JPanel progpanel = addProgressPanel(MessageManager.formatMessage("label.saving_vamsas_doc", new String[]{choice.getName()}));
2080 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice.getParent());
2081 String warnmsg = null;
2082 String warnttl = null;
2085 v_client.vclient.storeDocument(choice);
2088 warnttl = "Serious Problem saving Vamsas Document";
2089 warnmsg = ex.toString();
2090 jalview.bin.Cache.log.error("Error Whilst saving document to "
2093 } catch (Exception ex)
2095 warnttl = "Problem saving Vamsas Document.";
2096 warnmsg = ex.toString();
2097 jalview.bin.Cache.log.warn("Exception Whilst saving document to "
2101 removeProgressPanel(progpanel);
2102 if (warnmsg != null)
2104 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2106 warnmsg, warnttl, JOptionPane.ERROR_MESSAGE);
2112 JPanel vamUpdate = null;
2115 * hide vamsas user gui bits when a vamsas document event is being handled.
2118 * true to hide gui, false to reveal gui
2120 public void setVamsasUpdate(boolean b)
2122 jalview.bin.Cache.log.debug("Setting gui for Vamsas update "
2123 + (b ? "in progress" : "finished"));
2125 if (vamUpdate != null)
2127 this.removeProgressPanel(vamUpdate);
2131 vamUpdate = this.addProgressPanel(MessageManager.getString("label.updating_vamsas_session"));
2133 vamsasStart.setVisible(!b);
2134 vamsasStop.setVisible(!b);
2135 vamsasSave.setVisible(!b);
2138 public JInternalFrame[] getAllFrames()
2140 return desktop.getAllFrames();
2144 * Checks the given url to see if it gives a response indicating that the user
2145 * should be informed of a new questionnaire.
2149 public void checkForQuestionnaire(String url)
2151 UserQuestionnaireCheck jvq = new UserQuestionnaireCheck(url);
2152 // javax.swing.SwingUtilities.invokeLater(jvq);
2153 new Thread(jvq).start();
2157 * Proxy class for JDesktopPane which optionally displays the current memory
2158 * usage and highlights the desktop area with a red bar if free memory runs
2163 public class MyDesktopPane extends JDesktopPane implements Runnable
2166 boolean showMemoryUsage = false;
2170 java.text.NumberFormat df;
2172 float maxMemory, allocatedMemory, freeMemory, totalFreeMemory,
2175 public MyDesktopPane(boolean showMemoryUsage)
2177 showMemoryUsage(showMemoryUsage);
2180 public void showMemoryUsage(boolean showMemoryUsage)
2182 this.showMemoryUsage = showMemoryUsage;
2183 if (showMemoryUsage)
2185 Thread worker = new Thread(this);
2190 public boolean isShowMemoryUsage()
2192 return showMemoryUsage;
2197 df = java.text.NumberFormat.getNumberInstance();
2198 df.setMaximumFractionDigits(2);
2199 runtime = Runtime.getRuntime();
2201 while (showMemoryUsage)
2205 maxMemory = runtime.maxMemory() / 1048576f;
2206 allocatedMemory = runtime.totalMemory() / 1048576f;
2207 freeMemory = runtime.freeMemory() / 1048576f;
2208 totalFreeMemory = freeMemory + (maxMemory - allocatedMemory);
2210 percentUsage = (totalFreeMemory / maxMemory) * 100;
2212 // if (percentUsage < 20)
2214 // border1 = BorderFactory.createMatteBorder(12, 12, 12, 12,
2216 // instance.set.setBorder(border1);
2219 // sleep after showing usage
2221 } catch (Exception ex)
2223 ex.printStackTrace();
2228 public void paintComponent(Graphics g)
2230 if (showMemoryUsage && g != null && df != null)
2232 if (percentUsage < 20)
2234 g.setColor(Color.red);
2236 FontMetrics fm = g.getFontMetrics();
2239 g.drawString(MessageManager.formatMessage(
2240 "label.memory_stats",
2242 { df.format(totalFreeMemory), df.format(maxMemory),
2243 df.format(percentUsage) }), 10,
2244 getHeight() - fm.getHeight());
2251 * fixes stacking order after a modal dialog to ensure windows that should be
2252 * on top actually are
2254 public void relayerWindows()
2259 protected JMenuItem groovyShell;
2261 public void doGroovyCheck()
2263 if (jalview.bin.Cache.groovyJarsPresent())
2265 groovyShell = new JMenuItem();
2266 groovyShell.setText(MessageManager.getString("label.groovy_console"));
2267 groovyShell.addActionListener(new ActionListener()
2269 public void actionPerformed(ActionEvent e)
2271 groovyShell_actionPerformed(e);
2274 toolsMenu.add(groovyShell);
2275 groovyShell.setVisible(true);
2280 * Accessor method to quickly get all the AlignmentFrames loaded.
2282 public static AlignFrame[] getAlignFrames()
2284 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2290 List<AlignFrame> avp = new ArrayList<AlignFrame>();
2292 for (int i = frames.length - 1; i > -1; i--)
2294 if (frames[i] instanceof AlignFrame)
2296 avp.add((AlignFrame) frames[i]);
2298 else if (frames[i] instanceof SplitFrame)
2301 * Also check for a split frame containing an AlignFrame
2303 SplitFrame sf = (SplitFrame) frames[i];
2304 if (sf.getTopComponent() instanceof AlignFrame)
2306 avp.add((AlignFrame) sf.getTopComponent());
2308 if (sf.getBottomComponent() instanceof AlignFrame)
2310 avp.add((AlignFrame) sf.getBottomComponent());
2314 if (avp.size() == 0)
2318 AlignFrame afs[] = avp.toArray(new AlignFrame[avp.size()]);
2323 * Returns an array of any AppJmol frames in the Desktop (or null if none).
2327 public AppJmol[] getJmols()
2329 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2335 List<AppJmol> avp = new ArrayList<AppJmol>();
2337 for (int i = frames.length - 1; i > -1; i--)
2339 if (frames[i] instanceof AppJmol)
2341 AppJmol af = (AppJmol) frames[i];
2345 if (avp.size() == 0)
2349 AppJmol afs[] = avp.toArray(new AppJmol[avp.size()]);
2354 * Add Groovy Support to Jalview
2356 public void groovyShell_actionPerformed(ActionEvent e)
2358 // use reflection to avoid creating compilation dependency.
2359 if (!jalview.bin.Cache.groovyJarsPresent())
2361 throw new Error(MessageManager.getString("error.implementation_error_cannot_create_groovyshell"));
2365 Class gcClass = Desktop.class.getClassLoader().loadClass(
2366 "groovy.ui.Console");
2367 Constructor gccons = gcClass.getConstructor(null);
2368 java.lang.reflect.Method setvar = gcClass.getMethod("setVariable",
2370 { String.class, Object.class });
2371 java.lang.reflect.Method run = gcClass.getMethod("run", null);
2372 Object gc = gccons.newInstance(null);
2373 setvar.invoke(gc, new Object[]
2374 { "Jalview", this });
2375 run.invoke(gc, null);
2376 } catch (Exception ex)
2378 jalview.bin.Cache.log.error("Groovy Shell Creation failed.", ex);
2380 .showInternalMessageDialog(
2383 MessageManager.getString("label.couldnt_create_groovy_shell"),
2384 MessageManager.getString("label.groovy_support_failed"),
2385 JOptionPane.ERROR_MESSAGE);
2390 * Progress bars managed by the IProgressIndicator method.
2392 private Hashtable<Long, JPanel> progressBars;
2394 private Hashtable<Long, IProgressIndicatorHandler> progressBarHandlers;
2399 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
2401 public void setProgressBar(String message, long id)
2403 if (progressBars == null)
2405 progressBars = new Hashtable<Long, JPanel>();
2406 progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
2409 if (progressBars.get(new Long(id)) != null)
2411 JPanel progressPanel = progressBars.remove(new Long(id));
2412 if (progressBarHandlers.contains(new Long(id)))
2414 progressBarHandlers.remove(new Long(id));
2416 removeProgressPanel(progressPanel);
2420 progressBars.put(new Long(id), addProgressPanel(message));
2427 * @see jalview.gui.IProgressIndicator#registerHandler(long,
2428 * jalview.gui.IProgressIndicatorHandler)
2430 public void registerHandler(final long id,
2431 final IProgressIndicatorHandler handler)
2433 if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
2435 throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
2437 progressBarHandlers.put(new Long(id), handler);
2438 final JPanel progressPanel = progressBars.get(new Long(id));
2439 if (handler.canCancel())
2441 JButton cancel = new JButton(
2442 MessageManager.getString("action.cancel"));
2443 final IProgressIndicator us = this;
2444 cancel.addActionListener(new ActionListener()
2447 public void actionPerformed(ActionEvent e)
2449 handler.cancelActivity(id);
2450 us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
2453 progressPanel.add(cancel, BorderLayout.EAST);
2459 * @return true if any progress bars are still active
2462 public boolean operationInProgress()
2464 if (progressBars != null && progressBars.size() > 0)
2472 * This will return the first AlignFrame viewing AlignViewport av. It will
2473 * break if there are more than one AlignFrames viewing a particular av.
2476 * @return alignFrame for av
2478 public static AlignFrame getAlignFrameFor(AlignViewport av)
2480 if (desktop != null)
2482 AlignmentPanel[] aps = getAlignmentPanels(av.getSequenceSetId());
2483 for (int panel = 0; aps != null && panel < aps.length; panel++)
2485 if (aps[panel] != null && aps[panel].av == av)
2487 return aps[panel].alignFrame;
2494 public VamsasApplication getVamsasApplication()
2501 * flag set if jalview GUI is being operated programmatically
2503 private boolean inBatchMode = false;
2506 * check if jalview GUI is being operated programmatically
2508 * @return inBatchMode
2510 public boolean isInBatchMode()
2516 * set flag if jalview GUI is being operated programmatically
2518 * @param inBatchMode
2520 public void setInBatchMode(boolean inBatchMode)
2522 this.inBatchMode = inBatchMode;
2525 public void startServiceDiscovery()
2527 startServiceDiscovery(false);
2530 public void startServiceDiscovery(boolean blocking)
2532 boolean alive = true;
2533 Thread t0 = null, t1 = null, t2 = null;
2534 // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
2537 // todo: changesupport handlers need to be transferred
2538 if (discoverer == null)
2540 discoverer = new jalview.ws.jws1.Discoverer();
2541 // register PCS handler for desktop.
2542 discoverer.addPropertyChangeListener(changeSupport);
2544 // JAL-940 - disabled JWS1 service configuration - always start discoverer
2545 // until we phase out completely
2546 (t0 = new Thread(discoverer)).start();
2549 // ENFIN services are EOLed as of Jalview 2.8.1 release
2554 if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
2556 // EnfinEnvision web service menu entries are rebuild every time the
2557 // menu is shown, so no changeSupport events are needed.
2558 jalview.ws.EnfinEnvision2OneWay.getInstance();
2559 (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
2562 } catch (Exception e)
2565 .info("Exception when trying to launch Envision2 workflow discovery.",
2567 Cache.log.info(e.getStackTrace());
2571 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
2573 if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
2575 jalview.ws.jws2.Jws2Discoverer.getDiscoverer().setAborted(true);
2577 t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer().startDiscoverer(
2583 // TODO: do rest service discovery
2592 } catch (Exception e)
2595 alive = (t1 != null && t1.isAlive())
2596 || (t2 != null && t2.isAlive())
2597 || (t3 != null && t3.isAlive())
2598 || (t0 != null && t0.isAlive());
2604 * called to check if the service discovery process completed successfully.
2608 protected void JalviewServicesChanged(PropertyChangeEvent evt)
2610 if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
2612 final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
2613 .getErrorMessages();
2616 if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
2618 if (serviceChangedDialog == null)
2620 // only run if we aren't already displaying one of these.
2621 addDialogThread(serviceChangedDialog = new Runnable()
2627 * JalviewDialog jd =new JalviewDialog() {
2629 * @Override protected void cancelPressed() { // TODO
2630 * Auto-generated method stub
2632 * }@Override protected void okPressed() { // TODO
2633 * Auto-generated method stub
2635 * }@Override protected void raiseClosed() { // TODO
2636 * Auto-generated method stub
2638 * } }; jd.initDialogFrame(new
2639 * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
2640 * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
2641 * + " or mis-configured HTTP proxy settings.<br/>" +
2642 * "Check the <em>Connections</em> and <em>Web services</em> tab of the"
2644 * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
2645 * ), true, true, "Web Service Configuration Problem", 450,
2648 * jd.waitForInput();
2654 "<html><table width=\"450\"><tr><td>"
2656 + "</td></tr></table>"
2657 + "<p>It may be that you have invalid JABA URLs<br/>in your web service preferences,"
2658 + "<br>or as a command-line argument, or mis-configured HTTP proxy settings.</p>"
2659 + "<p>Check the <em>Connections</em> and <em>Web services</em> tab<br/>of the"
2660 + " Tools->Preferences dialog box to change them.</p></html>"),
2661 "Web Service Configuration Problem",
2662 JOptionPane.DEFAULT_OPTION,
2663 JOptionPane.ERROR_MESSAGE);
2664 serviceChangedDialog = null;
2673 .error("Errors reported by JABA discovery service. Check web services preferences.\n"
2680 private Runnable serviceChangedDialog = null;
2683 * start a thread to open a URL in the configured browser. Pops up a warning
2684 * dialog to the user if there is an exception when calling out to the browser
2689 public static void showUrl(final String url)
2691 showUrl(url, Desktop.instance);
2695 * Like showUrl but allows progress handler to be specified
2699 * (null) or object implementing IProgressIndicator
2701 public static void showUrl(final String url,
2702 final IProgressIndicator progress)
2704 new Thread(new Runnable()
2710 if (progress != null)
2712 progress.setProgressBar(MessageManager.formatMessage("status.opening_params", new String[]{url}), this.hashCode());
2714 jalview.util.BrowserLauncher.openURL(url);
2715 } catch (Exception ex)
2718 .showInternalMessageDialog(
2720 MessageManager.getString("label.web_browser_not_found_unix"),
2721 MessageManager.getString("label.web_browser_not_found"),
2722 JOptionPane.WARNING_MESSAGE);
2724 ex.printStackTrace();
2726 if (progress != null)
2728 progress.setProgressBar(null, this.hashCode());
2734 public static WsParamSetManager wsparamManager = null;
2736 public static ParamManager getUserParameterStore()
2738 if (wsparamManager == null)
2740 wsparamManager = new WsParamSetManager();
2742 return wsparamManager;
2746 * static hyperlink handler proxy method for use by Jalview's internal windows
2750 public static void hyperlinkUpdate(HyperlinkEvent e)
2752 if (e.getEventType() == EventType.ACTIVATED)
2757 url = e.getURL().toString();
2758 Desktop.showUrl(url);
2759 } catch (Exception x)
2763 if (Cache.log != null)
2765 Cache.log.error("Couldn't handle string " + url + " as a URL.");
2769 System.err.println("Couldn't handle string " + url
2773 // ignore any exceptions due to dud links.
2780 * single thread that handles display of dialogs to user.
2782 ExecutorService dialogExecutor = Executors.newSingleThreadExecutor();
2785 * flag indicating if dialogExecutor should try to acquire a permit
2787 private volatile boolean dialogPause = true;
2792 private java.util.concurrent.Semaphore block = new Semaphore(0);
2795 * add another dialog thread to the queue
2799 public void addDialogThread(final Runnable prompter)
2801 dialogExecutor.submit(new Runnable()
2810 } catch (InterruptedException x)
2815 if (instance == null)
2821 SwingUtilities.invokeAndWait(prompter);
2822 } catch (Exception q)
2824 Cache.log.warn("Unexpected Exception in dialog thread.", q);
2830 public void startDialogQueue()
2832 // set the flag so we don't pause waiting for another permit and semaphore
2833 // the current task to begin
2834 dialogPause = false;
2838 protected void snapShotWindow_actionPerformed(ActionEvent e)
2842 ImageMaker im = new jalview.util.ImageMaker(this, ImageMaker.TYPE.EPS,
2843 "View of Desktop", getWidth(), getHeight(), of = new File(
2844 "Jalview_snapshot" + System.currentTimeMillis()
2845 + ".eps"), "View of desktop");
2847 paintAll(im.getGraphics());
2849 } catch (Exception q)
2851 Cache.log.error("Couldn't write snapshot to "+of.getAbsolutePath(),q);
2854 Cache.log.info("Successfully written snapshot to file "+of.getAbsolutePath());