Merge branch 'master' of https://source.jalview.org/git/jalviewjs.git
[jalviewjs.git] / site / j2s / swingjs / plaf / JSButtonUI.java
index 38a2406..2c7b94a 100644 (file)
-package swingjs.plaf;\r
-\r
-//import jsjava.awt.FontMetrics;\r
-import jsjava.awt.event.MouseMotionListener;\r
-import jsjavax.swing.AbstractButton;\r
-import jsjavax.swing.LookAndFeel;\r
-import jsjavax.swing.UIManager;\r
-import swingjs.api.DOMNode;\r
-import jsjavax.swing.plaf.UIResource;\r
-/**\r
- * SWingJS implementation of stateful user interface for buttons. \r
- * Modeled after javax.swing.plaf.basic.BasicButtonUI.java (commented out below).\r
- * \r
- * @author Bob Hanson\r
- *\r
- */\r
-public class JSButtonUI extends JSComponentUI {\r
-\r
-       \r
-       /**\r
-        * the radio or check-box or simple button\r
-        * \r
-        */\r
-       protected DOMNode domBtn;\r
-\r
-       @Override\r
-       public DOMNode getDOMObject() {\r
-               if (domNode == null)\r
-                       domBtn = enableNode = valueNode = domNode = createDOMObject("input", id,\r
-                                       "type", "button");\r
-               setCssFont(DOMNode.setAttr(domNode, "value", ((AbstractButton) c).getText()),\r
-                               c.getFont());\r
-               return domNode;\r
-       }\r
-\r
-       /**\r
-        * validate a button press -- with a simple button, this is just TRUE.\r
-        * This is needed because sometimes the area near the button is pressed\r
-        * but not the actual button.\r
-        * @param isRelease TODO\r
-        * \r
-        * @return true if the HTML5 button was actually pressed\r
-        */\r
-  boolean verifyButtonClick(boolean isRelease) {\r
-               return true;\r
-       }\r
-\r
-\r
-       // from BasicButtonUI\r
-       \r
-       protected void installJSUI() {\r
-               installDefaults((AbstractButton) c);\r
-               installListeners((AbstractButton) c);\r
-               installKeyboardActions((AbstractButton) c);\r
-       }\r
-  \r
-       protected void uninstallJSUI() {\r
-               uninstallKeyboardActions((AbstractButton) c);\r
-               uninstallListeners((AbstractButton) c);\r
-               //uninstallDefaults((AbstractButton) c);\r
-       }\r
-       \r
-       protected void installListeners(AbstractButton b) {\r
-               JSButtonListener listener = new JSButtonListener(b);\r
-               if (listener != null) {\r
-                       b.addMouseListener(listener);\r
-                       b.addMouseMotionListener(listener);\r
-                       b.addFocusListener(listener);\r
-      b.addPropertyChangeListener(listener);\r
-                       b.addChangeListener(listener);\r
-               }\r
-       }\r
-\r
-       protected void uninstallListeners(AbstractButton b) {\r
-               JSButtonListener listener = getButtonListener(b);\r
-               if (listener != null) {\r
-                       b.removeMouseListener(listener);\r
-                       b.removeMouseMotionListener(listener);\r
-                       b.removeFocusListener(listener);\r
-                       b.removeChangeListener(listener);\r
-                       b.removePropertyChangeListener(listener);\r
-               }\r
-       }\r
-\r
-       protected void installKeyboardActions(AbstractButton b) {\r
-               JSButtonListener listener = getButtonListener(b);\r
-               if (listener != null) {\r
-                       listener.installKeyboardActions(b);\r
-               }\r
-       }\r
-       \r
-  protected void uninstallKeyboardActions(AbstractButton b) {\r
-      JSButtonListener listener = getButtonListener(b);\r
-      if(listener != null) {\r
-          listener.uninstallKeyboardActions(b);\r
-      }\r
-  }\r
-\r
-  /**\r
-   * Returns the ButtonListener for the passed in Button, or null if one\r
-   * could not be found.\r
-   */\r
-  protected JSButtonListener getButtonListener(AbstractButton b) {\r
-      MouseMotionListener[] listeners = b.getMouseMotionListeners();\r
-\r
-      if (listeners != null) {\r
-          for (int counter = 0; counter < listeners.length; counter++) {\r
-              if (listeners[counter] instanceof JSButtonListener) {\r
-                  return (JSButtonListener)listeners[counter];\r
-              }\r
-          }\r
-      }\r
-      return null;\r
-  }\r
-\r
-  // SwingJS -- this is interesting, as it summarizes everything we will need\r
-  // to implement, ultimately. SwingUtilities.layoutCompoundLabel\r
-  // details what we are going to have to do somewhere. \r
-  \r
-//     private String layout(AbstractButton b, FontMetrics fm, int width, int height) {\r
-//             Insets i = b.getInsets();\r
-//             viewRect.x = i.left;\r
-//             viewRect.y = i.top;\r
-//             viewRect.width = width - (i.right + viewRect.x);\r
-//             viewRect.height = height - (i.bottom + viewRect.y);\r
-//\r
-//             textRect.x = textRect.y = textRect.width = textRect.height = 0;\r
-//             iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;\r
-//\r
-//             // layout the text and icon\r
-//             return SwingUtilities.layoutCompoundLabel(b, fm, b.getText(), b.getIcon(),\r
-//                             b.getVerticalAlignment(), b.getHorizontalAlignment(),\r
-//                             b.getVerticalTextPosition(), b.getHorizontalTextPosition(), viewRect,\r
-//                             iconRect, textRect, b.getText() == null ? 0 : b.getIconTextGap());\r
-//             return null;\r
-//     }\r
-\r
-\r
-//  // Visual constants\r
-//  // NOTE: This is not used or set any where. Were we allowed to remove\r
-//  // fields, this would be removed.\r
-//  protected int defaultTextIconGap;\r
-//\r
-  /** Amount to offset text, the value of this comes from\r
-   defaultTextShiftOffset once setTextShiftOffset has been invoked.\r
-   */\r
-  protected int shiftOffset = 0;\r
-       \r
-  /** Value that is set in shiftOffset once setTextShiftOffset has been\r
-   invoked. The value of this comes from the defaults table.\r
-   */\r
-  protected int defaultTextShiftOffset;\r
-//\r
-//protected String propertyPrefix = "Button.";\r
-//  \r
-//  private static final Object BASIC_BUTTON_UI_KEY = new Object();\r
-//\r
-//  // ********************************\r
-//  //          Create PLAF\r
-//  // ********************************\r
-//  public static ComponentUI createUI(JComponent c) {\r
-//      AppContext appContext = AppContext.getAppContext();\r
-//      BasicButtonUI buttonUI = \r
-//              (BasicButtonUI) appContext.get(BASIC_BUTTON_UI_KEY);\r
-//      if (buttonUI == null) {\r
-//          buttonUI = new BasicButtonUI();\r
-//          appContext.put(BASIC_BUTTON_UI_KEY, buttonUI);\r
-//      }\r
-//      return buttonUI;\r
-//  }\r
-//\r
-  protected String getPropertyPrefix() {\r
-      return "Button.";\r
-  }\r
-//\r
-//\r
-//  // ********************************\r
-//  //          Install PLAF\r
-//  // ********************************\r
-//  public void installUI(JComponent c) {\r
-//      installDefaults((AbstractButton) c);\r
-//      installListeners((AbstractButton) c);\r
-//      installKeyboardActions((AbstractButton) c);\r
-//      BasicHTML.updateRenderer(c, ((AbstractButton) c).getText());\r
-//  }\r
-//\r
-  protected void installDefaults(AbstractButton b) {\r
-      // load shared instance defaults\r
-      String pp = getPropertyPrefix();\r
-\r
-      defaultTextShiftOffset = UIManager.getInt(pp + "textShiftOffset");\r
-\r
-//      // set the following defaults on the button\r
-//      if (b.isContentAreaFilled()) {\r
-//          LookAndFeel.installProperty(b, "opaque", Boolean.TRUE);\r
-//      } else {\r
-//          LookAndFeel.installProperty(b, "opaque", Boolean.FALSE);\r
-//      }\r
-\r
-      if(b.getMargin() == null || (b.getMargin() instanceof UIResource)) {\r
-          b.setMargin(UIManager.getInsets(pp + "margin"));\r
-      }\r
-\r
-      LookAndFeel.installColorsAndFont(b, pp + "background",\r
-                                       pp + "foreground", pp + "font");\r
-//      LookAndFeel.installBorder(b, pp + "border");\r
-//\r
-//      Object rollover = UIManager.get(pp + "rollover");\r
-//      if (rollover != null) {\r
-//          LookAndFeel.installProperty(b, "rolloverEnabled", rollover);\r
-//      }\r
-      LookAndFeel.installProperty(b, "iconTextGap", new Integer(4));\r
-  }\r
-//\r
-//  protected void installListeners(AbstractButton b) {\r
-//      JSButtonListener listener = createButtonListener(b);\r
-//      if(listener != null) {\r
-//          b.addMouseListener(listener);\r
-//          b.addMouseMotionListener(listener);\r
-//          b.addFocusListener(listener);\r
-//          b.addPropertyChangeListener(listener);\r
-//          b.addChangeListener(listener);\r
-//      }\r
-//  }\r
-//\r
-//  protected void installKeyboardActions(AbstractButton b){\r
-//      JSButtonListener listener = getButtonListener(b);\r
-//\r
-//      if(listener != null) {\r
-//          listener.installKeyboardActions(b);\r
-//      }\r
-//  }\r
-//\r
-//\r
-//  // ********************************\r
-//  //         Uninstall PLAF\r
-//  // ********************************\r
-//  public void uninstallUI(JComponent c) {\r
-//      uninstallKeyboardActions((AbstractButton) c);\r
-//      uninstallListeners((AbstractButton) c);\r
-//      uninstallDefaults((AbstractButton) c);\r
-//      BasicHTML.updateRenderer(c, "");\r
-//  }\r
-//\r
-//  protected void uninstallKeyboardActions(AbstractButton b) {\r
-//      JSButtonListener listener = getButtonListener(b);\r
-//      if(listener != null) {\r
-//          listener.uninstallKeyboardActions(b);\r
-//      }\r
-//  }\r
-//\r
-//  protected void uninstallListeners(AbstractButton b) {\r
-//      JSButtonListener listener = getButtonListener(b);\r
-//      if(listener != null) {\r
-//          b.removeMouseListener(listener);\r
-//          b.removeMouseMotionListener(listener);\r
-//          b.removeFocusListener(listener);\r
-//          b.removeChangeListener(listener);\r
-//          b.removePropertyChangeListener(listener);\r
-//      }\r
-//  }\r
-//\r
-//  protected void uninstallDefaults(AbstractButton b) {\r
-//      LookAndFeel.uninstallBorder(b);\r
-//  }\r
-//\r
-//  // ********************************\r
-//  //        Create Listeners\r
-//  // ********************************\r
-//  protected JSButtonListener createButtonListener(AbstractButton b) {\r
-//      return new JSButtonListener(b);\r
-//  }\r
-//\r
-//  public int getDefaultTextIconGap(AbstractButton b) {\r
-//      return defaultTextIconGap;\r
-//  }\r
-//\r
-//  /* These rectangles/insets are allocated once for all\r
-//   * ButtonUI.paint() calls.  Re-using rectangles rather than\r
-//   * allocating them in each paint call substantially reduced the time\r
-//   * it took paint to run.  Obviously, this method can't be re-entered.\r
-//   */\r
-//  private static Rectangle viewRect = new Rectangle();\r
-//  private static Rectangle textRect = new Rectangle();\r
-//  private static Rectangle iconRect = new Rectangle();\r
-//\r
-//  // ********************************\r
-//  //          Paint Methods\r
-//  // ********************************\r
-//\r
-//  public void paint(Graphics g, JComponent c)\r
-//  {\r
-//      AbstractButton b = (AbstractButton) c;\r
-//      ButtonModel model = b.getModel();\r
-//\r
-//      String text = layout(b, SwingUtilities2.getFontMetrics(b, g),\r
-//             b.getWidth(), b.getHeight());\r
-//\r
-//      clearTextShiftOffset();\r
-//\r
-//      // perform UI specific press action, e.g. Windows L&F shifts text\r
-//      if (model.isArmed() && model.isPressed()) {\r
-//          paintButtonPressed(g,b);\r
-//      }\r
-//\r
-//      // Paint the Icon\r
-//      if(b.getIcon() != null) {\r
-//          paintIcon(g,c,iconRect);\r
-//      }\r
-//\r
-//      if (text != null && !text.equals("")){\r
-//          View v = (View) c.getClientProperty(BasicHTML.propertyKey);\r
-//          if (v != null) {\r
-//              v.paint(g, textRect);\r
-//          } else {\r
-//              paintText(g, b, textRect, text);\r
-//          }\r
-//      }\r
-//\r
-//      if (b.isFocusPainted() && b.hasFocus()) {\r
-//          // paint UI specific focus\r
-//          paintFocus(g,b,viewRect,textRect,iconRect);\r
-//      }\r
-//  }\r
-//\r
-//  protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect){\r
-//          AbstractButton b = (AbstractButton) c;\r
-//          ButtonModel model = b.getModel();\r
-//          Icon icon = b.getIcon();\r
-//          Icon tmpIcon = null;\r
-//\r
-//          if(icon == null) {\r
-//             return;\r
-//          }\r
-//\r
-//          Icon selectedIcon = null;\r
-//\r
-//          /* the fallback icon should be based on the selected state */\r
-//          if (model.isSelected()) {\r
-//              selectedIcon = (Icon) b.getSelectedIcon();\r
-//              if (selectedIcon != null) {\r
-//                  icon = selectedIcon;\r
-//              }\r
-//          }\r
-//\r
-//          if(!model.isEnabled()) {\r
-//              if(model.isSelected()) {\r
-//                 tmpIcon = (Icon) b.getDisabledSelectedIcon();\r
-//                 if (tmpIcon == null) {\r
-//                     tmpIcon = selectedIcon;\r
-//                 }\r
-//              }\r
-//\r
-//              if (tmpIcon == null) {\r
-//                  tmpIcon = (Icon) b.getDisabledIcon();\r
-//              }\r
-//          } else if(model.isPressed() && model.isArmed()) {\r
-//              tmpIcon = (Icon) b.getPressedIcon();\r
-//              if(tmpIcon != null) {\r
-//                  // revert back to 0 offset\r
-//                  clearTextShiftOffset();\r
-//              }\r
-//          } else if(b.isRolloverEnabled() && model.isRollover()) {\r
-//              if(model.isSelected()) {\r
-//                 tmpIcon = (Icon) b.getRolloverSelectedIcon();\r
-//                 if (tmpIcon == null) {\r
-//                     tmpIcon = selectedIcon;\r
-//                 }\r
-//              }\r
-//\r
-//              if (tmpIcon == null) {\r
-//                  tmpIcon = (Icon) b.getRolloverIcon();\r
-//              }\r
-//          }\r
-//\r
-//          if(tmpIcon != null) {\r
-//              icon = tmpIcon;\r
-//          }\r
-//\r
-//          if(model.isPressed() && model.isArmed()) {\r
-//              icon.paintIcon(c, g, iconRect.x + getTextShiftOffset(),\r
-//                      iconRect.y + getTextShiftOffset());\r
-//          } else {\r
-//              icon.paintIcon(c, g, iconRect.x, iconRect.y);\r
-//          }\r
-//\r
-//  }\r
-//\r
-//  /**\r
-//   * As of Java 2 platform v 1.4 this method should not be used or overriden.\r
-//   * Use the paintText method which takes the AbstractButton argument.\r
-//   */\r
-//  protected void paintText(Graphics g, JComponent c, Rectangle textRect, String text) {\r
-//      AbstractButton b = (AbstractButton) c;\r
-//      ButtonModel model = b.getModel();\r
-//      FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);\r
-//      int mnemonicIndex = b.getDisplayedMnemonicIndex();\r
-//\r
-//      /* Draw the Text */\r
-//      if(model.isEnabled()) {\r
-//          /*** paint the text normally */\r
-//          g.setColor(b.getForeground());\r
-//          SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,\r
-//                                        textRect.x + getTextShiftOffset(),\r
-//                                        textRect.y + fm.getAscent() + getTextShiftOffset());\r
-//      }\r
-//      else {\r
-//          /*** paint the text disabled ***/\r
-//          g.setColor(b.getBackground().brighter());\r
-//          SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,\r
-//                                        textRect.x, textRect.y + fm.getAscent());\r
-//          g.setColor(b.getBackground().darker());\r
-//          SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,\r
-//                                        textRect.x - 1, textRect.y + fm.getAscent() - 1);\r
-//      }\r
-//  }\r
-//\r
-//  /**\r
-//   * Method which renders the text of the current button.\r
-//   * <p>\r
-//   * @param g Graphics context\r
-//   * @param b Current button to render\r
-//   * @param textRect Bounding rectangle to render the text.\r
-//   * @param text String to render\r
-//   * @since 1.4\r
-//   */\r
-//  protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) {\r
-//      paintText(g, (JComponent)b, textRect, text);\r
-//  }\r
-//\r
-//  // Method signature defined here overriden in subclasses.\r
-//  // Perhaps this class should be abstract?\r
-//  protected void paintFocus(Graphics g, AbstractButton b,\r
-//                            Rectangle viewRect, Rectangle textRect, Rectangle iconRect){\r
-//  }\r
-//\r
-//\r
-//\r
-//  protected void paintButtonPressed(Graphics g, AbstractButton b){\r
-//  }\r
-//\r
-//  protected void clearTextShiftOffset(){\r
-//      this.shiftOffset = 0;\r
-//  }\r
-//\r
-//  protected void setTextShiftOffset(){\r
-//      this.shiftOffset = defaultTextShiftOffset;\r
-//  }\r
-//\r
-//  protected int getTextShiftOffset() {\r
-//      return shiftOffset;\r
-//  }\r
-//\r
-//  // ********************************\r
-//  //          Layout Methods\r
-//  // ********************************\r
-//  public Dimension getMinimumSize(JComponent c) {\r
-//      Dimension d = getPreferredSize(c);\r
-//      View v = (View) c.getClientProperty(BasicHTML.propertyKey);\r
-//      if (v != null) {\r
-//          d.width -= v.getPreferredSpan(View.X_AXIS) - v.getMinimumSpan(View.X_AXIS);\r
-//      }\r
-//      return d;\r
-//  }\r
-//\r
-//  public Dimension getPreferredSize(JComponent c) {\r
-//      AbstractButton b = (AbstractButton)c;\r
-//      return BasicGraphicsUtils.getPreferredButtonSize(b, b.getIconTextGap());\r
-//  }\r
-//\r
-//  public Dimension getMaximumSize(JComponent c) {\r
-//      Dimension d = getPreferredSize(c);\r
-//      View v = (View) c.getClientProperty(BasicHTML.propertyKey);\r
-//      if (v != null) {\r
-//          d.width += v.getMaximumSpan(View.X_AXIS) - v.getPreferredSpan(View.X_AXIS);\r
-//      }\r
-//      return d;\r
-//  }\r
-//\r
-//  /**\r
-//   * Returns the baseline.\r
-//   *\r
-//   * @throws NullPointerException {@inheritDoc}\r
-//   * @throws IllegalArgumentException {@inheritDoc}\r
-//   * @see javax.swing.JComponent#getBaseline(int, int)\r
-//   * @since 1.6\r
-//   */\r
-//  public int getBaseline(JComponent c, int width, int height) {\r
-//      super.getBaseline(c, width, height);\r
-//      AbstractButton b = (AbstractButton)c;\r
-//      String text = b.getText();\r
-//      if (text == null || "".equals(text)) {\r
-//          return -1;\r
-//      }\r
-//      FontMetrics fm = b.getFontMetrics(b.getFont());\r
-//      layout(b, fm, width, height);\r
-//      return BasicHTML.getBaseline(b, textRect.y, fm.getAscent(),\r
-//                                   textRect.width, textRect.height);\r
-//  }\r
-//\r
-//  /**\r
-//   * Returns an enum indicating how the baseline of the component\r
-//   * changes as the size changes.\r
-//   *\r
-//   * @throws NullPointerException {@inheritDoc}\r
-//   * @see javax.swing.JComponent#getBaseline(int, int)\r
-//   * @since 1.6\r
-//   */\r
-//  public Component.BaselineResizeBehavior getBaselineResizeBehavior(\r
-//          JComponent c) {\r
-//      super.getBaselineResizeBehavior(c);\r
-//      if (c.getClientProperty(BasicHTML.propertyKey) != null) {\r
-//          return Component.BaselineResizeBehavior.OTHER;\r
-//      }\r
-//      switch(((AbstractButton)c).getVerticalAlignment()) {\r
-//      case AbstractButton.TOP:\r
-//          return Component.BaselineResizeBehavior.CONSTANT_ASCENT;\r
-//      case AbstractButton.BOTTOM:\r
-//          return Component.BaselineResizeBehavior.CONSTANT_DESCENT;\r
-//      case AbstractButton.CENTER:\r
-//          return Component.BaselineResizeBehavior.CENTER_OFFSET;\r
-//      }\r
-//      return Component.BaselineResizeBehavior.OTHER;\r
-//  }\r
-//\r
-//  private String layout(AbstractButton b, FontMetrics fm,\r
-//                        int width, int height) {\r
-//      Insets i = b.getInsets();\r
-//      viewRect.x = i.left;\r
-//      viewRect.y = i.top;\r
-//      viewRect.width = width - (i.right + viewRect.x);\r
-//      viewRect.height = height - (i.bottom + viewRect.y);\r
-//\r
-//      textRect.x = textRect.y = textRect.width = textRect.height = 0;\r
-//      iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;\r
-//\r
-//      // layout the text and icon\r
-//      return SwingUtilities.layoutCompoundLabel(\r
-//          b, fm, b.getText(), b.getIcon(),\r
-//          b.getVerticalAlignment(), b.getHorizontalAlignment(),\r
-//          b.getVerticalTextPosition(), b.getHorizontalTextPosition(),\r
-//          viewRect, iconRect, textRect,\r
-//          b.getText() == null ? 0 : b.getIconTextGap());\r
-//  }\r
-//\r
-//  /**\r
-//   * Returns the ButtonListener for the passed in Button, or null if one\r
-//   * could not be found.\r
-//   */\r
-//  private JSButtonListener getButtonListener(AbstractButton b) {\r
-//      MouseMotionListener[] listeners = b.getMouseMotionListeners();\r
-//\r
-//      if (listeners != null) {\r
-//          for (int counter = 0; counter < listeners.length; counter++) {\r
-//              if (listeners[counter] instanceof JSButtonListener) {\r
-//                  return (JSButtonListener)listeners[counter];\r
-//              }\r
-//          }\r
-//      }\r
-//      return null;\r
-//  }\r
-//\r
-//\r
-\r
-}\r
+package swingjs.plaf;
+
+//import jsjava.awt.FontMetrics;
+import jsjava.awt.event.MouseMotionListener;
+import jsjavax.swing.AbstractButton;
+import jsjavax.swing.LookAndFeel;
+import jsjavax.swing.UIManager;
+import swingjs.api.DOMNode;
+import jsjavax.swing.plaf.UIResource;
+/**
+ * SWingJS implementation of stateful user interface for buttons. 
+ * Modeled after javax.swing.plaf.basic.BasicButtonUI.java (commented out below).
+ * 
+ * @author Bob Hanson
+ *
+ */
+public class JSButtonUI extends JSComponentUI {
+
+       
+       /**
+        * the radio or check-box or simple button
+        * 
+        */
+       protected DOMNode domBtn;
+
+       @Override
+       public DOMNode getDOMObject() {
+               if (domNode == null)
+                       domBtn = enableNode = valueNode = domNode = createDOMObject("input", id,
+                                       "type", "button");
+               setCssFont(DOMNode.setAttr(domNode, "value", ((AbstractButton) c).getText()),
+                               c.getFont());
+               return domNode;
+       }
+
+       /**
+        * validate a button press -- with a simple button, this is just TRUE.
+        * This is needed because sometimes the area near the button is pressed
+        * but not the actual button.
+        * @param isRelease TODO
+        * 
+        * @return true if the HTML5 button was actually pressed
+        */
+  boolean verifyButtonClick(boolean isRelease) {
+               return true;
+       }
+
+
+       // from BasicButtonUI
+       
+       protected void installJSUI() {
+               installDefaults((AbstractButton) c);
+               installListeners((AbstractButton) c);
+               installKeyboardActions((AbstractButton) c);
+       }
+  
+       protected void uninstallJSUI() {
+               uninstallKeyboardActions((AbstractButton) c);
+               uninstallListeners((AbstractButton) c);
+               //uninstallDefaults((AbstractButton) c);
+       }
+       
+       protected void installListeners(AbstractButton b) {
+               JSButtonListener listener = new JSButtonListener(b);
+               if (listener != null) {
+                       b.addMouseListener(listener);
+                       b.addMouseMotionListener(listener);
+                       b.addFocusListener(listener);
+      b.addPropertyChangeListener(listener);
+                       b.addChangeListener(listener);
+               }
+       }
+
+       protected void uninstallListeners(AbstractButton b) {
+               JSButtonListener listener = getButtonListener(b);
+               if (listener != null) {
+                       b.removeMouseListener(listener);
+                       b.removeMouseMotionListener(listener);
+                       b.removeFocusListener(listener);
+                       b.removeChangeListener(listener);
+                       b.removePropertyChangeListener(listener);
+               }
+       }
+
+       protected void installKeyboardActions(AbstractButton b) {
+               JSButtonListener listener = getButtonListener(b);
+               if (listener != null) {
+                       listener.installKeyboardActions(b);
+               }
+       }
+       
+  protected void uninstallKeyboardActions(AbstractButton b) {
+      JSButtonListener listener = getButtonListener(b);
+      if(listener != null) {
+          listener.uninstallKeyboardActions(b);
+      }
+  }
+
+  /**
+   * Returns the ButtonListener for the passed in Button, or null if one
+   * could not be found.
+   */
+  protected JSButtonListener getButtonListener(AbstractButton b) {
+      MouseMotionListener[] listeners = b.getMouseMotionListeners();
+
+      if (listeners != null) {
+          for (int counter = 0; counter < listeners.length; counter++) {
+              if (listeners[counter] instanceof JSButtonListener) {
+                  return (JSButtonListener)listeners[counter];
+              }
+          }
+      }
+      return null;
+  }
+
+  // SwingJS -- this is interesting, as it summarizes everything we will need
+  // to implement, ultimately. SwingUtilities.layoutCompoundLabel
+  // details what we are going to have to do somewhere. 
+  
+//     private String layout(AbstractButton b, FontMetrics fm, int width, int height) {
+//             Insets i = b.getInsets();
+//             viewRect.x = i.left;
+//             viewRect.y = i.top;
+//             viewRect.width = width - (i.right + viewRect.x);
+//             viewRect.height = height - (i.bottom + viewRect.y);
+//
+//             textRect.x = textRect.y = textRect.width = textRect.height = 0;
+//             iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
+//
+//             // layout the text and icon
+//             return SwingUtilities.layoutCompoundLabel(b, fm, b.getText(), b.getIcon(),
+//                             b.getVerticalAlignment(), b.getHorizontalAlignment(),
+//                             b.getVerticalTextPosition(), b.getHorizontalTextPosition(), viewRect,
+//                             iconRect, textRect, b.getText() == null ? 0 : b.getIconTextGap());
+//             return null;
+//     }
+
+
+//  // Visual constants
+//  // NOTE: This is not used or set any where. Were we allowed to remove
+//  // fields, this would be removed.
+//  protected int defaultTextIconGap;
+//
+  /** Amount to offset text, the value of this comes from
+   defaultTextShiftOffset once setTextShiftOffset has been invoked.
+   */
+  protected int shiftOffset = 0;
+       
+  /** Value that is set in shiftOffset once setTextShiftOffset has been
+   invoked. The value of this comes from the defaults table.
+   */
+  protected int defaultTextShiftOffset;
+//
+//protected String propertyPrefix = "Button.";
+//  
+//  private static final Object BASIC_BUTTON_UI_KEY = new Object();
+//
+//  // ********************************
+//  //          Create PLAF
+//  // ********************************
+//  public static ComponentUI createUI(JComponent c) {
+//      AppContext appContext = AppContext.getAppContext();
+//      BasicButtonUI buttonUI = 
+//              (BasicButtonUI) appContext.get(BASIC_BUTTON_UI_KEY);
+//      if (buttonUI == null) {
+//          buttonUI = new BasicButtonUI();
+//          appContext.put(BASIC_BUTTON_UI_KEY, buttonUI);
+//      }
+//      return buttonUI;
+//  }
+//
+  protected String getPropertyPrefix() {
+      return "Button.";
+  }
+//
+//
+//  // ********************************
+//  //          Install PLAF
+//  // ********************************
+//  public void installUI(JComponent c) {
+//      installDefaults((AbstractButton) c);
+//      installListeners((AbstractButton) c);
+//      installKeyboardActions((AbstractButton) c);
+//      BasicHTML.updateRenderer(c, ((AbstractButton) c).getText());
+//  }
+//
+  protected void installDefaults(AbstractButton b) {
+      // load shared instance defaults
+      String pp = getPropertyPrefix();
+
+      defaultTextShiftOffset = UIManager.getInt(pp + "textShiftOffset");
+
+//      // set the following defaults on the button
+//      if (b.isContentAreaFilled()) {
+//          LookAndFeel.installProperty(b, "opaque", Boolean.TRUE);
+//      } else {
+//          LookAndFeel.installProperty(b, "opaque", Boolean.FALSE);
+//      }
+
+      if(b.getMargin() == null || (b.getMargin() instanceof UIResource)) {
+          b.setMargin(UIManager.getInsets(pp + "margin"));
+      }
+
+      LookAndFeel.installColorsAndFont(b, pp + "background",
+                                       pp + "foreground", pp + "font");
+//      LookAndFeel.installBorder(b, pp + "border");
+//
+//      Object rollover = UIManager.get(pp + "rollover");
+//      if (rollover != null) {
+//          LookAndFeel.installProperty(b, "rolloverEnabled", rollover);
+//      }
+      LookAndFeel.installProperty(b, "iconTextGap", new Integer(4));
+  }
+//
+//  protected void installListeners(AbstractButton b) {
+//      JSButtonListener listener = createButtonListener(b);
+//      if(listener != null) {
+//          b.addMouseListener(listener);
+//          b.addMouseMotionListener(listener);
+//          b.addFocusListener(listener);
+//          b.addPropertyChangeListener(listener);
+//          b.addChangeListener(listener);
+//      }
+//  }
+//
+//  protected void installKeyboardActions(AbstractButton b){
+//      JSButtonListener listener = getButtonListener(b);
+//
+//      if(listener != null) {
+//          listener.installKeyboardActions(b);
+//      }
+//  }
+//
+//
+//  // ********************************
+//  //         Uninstall PLAF
+//  // ********************************
+//  public void uninstallUI(JComponent c) {
+//      uninstallKeyboardActions((AbstractButton) c);
+//      uninstallListeners((AbstractButton) c);
+//      uninstallDefaults((AbstractButton) c);
+//      BasicHTML.updateRenderer(c, "");
+//  }
+//
+//  protected void uninstallKeyboardActions(AbstractButton b) {
+//      JSButtonListener listener = getButtonListener(b);
+//      if(listener != null) {
+//          listener.uninstallKeyboardActions(b);
+//      }
+//  }
+//
+//  protected void uninstallListeners(AbstractButton b) {
+//      JSButtonListener listener = getButtonListener(b);
+//      if(listener != null) {
+//          b.removeMouseListener(listener);
+//          b.removeMouseMotionListener(listener);
+//          b.removeFocusListener(listener);
+//          b.removeChangeListener(listener);
+//          b.removePropertyChangeListener(listener);
+//      }
+//  }
+//
+//  protected void uninstallDefaults(AbstractButton b) {
+//      LookAndFeel.uninstallBorder(b);
+//  }
+//
+//  // ********************************
+//  //        Create Listeners
+//  // ********************************
+//  protected JSButtonListener createButtonListener(AbstractButton b) {
+//      return new JSButtonListener(b);
+//  }
+//
+//  public int getDefaultTextIconGap(AbstractButton b) {
+//      return defaultTextIconGap;
+//  }
+//
+//  /* These rectangles/insets are allocated once for all
+//   * ButtonUI.paint() calls.  Re-using rectangles rather than
+//   * allocating them in each paint call substantially reduced the time
+//   * it took paint to run.  Obviously, this method can't be re-entered.
+//   */
+//  private static Rectangle viewRect = new Rectangle();
+//  private static Rectangle textRect = new Rectangle();
+//  private static Rectangle iconRect = new Rectangle();
+//
+//  // ********************************
+//  //          Paint Methods
+//  // ********************************
+//
+//  public void paint(Graphics g, JComponent c)
+//  {
+//      AbstractButton b = (AbstractButton) c;
+//      ButtonModel model = b.getModel();
+//
+//      String text = layout(b, SwingUtilities2.getFontMetrics(b, g),
+//             b.getWidth(), b.getHeight());
+//
+//      clearTextShiftOffset();
+//
+//      // perform UI specific press action, e.g. Windows L&F shifts text
+//      if (model.isArmed() && model.isPressed()) {
+//          paintButtonPressed(g,b);
+//      }
+//
+//      // Paint the Icon
+//      if(b.getIcon() != null) {
+//          paintIcon(g,c,iconRect);
+//      }
+//
+//      if (text != null && !text.equals("")){
+//          View v = (View) c.getClientProperty(BasicHTML.propertyKey);
+//          if (v != null) {
+//              v.paint(g, textRect);
+//          } else {
+//              paintText(g, b, textRect, text);
+//          }
+//      }
+//
+//      if (b.isFocusPainted() && b.hasFocus()) {
+//          // paint UI specific focus
+//          paintFocus(g,b,viewRect,textRect,iconRect);
+//      }
+//  }
+//
+//  protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect){
+//          AbstractButton b = (AbstractButton) c;
+//          ButtonModel model = b.getModel();
+//          Icon icon = b.getIcon();
+//          Icon tmpIcon = null;
+//
+//          if(icon == null) {
+//             return;
+//          }
+//
+//          Icon selectedIcon = null;
+//
+//          /* the fallback icon should be based on the selected state */
+//          if (model.isSelected()) {
+//              selectedIcon = (Icon) b.getSelectedIcon();
+//              if (selectedIcon != null) {
+//                  icon = selectedIcon;
+//              }
+//          }
+//
+//          if(!model.isEnabled()) {
+//              if(model.isSelected()) {
+//                 tmpIcon = (Icon) b.getDisabledSelectedIcon();
+//                 if (tmpIcon == null) {
+//                     tmpIcon = selectedIcon;
+//                 }
+//              }
+//
+//              if (tmpIcon == null) {
+//                  tmpIcon = (Icon) b.getDisabledIcon();
+//              }
+//          } else if(model.isPressed() && model.isArmed()) {
+//              tmpIcon = (Icon) b.getPressedIcon();
+//              if(tmpIcon != null) {
+//                  // revert back to 0 offset
+//                  clearTextShiftOffset();
+//              }
+//          } else if(b.isRolloverEnabled() && model.isRollover()) {
+//              if(model.isSelected()) {
+//                 tmpIcon = (Icon) b.getRolloverSelectedIcon();
+//                 if (tmpIcon == null) {
+//                     tmpIcon = selectedIcon;
+//                 }
+//              }
+//
+//              if (tmpIcon == null) {
+//                  tmpIcon = (Icon) b.getRolloverIcon();
+//              }
+//          }
+//
+//          if(tmpIcon != null) {
+//              icon = tmpIcon;
+//          }
+//
+//          if(model.isPressed() && model.isArmed()) {
+//              icon.paintIcon(c, g, iconRect.x + getTextShiftOffset(),
+//                      iconRect.y + getTextShiftOffset());
+//          } else {
+//              icon.paintIcon(c, g, iconRect.x, iconRect.y);
+//          }
+//
+//  }
+//
+//  /**
+//   * As of Java 2 platform v 1.4 this method should not be used or overriden.
+//   * Use the paintText method which takes the AbstractButton argument.
+//   */
+//  protected void paintText(Graphics g, JComponent c, Rectangle textRect, String text) {
+//      AbstractButton b = (AbstractButton) c;
+//      ButtonModel model = b.getModel();
+//      FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);
+//      int mnemonicIndex = b.getDisplayedMnemonicIndex();
+//
+//      /* Draw the Text */
+//      if(model.isEnabled()) {
+//          /*** paint the text normally */
+//          g.setColor(b.getForeground());
+//          SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
+//                                        textRect.x + getTextShiftOffset(),
+//                                        textRect.y + fm.getAscent() + getTextShiftOffset());
+//      }
+//      else {
+//          /*** paint the text disabled ***/
+//          g.setColor(b.getBackground().brighter());
+//          SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
+//                                        textRect.x, textRect.y + fm.getAscent());
+//          g.setColor(b.getBackground().darker());
+//          SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
+//                                        textRect.x - 1, textRect.y + fm.getAscent() - 1);
+//      }
+//  }
+//
+//  /**
+//   * Method which renders the text of the current button.
+//   * <p>
+//   * @param g Graphics context
+//   * @param b Current button to render
+//   * @param textRect Bounding rectangle to render the text.
+//   * @param text String to render
+//   * @since 1.4
+//   */
+//  protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) {
+//      paintText(g, (JComponent)b, textRect, text);
+//  }
+//
+//  // Method signature defined here overriden in subclasses.
+//  // Perhaps this class should be abstract?
+//  protected void paintFocus(Graphics g, AbstractButton b,
+//                            Rectangle viewRect, Rectangle textRect, Rectangle iconRect){
+//  }
+//
+//
+//
+//  protected void paintButtonPressed(Graphics g, AbstractButton b){
+//  }
+//
+//  protected void clearTextShiftOffset(){
+//      this.shiftOffset = 0;
+//  }
+//
+//  protected void setTextShiftOffset(){
+//      this.shiftOffset = defaultTextShiftOffset;
+//  }
+//
+//  protected int getTextShiftOffset() {
+//      return shiftOffset;
+//  }
+//
+//  // ********************************
+//  //          Layout Methods
+//  // ********************************
+//  public Dimension getMinimumSize(JComponent c) {
+//      Dimension d = getPreferredSize(c);
+//      View v = (View) c.getClientProperty(BasicHTML.propertyKey);
+//      if (v != null) {
+//          d.width -= v.getPreferredSpan(View.X_AXIS) - v.getMinimumSpan(View.X_AXIS);
+//      }
+//      return d;
+//  }
+//
+//  public Dimension getPreferredSize(JComponent c) {
+//      AbstractButton b = (AbstractButton)c;
+//      return BasicGraphicsUtils.getPreferredButtonSize(b, b.getIconTextGap());
+//  }
+//
+//  public Dimension getMaximumSize(JComponent c) {
+//      Dimension d = getPreferredSize(c);
+//      View v = (View) c.getClientProperty(BasicHTML.propertyKey);
+//      if (v != null) {
+//          d.width += v.getMaximumSpan(View.X_AXIS) - v.getPreferredSpan(View.X_AXIS);
+//      }
+//      return d;
+//  }
+//
+//  /**
+//   * Returns the baseline.
+//   *
+//   * @throws NullPointerException {@inheritDoc}
+//   * @throws IllegalArgumentException {@inheritDoc}
+//   * @see javax.swing.JComponent#getBaseline(int, int)
+//   * @since 1.6
+//   */
+//  public int getBaseline(JComponent c, int width, int height) {
+//      super.getBaseline(c, width, height);
+//      AbstractButton b = (AbstractButton)c;
+//      String text = b.getText();
+//      if (text == null || "".equals(text)) {
+//          return -1;
+//      }
+//      FontMetrics fm = b.getFontMetrics(b.getFont());
+//      layout(b, fm, width, height);
+//      return BasicHTML.getBaseline(b, textRect.y, fm.getAscent(),
+//                                   textRect.width, textRect.height);
+//  }
+//
+//  /**
+//   * Returns an enum indicating how the baseline of the component
+//   * changes as the size changes.
+//   *
+//   * @throws NullPointerException {@inheritDoc}
+//   * @see javax.swing.JComponent#getBaseline(int, int)
+//   * @since 1.6
+//   */
+//  public Component.BaselineResizeBehavior getBaselineResizeBehavior(
+//          JComponent c) {
+//      super.getBaselineResizeBehavior(c);
+//      if (c.getClientProperty(BasicHTML.propertyKey) != null) {
+//          return Component.BaselineResizeBehavior.OTHER;
+//      }
+//      switch(((AbstractButton)c).getVerticalAlignment()) {
+//      case AbstractButton.TOP:
+//          return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
+//      case AbstractButton.BOTTOM:
+//          return Component.BaselineResizeBehavior.CONSTANT_DESCENT;
+//      case AbstractButton.CENTER:
+//          return Component.BaselineResizeBehavior.CENTER_OFFSET;
+//      }
+//      return Component.BaselineResizeBehavior.OTHER;
+//  }
+//
+//  private String layout(AbstractButton b, FontMetrics fm,
+//                        int width, int height) {
+//      Insets i = b.getInsets();
+//      viewRect.x = i.left;
+//      viewRect.y = i.top;
+//      viewRect.width = width - (i.right + viewRect.x);
+//      viewRect.height = height - (i.bottom + viewRect.y);
+//
+//      textRect.x = textRect.y = textRect.width = textRect.height = 0;
+//      iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
+//
+//      // layout the text and icon
+//      return SwingUtilities.layoutCompoundLabel(
+//          b, fm, b.getText(), b.getIcon(),
+//          b.getVerticalAlignment(), b.getHorizontalAlignment(),
+//          b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
+//          viewRect, iconRect, textRect,
+//          b.getText() == null ? 0 : b.getIconTextGap());
+//  }
+//
+//  /**
+//   * Returns the ButtonListener for the passed in Button, or null if one
+//   * could not be found.
+//   */
+//  private JSButtonListener getButtonListener(AbstractButton b) {
+//      MouseMotionListener[] listeners = b.getMouseMotionListeners();
+//
+//      if (listeners != null) {
+//          for (int counter = 0; counter < listeners.length; counter++) {
+//              if (listeners[counter] instanceof JSButtonListener) {
+//                  return (JSButtonListener)listeners[counter];
+//              }
+//          }
+//      }
+//      return null;
+//  }
+//
+//
+
+}