import jalview.schemes.*;
public class AlignFrame
- extends Frame implements ActionListener,
- ItemListener, KeyListener, MouseListener
+ extends EmbmenuFrame implements ActionListener,
+ ItemListener, KeyListener
{
public AlignmentPanel alignPanel;
public AlignViewport viewport;
MenuItem documentation = new MenuItem();
MenuItem about = new MenuItem();
CheckboxMenuItem seqLimits = new CheckboxMenuItem();
- Panel embeddedMenu;
- Label embeddedEdit;
- Label embeddedSelect;
- Label embeddedView;
- Label embeddedFormat;
- Label embeddedColour;
- Label embeddedFile;
- Label embeddedHelp;
- Label embeddedCalculate;
- FlowLayout flowLayout1;
private void jbInit()
throws Exception
selectMenu.add(invertColSel);
selectMenu.add(deleteGroups);
}
+ MenuItem featureSettings = new MenuItem();
+ CheckboxMenuItem sequenceFeatures = new CheckboxMenuItem();
+ MenuItem annotationColour = new MenuItem();
+ MenuItem invertColSel = new MenuItem();
+ Menu menu1 = new Menu();
+ MenuItem showColumns = new MenuItem();
+ MenuItem showSeqs = new MenuItem();
+ Menu menu2 = new Menu();
+ MenuItem hideColumns = new MenuItem();
+ MenuItem hideSequences = new MenuItem();
+ Menu formatMenu = new Menu();
+ Menu selectMenu = new Menu();
+ MenuItem newView = new MenuItem();
+
/**
+ * Attach the alignFrame panels after embedding menus, if necessary.
* This used to be called setEmbedded, but is now creates the
* dropdown menus in a platform independent manner
* to avoid OSX/Mac menu appendage daftness.
*/
public void createAlignFrameWindow(boolean reallyEmbedded, String title)
{
- embeddedMenu = new Panel();
- embeddedEdit = new Label("Edit");
- embeddedSelect = new Label("Select");
- embeddedView = new Label("View");
- embeddedFormat = new Label("Format");
- embeddedColour = new Label("Colour");
- embeddedFile = new Label("File");
- embeddedHelp = new Label("Help");
- embeddedCalculate = new Label("Calculate");
- flowLayout1 = new FlowLayout();
- embeddedMenu.setBackground(Color.lightGray);
- embeddedMenu.setLayout(flowLayout1);
- embeddedEdit.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
- embeddedSelect.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
- embeddedView.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
- embeddedFormat.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
- embeddedColour.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
- embeddedFile.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
- embeddedHelp.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
- embeddedCalculate.setFont(new java.awt.Font("Arial", Font.PLAIN, 10));
- embeddedMenu.add(embeddedFile);
- embeddedMenu.add(embeddedEdit);
- embeddedMenu.add(embeddedSelect);
- embeddedMenu.add(embeddedView);
- embeddedMenu.add(embeddedFormat);
- embeddedMenu.add(embeddedColour);
- embeddedMenu.add(embeddedCalculate);
- embeddedMenu.add(embeddedHelp);
- flowLayout1.setAlignment(FlowLayout.LEFT);
- flowLayout1.setHgap(2);
- flowLayout1.setVgap(0);
- embeddedFile.addMouseListener(this);
- embeddedEdit.addMouseListener(this);
- embeddedSelect.addMouseListener(this);
- embeddedView.addMouseListener(this);
- embeddedFormat.addMouseListener(this);
- embeddedColour.addMouseListener(this);
- embeddedCalculate.addMouseListener(this);
- embeddedHelp.addMouseListener(this);
if (reallyEmbedded)
{
+ //////
+ // Explicly build the embedded menu panel for the on-page applet
+ //
+ embeddedMenu = makeEmbeddedPopupMenu(alignFrameMenuBar, "Arial", Font.PLAIN, 10, false); // use our own fonts.
// view cannot be closed if its actually on the page
fileMenu.remove(closeMenuItem);
fileMenu.remove(3); // Remove Seperator
viewport.applet.add(alignPanel, BorderLayout.CENTER);
viewport.applet.validate();
} else {
- if (new jalview.util.Platform().isAMac())
- {
- // TODO: try to modify the embeddedMenu display so it looks like a real toolbar menu
- // TODO: modify click/mouse handler for embeddedMenu so it behaves more like a real pulldown menu toolbar
- setMenuBar(null);// alignFramMenuBar);
- // add the components to the AlignFrame area.
- add(embeddedMenu, BorderLayout.NORTH);
+ ////////
+ // test and embed menu bar if necessary.
+ //
+ if (embedMenuIfNeeded(alignPanel)) {
+ // adjust for status bar height too
alignPanel.setSize(getSize().width,
getSize().height
- - embeddedMenu.HEIGHT - statusBar.HEIGHT);
-
+ - statusBar.HEIGHT);
}
add(statusBar, BorderLayout.SOUTH);
add(alignPanel, BorderLayout.CENTER);
DEFAULT_HEIGHT);
}
}
-
- PopupMenu filePopup, editPopup, searchPopup,
- viewPopup, formatPopup, colourPopup, calculatePopup, helpPopup;
- MenuItem featureSettings = new MenuItem();
- CheckboxMenuItem sequenceFeatures = new CheckboxMenuItem();
- MenuItem annotationColour = new MenuItem();
- MenuItem invertColSel = new MenuItem();
- Menu menu1 = new Menu();
- MenuItem showColumns = new MenuItem();
- MenuItem showSeqs = new MenuItem();
- Menu menu2 = new Menu();
- MenuItem hideColumns = new MenuItem();
- MenuItem hideSequences = new MenuItem();
- Menu formatMenu = new Menu();
- Menu selectMenu = new Menu();
- MenuItem newView = new MenuItem();
-
- public void mousePressed(MouseEvent evt)
- {
- PopupMenu popup = null;
- Label source = (Label) evt.getSource();
- if (source == embeddedFile)
- {
- popup = filePopup = genPopupMenu(filePopup, fileMenu);
- }
- else if (source == embeddedEdit)
- {
- popup = editPopup = genPopupMenu(editPopup, editMenu);
- }
- else if (source == embeddedSelect)
- {
- popup = searchPopup = genPopupMenu(searchPopup, selectMenu);
- }
- else if (source == embeddedView)
- {
- popup = viewPopup = genPopupMenu(viewPopup, viewMenu);
- }
- else if (source == embeddedFormat)
- {
- popup = formatPopup = genPopupMenu(formatPopup, formatMenu);
- }
- else if (source == embeddedColour)
- {
- popup = colourPopup = genPopupMenu(colourPopup, colourMenu);
- }
- else if (source == embeddedCalculate)
- {
- popup = calculatePopup = genPopupMenu(calculatePopup, calculateMenu);
- }
- else if (source == embeddedHelp)
- {
- popup = helpPopup = genPopupMenu(helpPopup, helpMenu);
- }
-
- embeddedMenu.add(popup);
- popup.show(embeddedMenu,
- source.getBounds().x,
- source.getBounds().y + source.getBounds().getSize().height);
- }
-
- PopupMenu genPopupMenu(PopupMenu popup, Menu original)
- {
- if (popup != null)
- {
- return popup;
- }
- popup = new PopupMenu();
- int m, mSize = original.getItemCount();
- for (m = 0; m < mSize; m++)
- {
- popup.add(original.getItem(m));
- mSize--;
- m--;
- }
-
- return popup;
- }
-
- public void mouseClicked(MouseEvent evt)
- {}
-
- public void mouseReleased(MouseEvent evt)
- {}
-
- public void mouseEntered(MouseEvent evt)
- {}
-
- public void mouseExited(MouseEvent evt)
- {}
-
}
--- /dev/null
+package jalview.appletgui;\r
+\r
+import java.awt.BorderLayout;\r
+import java.awt.Color;\r
+import java.awt.Container;\r
+import java.awt.FlowLayout;\r
+import java.awt.Font;\r
+import java.awt.Frame;\r
+import java.awt.GraphicsConfiguration;\r
+import java.awt.HeadlessException;\r
+import java.awt.Label;\r
+import java.awt.Menu;\r
+import java.awt.MenuBar;\r
+import java.awt.Panel;\r
+import java.awt.PopupMenu;\r
+import java.awt.event.ActionListener;\r
+import java.awt.event.ItemListener;\r
+import java.awt.event.MouseEvent;\r
+import java.awt.event.MouseListener;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+/**\r
+ * This class implements a pattern form embedding toolbars as a panel with popups\r
+ * for situations where the system menu bar is either invisible or inappropriate.\r
+ * It was derived from the code for embedding the jalview applet alignFrame as\r
+ * a component on the web-page, which requires the local alignFrame menu to be\r
+ * attached to that panel rather than placed on the parent (which isn't allowed\r
+ * anyhow).\r
+ * TODO: try to modify the embeddedMenu display so it looks like a real toolbar menu\r
+ * TODO: modify click/mouse handler for embeddedMenu so it behaves more like a real pulldown menu toolbar\r
+ * \r
+ * @author Jim Procter and Andrew Waterhouse\r
+ *\r
+ */\r
+public class EmbmenuFrame extends Frame implements MouseListener\r
+{\r
+ /**\r
+ * map from labels to popup menus for the embedded menubar\r
+ */\r
+ protected Hashtable embeddedPopup;\r
+ /**\r
+ * the embedded menu is built on this and should be \r
+ * added to the frame at the appropriate position.\r
+ * \r
+ */\r
+ protected Panel embeddedMenu;\r
+\r
+ public EmbmenuFrame() throws HeadlessException\r
+ {\r
+ super();\r
+ }\r
+ public EmbmenuFrame(String title) throws HeadlessException\r
+ {\r
+ super(title);\r
+ }\r
+ /**\r
+ * Check if the applet is running on a platform that requires the Frame menuBar to be embedded,\r
+ * and if so, embeds it.\r
+ * @param tobeAdjusted the panel that is to be reduced to make space for the embedded menu bar\r
+ * @return true if menuBar was embedded and tobeAdjusted's height modified\r
+ */\r
+ protected boolean embedMenuIfNeeded(Panel tobeAdjusted)\r
+ {\r
+ MenuBar topMenuBar = getMenuBar();\r
+ if (topMenuBar==null)\r
+ {\r
+ return false;\r
+ }\r
+ // DEBUG Hint: can test embedded menus by inserting true here.\r
+ if (new jalview.util.Platform().isAMac())\r
+ {\r
+ // Build the embedded menu panel\r
+ embeddedMenu = makeEmbeddedPopupMenu(topMenuBar, "Arial", Font.PLAIN, 10, true); // try to pickup system font.\r
+ setMenuBar(null);\r
+ // add the components to the TreePanel area.\r
+ add(embeddedMenu, BorderLayout.NORTH);\r
+ tobeAdjusted.setSize(getSize().width,\r
+ getSize().height\r
+ - embeddedMenu.HEIGHT); \r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+ /**\r
+ * move all menus on menuBar onto embeddedMenu.\r
+ * embeddedPopup is used to store the popups for each menu removed from the menuBar and added\r
+ * to the panel.\r
+ * NOTE: it is up to the caller to remove menuBar from the Frame if it is already attached.\r
+ * @param menuBar\r
+ * @param fn\r
+ * @param fstyle\r
+ * @param fsz\r
+ * @param overrideFonts true if we take the menuBar fonts in preference to the supplied defaults\r
+ * @return the embedded menu instance to be added to the frame.\r
+ */\r
+ protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, String fn,\r
+ int fstyle, int fsz, boolean overrideFonts)\r
+ {\r
+ return makeEmbeddedPopupMenu(menuBar, fn, fstyle, fsz, overrideFonts, false);\r
+ }\r
+ /**\r
+ * Create or add elements to the embedded menu from menuBar. This removes all menu from\r
+ * menuBar and it is up to the caller to remove the now useless menuBar from the Frame if it is already attached. \r
+ * @param menuBar\r
+ * @param fn\r
+ * @param fstyle\r
+ * @param fsz\r
+ * @param overrideFonts \r
+ * @param append true means existing menu will be emptied before adding new elements\r
+ * @return\r
+ */\r
+ protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, String fn,\r
+ int fstyle, int fsz, boolean overrideFonts, boolean append)\r
+ {\r
+ if (!append)\r
+ {\r
+ if (embeddedPopup != null)\r
+ {\r
+ embeddedPopup.clear(); // TODO: check if j1.1\r
+ } \r
+ if (embeddedMenu!=null)\r
+ {\r
+ embeddedMenu.removeAll(); \r
+ }\r
+ }\r
+ if (embeddedPopup==null)\r
+ {\r
+ embeddedPopup = new Hashtable();\r
+ }\r
+ \r
+ embeddedMenu = makeEmbeddedPopupMenu(menuBar, fn, fstyle, fsz, overrideFonts, embeddedPopup, new Panel(), this);\r
+ return embeddedMenu;\r
+ }\r
+ /**\r
+ * Generic method to move elements from menubar onto embeddedMenu using the existing or the supplied font, \r
+ * and adds binding from panel to attached menus in embeddedPopup\r
+ * This removes all menu from\r
+ * menuBar and it is up to the caller to remove the now useless menuBar from the Frame if it is already attached.\r
+ * @param menuBar must be non-null\r
+ * @param fn\r
+ * @param fstyle\r
+ * @param fsz\r
+ * @param overrideFonts\r
+ * @param embeddedPopup must be non-null\r
+ * @param embeddedMenu if null, a new panel will be created and returned\r
+ * @param clickHandler - usually the instance of EmbmenuFrame that holds references to embeddedPopup and embeddedMenu\r
+ * @return the panel instance for convenience.\r
+ */\r
+ protected Panel makeEmbeddedPopupMenu(MenuBar menuBar, String fn,\r
+ int fstyle, int fsz, boolean overrideFonts, Hashtable embeddedPopup, Panel embeddedMenu, MouseListener clickHandler)\r
+ {\r
+ if (embeddedPopup==null)\r
+ {\r
+ throw new Error("Implementation error - embeddedPopup must be non-null");\r
+ }\r
+ if (overrideFonts)\r
+ {\r
+ Font mbf = menuBar.getFont();\r
+ if (mbf!=null)\r
+ {\r
+ fn = mbf.getName();\r
+ fstyle = mbf.getStyle();\r
+ fsz = mbf.getSize();\r
+ }\r
+ }\r
+ if (embeddedMenu==null)\r
+ embeddedMenu = new Panel();\r
+ FlowLayout flowLayout1 = new FlowLayout();\r
+ embeddedMenu.setBackground(Color.lightGray);\r
+ embeddedMenu.setLayout(flowLayout1);\r
+ // loop thru\r
+ for (int mbi = 0,nMbi=menuBar.getMenuCount(); mbi<nMbi; mbi++)\r
+ {\r
+ Menu mi = menuBar.getMenu(mbi);\r
+ Label elab = new Label(mi.getLabel());\r
+ elab.setFont(new java.awt.Font(fn, fstyle, fsz));\r
+ // add the menu entries\r
+ PopupMenu popup = new PopupMenu();\r
+ int m, mSize = mi.getItemCount();\r
+ for (m = 0; m < mSize; m++)\r
+ {\r
+ popup.add(mi.getItem(m));\r
+ mSize--;\r
+ m--;\r
+ }\r
+ embeddedPopup.put(elab, popup);\r
+ embeddedMenu.add(elab);\r
+ elab.addMouseListener(clickHandler);\r
+ }\r
+ flowLayout1.setAlignment(FlowLayout.LEFT);\r
+ flowLayout1.setHgap(2);\r
+ flowLayout1.setVgap(0);\r
+ return embeddedMenu;\r
+ }\r
+\r
+ public void mousePressed(MouseEvent evt)\r
+ {\r
+ PopupMenu popup = null;\r
+ Label source = (Label) evt.getSource();\r
+ popup = getPopupMenu(source);\r
+ if (popup!=null)\r
+ {\r
+ embeddedMenu.add(popup);\r
+ popup.show(embeddedMenu,\r
+ source.getBounds().x,\r
+ source.getBounds().y + source.getBounds().getSize().height);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * get the menu for source from the hash.\r
+ * @param source what was clicked on.\r
+ */\r
+ PopupMenu getPopupMenu(Label source)\r
+ {\r
+ return (PopupMenu) embeddedPopup.get(source);\r
+ }\r
+\r
+ public void mouseClicked(MouseEvent evt)\r
+ {}\r
+\r
+ public void mouseReleased(MouseEvent evt)\r
+ {}\r
+\r
+ public void mouseEntered(MouseEvent evt)\r
+ {}\r
+\r
+ public void mouseExited(MouseEvent evt)\r
+ {}\r
+\r
+ /**\r
+ * called to clear the GUI resources taken up for embedding\r
+ * and remove any self references so we can be garbage collected.\r
+ */\r
+ public void destroyMenus()\r
+ {\r
+ if (embeddedPopup!=null)\r
+ {\r
+ Enumeration e = embeddedPopup.keys();\r
+ while (e.hasMoreElements())\r
+ {\r
+ Label lb = (Label) e.nextElement();\r
+ lb.removeMouseListener(this);\r
+ }\r
+ embeddedPopup.clear();\r
+ }\r
+ if (embeddedMenu!=null)\r
+ {\r
+ embeddedMenu.removeAll();\r
+ }\r
+ }\r
+ /**\r
+ * calls destroyMenus()\r
+ */\r
+ public void finalize() throws Throwable {\r
+ destroyMenus();\r
+ embeddedPopup=null;\r
+ embeddedMenu=null;\r
+ super.finalize();\r
+ }\r
+}
\ No newline at end of file