3 //import jsjava.awt.FontMetrics;
4 import jsjava.awt.event.MouseMotionListener;
5 import jsjavax.swing.AbstractButton;
6 import jsjavax.swing.LookAndFeel;
7 import jsjavax.swing.UIManager;
8 import swingjs.api.DOMNode;
9 import jsjavax.swing.plaf.UIResource;
11 * SWingJS implementation of stateful user interface for buttons.
12 * Modeled after javax.swing.plaf.basic.BasicButtonUI.java (commented out below).
17 public class JSMenuItemUI extends JSButtonUI {
21 * the radio or check-box or simple button
24 protected DOMNode domBtn;
27 public DOMNode getDOMObject() {
29 domBtn = enableNode = valueNode = domNode = createDOMObject("input", id,
31 setCssFont(DOMNode.setAttr(domNode, "value", ((AbstractButton) c).getText()),
37 * validate a button press -- with a simple button, this is just TRUE.
38 * This is needed because sometimes the area near the button is pressed
39 * but not the actual button.
40 * @param isRelease TODO
42 * @return true if the HTML5 button was actually pressed
44 boolean verifyButtonClick(boolean isRelease) {
51 protected void installJSUI() {
52 installDefaults((AbstractButton) c);
53 installListeners((AbstractButton) c);
54 installKeyboardActions((AbstractButton) c);
57 protected void uninstallJSUI() {
58 uninstallKeyboardActions((AbstractButton) c);
59 uninstallListeners((AbstractButton) c);
60 //uninstallDefaults((AbstractButton) c);
63 protected void installListeners(AbstractButton b) {
64 JSButtonListener listener = new JSButtonListener(b);
65 if (listener != null) {
66 b.addMouseListener(listener);
67 b.addMouseMotionListener(listener);
68 b.addFocusListener(listener);
69 b.addPropertyChangeListener(listener);
70 b.addChangeListener(listener);
74 protected void uninstallListeners(AbstractButton b) {
75 JSButtonListener listener = getButtonListener(b);
76 if (listener != null) {
77 b.removeMouseListener(listener);
78 b.removeMouseMotionListener(listener);
79 b.removeFocusListener(listener);
80 b.removeChangeListener(listener);
81 b.removePropertyChangeListener(listener);
85 protected void installKeyboardActions(AbstractButton b) {
86 JSButtonListener listener = getButtonListener(b);
87 if (listener != null) {
88 listener.installKeyboardActions(b);
92 protected void uninstallKeyboardActions(AbstractButton b) {
93 JSButtonListener listener = getButtonListener(b);
94 if(listener != null) {
95 listener.uninstallKeyboardActions(b);
99 // SwingJS -- this is interesting, as it summarizes everything we will need
100 // to implement, ultimately. SwingUtilities.layoutCompoundLabel
101 // details what we are going to have to do somewhere.
103 // private String layout(AbstractButton b, FontMetrics fm, int width, int height) {
104 // Insets i = b.getInsets();
105 // viewRect.x = i.left;
106 // viewRect.y = i.top;
107 // viewRect.width = width - (i.right + viewRect.x);
108 // viewRect.height = height - (i.bottom + viewRect.y);
110 // textRect.x = textRect.y = textRect.width = textRect.height = 0;
111 // iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
113 // // layout the text and icon
114 // return SwingUtilities.layoutCompoundLabel(b, fm, b.getText(), b.getIcon(),
115 // b.getVerticalAlignment(), b.getHorizontalAlignment(),
116 // b.getVerticalTextPosition(), b.getHorizontalTextPosition(), viewRect,
117 // iconRect, textRect, b.getText() == null ? 0 : b.getIconTextGap());
122 // // Visual constants
123 // // NOTE: This is not used or set any where. Were we allowed to remove
124 // // fields, this would be removed.
125 // protected int defaultTextIconGap;
127 /** Amount to offset text, the value of this comes from
128 defaultTextShiftOffset once setTextShiftOffset has been invoked.
130 protected int shiftOffset = 0;
132 /** Value that is set in shiftOffset once setTextShiftOffset has been
133 invoked. The value of this comes from the defaults table.
135 protected int defaultTextShiftOffset;
137 //protected String propertyPrefix = "Button.";
139 // private static final Object BASIC_BUTTON_UI_KEY = new Object();
141 // // ********************************
143 // // ********************************
144 // public static ComponentUI createUI(JComponent c) {
145 // AppContext appContext = AppContext.getAppContext();
146 // BasicButtonUI buttonUI =
147 // (BasicButtonUI) appContext.get(BASIC_BUTTON_UI_KEY);
148 // if (buttonUI == null) {
149 // buttonUI = new BasicButtonUI();
150 // appContext.put(BASIC_BUTTON_UI_KEY, buttonUI);
155 protected String getPropertyPrefix() {
160 // // ********************************
162 // // ********************************
163 // public void installUI(JComponent c) {
164 // installDefaults((AbstractButton) c);
165 // installListeners((AbstractButton) c);
166 // installKeyboardActions((AbstractButton) c);
167 // BasicHTML.updateRenderer(c, ((AbstractButton) c).getText());
170 protected void installDefaults(AbstractButton b) {
171 // load shared instance defaults
172 String pp = getPropertyPrefix();
174 defaultTextShiftOffset = UIManager.getInt(pp + "textShiftOffset");
176 // // set the following defaults on the button
177 // if (b.isContentAreaFilled()) {
178 // LookAndFeel.installProperty(b, "opaque", Boolean.TRUE);
180 // LookAndFeel.installProperty(b, "opaque", Boolean.FALSE);
183 if(b.getMargin() == null || (b.getMargin() instanceof UIResource)) {
184 b.setMargin(UIManager.getInsets(pp + "margin"));
187 LookAndFeel.installColorsAndFont(b, pp + "background",
188 pp + "foreground", pp + "font");
189 // LookAndFeel.installBorder(b, pp + "border");
191 // Object rollover = UIManager.get(pp + "rollover");
192 // if (rollover != null) {
193 // LookAndFeel.installProperty(b, "rolloverEnabled", rollover);
195 LookAndFeel.installProperty(b, "iconTextGap", new Integer(4));
198 // protected void installListeners(AbstractButton b) {
199 // JSButtonListener listener = createButtonListener(b);
200 // if(listener != null) {
201 // b.addMouseListener(listener);
202 // b.addMouseMotionListener(listener);
203 // b.addFocusListener(listener);
204 // b.addPropertyChangeListener(listener);
205 // b.addChangeListener(listener);
209 // protected void installKeyboardActions(AbstractButton b){
210 // JSButtonListener listener = getButtonListener(b);
212 // if(listener != null) {
213 // listener.installKeyboardActions(b);
218 // // ********************************
220 // // ********************************
221 // public void uninstallUI(JComponent c) {
222 // uninstallKeyboardActions((AbstractButton) c);
223 // uninstallListeners((AbstractButton) c);
224 // uninstallDefaults((AbstractButton) c);
225 // BasicHTML.updateRenderer(c, "");
228 // protected void uninstallKeyboardActions(AbstractButton b) {
229 // JSButtonListener listener = getButtonListener(b);
230 // if(listener != null) {
231 // listener.uninstallKeyboardActions(b);
235 // protected void uninstallListeners(AbstractButton b) {
236 // JSButtonListener listener = getButtonListener(b);
237 // if(listener != null) {
238 // b.removeMouseListener(listener);
239 // b.removeMouseMotionListener(listener);
240 // b.removeFocusListener(listener);
241 // b.removeChangeListener(listener);
242 // b.removePropertyChangeListener(listener);
246 // protected void uninstallDefaults(AbstractButton b) {
247 // LookAndFeel.uninstallBorder(b);
250 // // ********************************
251 // // Create Listeners
252 // // ********************************
253 // protected JSButtonListener createButtonListener(AbstractButton b) {
254 // return new JSButtonListener(b);
257 // public int getDefaultTextIconGap(AbstractButton b) {
258 // return defaultTextIconGap;
261 // /* These rectangles/insets are allocated once for all
262 // * ButtonUI.paint() calls. Re-using rectangles rather than
263 // * allocating them in each paint call substantially reduced the time
264 // * it took paint to run. Obviously, this method can't be re-entered.
266 // private static Rectangle viewRect = new Rectangle();
267 // private static Rectangle textRect = new Rectangle();
268 // private static Rectangle iconRect = new Rectangle();
270 // // ********************************
272 // // ********************************
274 // public void paint(Graphics g, JComponent c)
276 // AbstractButton b = (AbstractButton) c;
277 // ButtonModel model = b.getModel();
279 // String text = layout(b, SwingUtilities2.getFontMetrics(b, g),
280 // b.getWidth(), b.getHeight());
282 // clearTextShiftOffset();
284 // // perform UI specific press action, e.g. Windows L&F shifts text
285 // if (model.isArmed() && model.isPressed()) {
286 // paintButtonPressed(g,b);
290 // if(b.getIcon() != null) {
291 // paintIcon(g,c,iconRect);
294 // if (text != null && !text.equals("")){
295 // View v = (View) c.getClientProperty(BasicHTML.propertyKey);
297 // v.paint(g, textRect);
299 // paintText(g, b, textRect, text);
303 // if (b.isFocusPainted() && b.hasFocus()) {
304 // // paint UI specific focus
305 // paintFocus(g,b,viewRect,textRect,iconRect);
309 // protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect){
310 // AbstractButton b = (AbstractButton) c;
311 // ButtonModel model = b.getModel();
312 // Icon icon = b.getIcon();
313 // Icon tmpIcon = null;
315 // if(icon == null) {
319 // Icon selectedIcon = null;
321 // /* the fallback icon should be based on the selected state */
322 // if (model.isSelected()) {
323 // selectedIcon = (Icon) b.getSelectedIcon();
324 // if (selectedIcon != null) {
325 // icon = selectedIcon;
329 // if(!model.isEnabled()) {
330 // if(model.isSelected()) {
331 // tmpIcon = (Icon) b.getDisabledSelectedIcon();
332 // if (tmpIcon == null) {
333 // tmpIcon = selectedIcon;
337 // if (tmpIcon == null) {
338 // tmpIcon = (Icon) b.getDisabledIcon();
340 // } else if(model.isPressed() && model.isArmed()) {
341 // tmpIcon = (Icon) b.getPressedIcon();
342 // if(tmpIcon != null) {
343 // // revert back to 0 offset
344 // clearTextShiftOffset();
346 // } else if(b.isRolloverEnabled() && model.isRollover()) {
347 // if(model.isSelected()) {
348 // tmpIcon = (Icon) b.getRolloverSelectedIcon();
349 // if (tmpIcon == null) {
350 // tmpIcon = selectedIcon;
354 // if (tmpIcon == null) {
355 // tmpIcon = (Icon) b.getRolloverIcon();
359 // if(tmpIcon != null) {
363 // if(model.isPressed() && model.isArmed()) {
364 // icon.paintIcon(c, g, iconRect.x + getTextShiftOffset(),
365 // iconRect.y + getTextShiftOffset());
367 // icon.paintIcon(c, g, iconRect.x, iconRect.y);
373 // * As of Java 2 platform v 1.4 this method should not be used or overriden.
374 // * Use the paintText method which takes the AbstractButton argument.
376 // protected void paintText(Graphics g, JComponent c, Rectangle textRect, String text) {
377 // AbstractButton b = (AbstractButton) c;
378 // ButtonModel model = b.getModel();
379 // FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);
380 // int mnemonicIndex = b.getDisplayedMnemonicIndex();
382 // /* Draw the Text */
383 // if(model.isEnabled()) {
384 // /*** paint the text normally */
385 // g.setColor(b.getForeground());
386 // SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
387 // textRect.x + getTextShiftOffset(),
388 // textRect.y + fm.getAscent() + getTextShiftOffset());
391 // /*** paint the text disabled ***/
392 // g.setColor(b.getBackground().brighter());
393 // SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
394 // textRect.x, textRect.y + fm.getAscent());
395 // g.setColor(b.getBackground().darker());
396 // SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,
397 // textRect.x - 1, textRect.y + fm.getAscent() - 1);
402 // * Method which renders the text of the current button.
404 // * @param g Graphics context
405 // * @param b Current button to render
406 // * @param textRect Bounding rectangle to render the text.
407 // * @param text String to render
410 // protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) {
411 // paintText(g, (JComponent)b, textRect, text);
414 // // Method signature defined here overriden in subclasses.
415 // // Perhaps this class should be abstract?
416 // protected void paintFocus(Graphics g, AbstractButton b,
417 // Rectangle viewRect, Rectangle textRect, Rectangle iconRect){
422 // protected void paintButtonPressed(Graphics g, AbstractButton b){
425 // protected void clearTextShiftOffset(){
426 // this.shiftOffset = 0;
429 // protected void setTextShiftOffset(){
430 // this.shiftOffset = defaultTextShiftOffset;
433 // protected int getTextShiftOffset() {
434 // return shiftOffset;
437 // // ********************************
439 // // ********************************
440 // public Dimension getMinimumSize(JComponent c) {
441 // Dimension d = getPreferredSize(c);
442 // View v = (View) c.getClientProperty(BasicHTML.propertyKey);
444 // d.width -= v.getPreferredSpan(View.X_AXIS) - v.getMinimumSpan(View.X_AXIS);
449 // public Dimension getPreferredSize(JComponent c) {
450 // AbstractButton b = (AbstractButton)c;
451 // return BasicGraphicsUtils.getPreferredButtonSize(b, b.getIconTextGap());
454 // public Dimension getMaximumSize(JComponent c) {
455 // Dimension d = getPreferredSize(c);
456 // View v = (View) c.getClientProperty(BasicHTML.propertyKey);
458 // d.width += v.getMaximumSpan(View.X_AXIS) - v.getPreferredSpan(View.X_AXIS);
464 // * Returns the baseline.
466 // * @throws NullPointerException {@inheritDoc}
467 // * @throws IllegalArgumentException {@inheritDoc}
468 // * @see javax.swing.JComponent#getBaseline(int, int)
471 // public int getBaseline(JComponent c, int width, int height) {
472 // super.getBaseline(c, width, height);
473 // AbstractButton b = (AbstractButton)c;
474 // String text = b.getText();
475 // if (text == null || "".equals(text)) {
478 // FontMetrics fm = b.getFontMetrics(b.getFont());
479 // layout(b, fm, width, height);
480 // return BasicHTML.getBaseline(b, textRect.y, fm.getAscent(),
481 // textRect.width, textRect.height);
485 // * Returns an enum indicating how the baseline of the component
486 // * changes as the size changes.
488 // * @throws NullPointerException {@inheritDoc}
489 // * @see javax.swing.JComponent#getBaseline(int, int)
492 // public Component.BaselineResizeBehavior getBaselineResizeBehavior(
494 // super.getBaselineResizeBehavior(c);
495 // if (c.getClientProperty(BasicHTML.propertyKey) != null) {
496 // return Component.BaselineResizeBehavior.OTHER;
498 // switch(((AbstractButton)c).getVerticalAlignment()) {
499 // case AbstractButton.TOP:
500 // return Component.BaselineResizeBehavior.CONSTANT_ASCENT;
501 // case AbstractButton.BOTTOM:
502 // return Component.BaselineResizeBehavior.CONSTANT_DESCENT;
503 // case AbstractButton.CENTER:
504 // return Component.BaselineResizeBehavior.CENTER_OFFSET;
506 // return Component.BaselineResizeBehavior.OTHER;
509 // private String layout(AbstractButton b, FontMetrics fm,
510 // int width, int height) {
511 // Insets i = b.getInsets();
512 // viewRect.x = i.left;
513 // viewRect.y = i.top;
514 // viewRect.width = width - (i.right + viewRect.x);
515 // viewRect.height = height - (i.bottom + viewRect.y);
517 // textRect.x = textRect.y = textRect.width = textRect.height = 0;
518 // iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
520 // // layout the text and icon
521 // return SwingUtilities.layoutCompoundLabel(
522 // b, fm, b.getText(), b.getIcon(),
523 // b.getVerticalAlignment(), b.getHorizontalAlignment(),
524 // b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
525 // viewRect, iconRect, textRect,
526 // b.getText() == null ? 0 : b.getIconTextGap());
530 // * Returns the ButtonListener for the passed in Button, or null if one
531 // * could not be found.
533 // private JSButtonListener getButtonListener(AbstractButton b) {
534 // MouseMotionListener[] listeners = b.getMouseMotionListeners();
536 // if (listeners != null) {
537 // for (int counter = 0; counter < listeners.length; counter++) {
538 // if (listeners[counter] instanceof JSButtonListener) {
539 // return (JSButtonListener)listeners[counter];