Package org.pushingpixels.substance.internal.ui

Source Code of org.pushingpixels.substance.internal.ui.SubstanceComboBoxUI

/*
* Copyright (c) 2005-2010 Substance Kirill Grouchnikov. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*  o Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*
*  o Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
*
*  o Neither the name of Substance Kirill Grouchnikov nor the names of
*    its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.pushingpixels.substance.internal.ui;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.BasicComboBoxUI;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.text.JTextComponent;

import org.pushingpixels.substance.api.SubstanceLookAndFeel;
import org.pushingpixels.substance.api.SubstanceConstants.Side;
import org.pushingpixels.substance.api.renderers.SubstanceDefaultComboBoxRenderer;
import org.pushingpixels.substance.api.shaper.ClassicButtonShaper;
import org.pushingpixels.substance.api.shaper.SubstanceButtonShaper;
import org.pushingpixels.substance.internal.animation.StateTransitionTracker;
import org.pushingpixels.substance.internal.animation.TransitionAwareUI;
import org.pushingpixels.substance.internal.utils.*;
import org.pushingpixels.substance.internal.utils.SubstanceCoreUtilities.TextComponentAware;
import org.pushingpixels.substance.internal.utils.border.SubstanceTextComponentBorder;
import org.pushingpixels.substance.internal.utils.combo.*;
import org.pushingpixels.substance.internal.utils.icon.TransitionAwareIcon;

/**
* UI for combo boxes in <b>Substance </b> look and feel.
*
* @author Kirill Grouchnikov
* @author Thomas Bierhance http://www.orbital-computer.de/JComboBox/
* @author inostock
*/
public class SubstanceComboBoxUI extends BasicComboBoxUI implements
    TransitionAwareUI {
  /**
   * Property change handler on <code>enabled</code> property,
   * <code>componentOrientation</code> property and on
   * {@link SubstanceLookAndFeel#COMBO_BOX_POPUP_FLYOUT_ORIENTATION} property.
   */
  protected ComboBoxPropertyChangeHandler substanceChangeHandler;

  protected StateTransitionTracker stateTransitionTracker;

  /**
   * Surrogate button model for tracking the state transitions.
   */
  private ButtonModel transitionModel;

  /**
   * Listener for transition animations.
   */
  private RolloverTextControlListener substanceRolloverListener;

  /**
   * Painting delegate.
   */
  private ComboBoxBackgroundDelegate delegate;

  private Icon uneditableArrowIcon;

  private Insets layoutInsets;

  /*
   * (non-Javadoc)
   *
   * @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
   */
  public static ComponentUI createUI(JComponent comp) {
    SubstanceCoreUtilities.testComponentCreationThreadingViolation(comp);
    SubstanceComboBoxUI ui = new SubstanceComboBoxUI((JComboBox) comp);
    ui.comboBox = (JComboBox) comp;
    ui.comboBox.setOpaque(false);
    return ui;
  }

  @Override
  public void installUI(JComponent c) {
    super.installUI(c);

    c.putClientProperty(SubstanceCoreUtilities.TEXT_COMPONENT_AWARE,
        new TextComponentAware<JComboBox>() {
          @Override
          public JTextComponent getTextComponent(JComboBox t) {
            if (t.isEditable()) {
              Component editorComp = t.getEditor()
                  .getEditorComponent();
              if (editorComp instanceof JTextComponent) {
                return (JTextComponent) editorComp;
              }
            }
            return null;
          }
        });
  }

  @Override
  public void uninstallUI(JComponent c) {
    c.putClientProperty(SubstanceCoreUtilities.TEXT_COMPONENT_AWARE, null);

    super.uninstallUI(c);
  }

  public SubstanceComboBoxUI(JComboBox combo) {
    this.comboBox = combo;

    this.transitionModel = new DefaultButtonModel();
    this.transitionModel.setArmed(false);
    this.transitionModel.setSelected(false);
    this.transitionModel.setPressed(false);
    this.transitionModel.setRollover(false);
    this.transitionModel.setEnabled(combo.isEnabled());

    this.stateTransitionTracker = new StateTransitionTracker(this.comboBox,
        this.transitionModel);

    this.delegate = new ComboBoxBackgroundDelegate();
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.swing.plaf.basic.BasicComboBoxUI#createArrowButton()
   */
  @Override
  protected JButton createArrowButton() {
    SubstanceDropDownButton result = new SubstanceDropDownButton(
        this.comboBox);
    result.setFont(this.comboBox.getFont());
    result.setIcon(getCurrentIcon(result));
    return result;
  }

  /**
   * Returns the icon for the specified arrow button.
   *
   * @param button
   *            Arrow button.
   * @return Icon for the specified button.
   */
  private Icon getCurrentIcon(JButton button) {
    Icon icon = SubstanceCoreUtilities
        .getArrowIcon(button, SubstanceCoreUtilities
            .getPopupFlyoutOrientation(this.comboBox));
    return icon;
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.swing.plaf.basic.BasicComboBoxUI#createRenderer()
   */
  @Override
  protected ListCellRenderer createRenderer() {
    return new SubstanceDefaultComboBoxRenderer.SubstanceUIResource(
        this.comboBox);
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.swing.plaf.basic.BasicComboBoxUI#installListeners()
   */
  @Override
  protected void installListeners() {
    super.installListeners();
    this.substanceChangeHandler = new ComboBoxPropertyChangeHandler();
    this.comboBox.addPropertyChangeListener(this.substanceChangeHandler);

    this.substanceRolloverListener = new RolloverTextControlListener(
        this.comboBox, this, this.transitionModel);
    this.substanceRolloverListener.registerListeners();

    this.stateTransitionTracker.registerModelListeners();
    this.stateTransitionTracker.registerFocusListeners();
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.swing.plaf.basic.BasicComboBoxUI#uninstallListeners()
   */
  @Override
  protected void uninstallListeners() {
    this.stateTransitionTracker.unregisterModelListeners();
    this.stateTransitionTracker.unregisterFocusListeners();

    this.comboBox.removePropertyChangeListener(this.substanceChangeHandler);
    this.substanceChangeHandler = null;

    this.substanceRolloverListener.unregisterListeners();
    this.substanceRolloverListener = null;

    super.uninstallListeners();
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.swing.plaf.basic.BasicComboBoxUI#installDefaults()
   */
  @Override
  protected void installDefaults() {
    super.installDefaults();

    // this icon must be created after the font has been installed
    // on the combobox
    this.uneditableArrowIcon = SubstanceCoreUtilities.getArrowIcon(
        this.comboBox,
        new TransitionAwareIcon.TransitionAwareUIDelegate() {
          @Override
          public TransitionAwareUI getTransitionAwareUI() {
            return (TransitionAwareUI) comboBox.getUI();
          }
        }, SubstanceCoreUtilities
            .getPopupFlyoutOrientation(this.comboBox));
    this.updateComboBoxBorder();
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.swing.plaf.basic.BasicComboBoxUI#createLayoutManager()
   */
  @Override
  protected LayoutManager createLayoutManager() {
    return new SubstanceComboBoxLayoutManager();
  }

  /**
   * Layout manager for combo box.
   *
   * @author Kirill Grouchnikov
   */
  private class SubstanceComboBoxLayoutManager extends
      BasicComboBoxUI.ComboBoxLayoutManager {
    /*
     * (non-Javadoc)
     *
     * @see java.awt.LayoutManager#layoutContainer(java.awt.Container)
     */
    @Override
    public void layoutContainer(Container parent) {
      JComboBox cb = (JComboBox) parent;

      int width = cb.getWidth();
      int height = cb.getHeight();

      Insets insets = layoutInsets;
      int buttonWidth = SubstanceSizeUtils
          .getScrollBarWidth(SubstanceSizeUtils
              .getComponentFontSize(comboBox));
      // buttonWidth = Math.max(buttonWidth,
      // arrowButton.getPreferredSize().width);

      if (arrowButton != null) {
        if (!comboBox.isEditable()) {
          arrowButton.setBounds(0, 0, 0, 0);
        } else {
          if (cb.getComponentOrientation().isLeftToRight()) {
            arrowButton.setBounds(width - buttonWidth
                - insets.right, 0, buttonWidth + insets.right,
                height);
          } else {
            arrowButton.setBounds(0, 0, buttonWidth + insets.left,
                height);
          }
        }
      }
      if (editor != null) {
        Rectangle r = rectangleForCurrentValue();
        editor.setBounds(r);
      }
    }
  }

  @Override
  protected Rectangle rectangleForCurrentValue() {
    int width = this.comboBox.getWidth();
    int height = this.comboBox.getHeight();
    Insets insets = this.layoutInsets;
    int buttonWidth = SubstanceSizeUtils
        .getScrollBarWidth(SubstanceSizeUtils
            .getComponentFontSize(comboBox));
    if (this.comboBox.getComponentOrientation().isLeftToRight()) {
      return new Rectangle(insets.left, insets.top, width - insets.left
          - insets.right - buttonWidth, height - insets.top
          - insets.bottom);
    } else {
      int startX = insets.left + buttonWidth;
      return new Rectangle(startX, insets.top, width - startX
          - insets.right, height - insets.top - insets.bottom);
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.swing.plaf.basic.BasicComboBoxUI#getDefaultSize()
   */
  @Override
  protected Dimension getDefaultSize() {
    Component rend = new SubstanceDefaultComboBoxRenderer(this.comboBox)
        .getListCellRendererComponent(listBox, " ", -1, false, false);
    rend.setFont(this.comboBox.getFont());

    return rend.getPreferredSize();
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * javax.swing.plaf.basic.BasicComboBoxUI#getMinimumSize(javax.swing.JComponent
   * )
   */
  @Override
  public Dimension getMinimumSize(JComponent c) {
    if (!this.isMinimumSizeDirty) {
      return new Dimension(this.cachedMinimumSize);
    }

    // Dimension size = null;
    //
    // if (!this.comboBox.isEditable() && this.arrowButton != null
    // && this.arrowButton instanceof SubstanceComboBoxButton) {
    //
    SubstanceDropDownButton button = (SubstanceDropDownButton) this.arrowButton;
    Insets buttonInsets = button.getInsets();
    Insets insets = this.comboBox.getInsets();

    Dimension size = this.getDisplaySize();

    size.width += insets.left + insets.right;
    size.width += buttonInsets.left + buttonInsets.right;
    size.width += button.getMinimumSize().getWidth();
    size.height += insets.top + insets.bottom;
    // } else if (this.comboBox.isEditable() && this.arrowButton != null
    // && this.editor != null) {
    // size = super.getMinimumSize(c);
    // } else {
    // size = super.getMinimumSize(c);
    // }

    this.cachedMinimumSize.setSize(size.width, size.height);
    this.isMinimumSizeDirty = false;

    return new Dimension(this.cachedMinimumSize);
  }

  /**
   * This property change handler changes combo box arrow icon based on the
   * enabled status of the combo box.
   *
   * @author Kirill Grouchnikov
   */
  public class ComboBoxPropertyChangeHandler extends PropertyChangeHandler {
    /*
     * (non-Javadoc)
     *
     * @seejavax.swing.plaf.basic.BasicComboBoxUI$PropertyChangeHandler#
     * propertyChange(java.beans.PropertyChangeEvent)
     */
    @Override
    public void propertyChange(final PropertyChangeEvent e) {
      String propertyName = e.getPropertyName();

      if (propertyName.equals("componentOrientation")) {
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            if (SubstanceComboBoxUI.this.comboBox == null)
              return;
            final ComponentOrientation newOrientation = (ComponentOrientation) e
                .getNewValue();
            final ListCellRenderer cellRenderer = SubstanceComboBoxUI.this.comboBox
                .getRenderer();
            final ComboBoxEditor editor = SubstanceComboBoxUI.this.comboBox
                .getEditor();
            if (SubstanceComboBoxUI.this.popup instanceof Component) {
              final Component cPopup = (Component) SubstanceComboBoxUI.this.popup;
              cPopup.applyComponentOrientation(newOrientation);
              cPopup.doLayout();
            }
            if (cellRenderer instanceof Component) {
              ((Component) cellRenderer)
                  .applyComponentOrientation(newOrientation);
            }
            if ((editor != null)
                && (editor.getEditorComponent() != null)) {
              (editor.getEditorComponent())
                  .applyComponentOrientation(newOrientation);
            }
            if (SubstanceComboBoxUI.this.comboBox != null)
              SubstanceComboBoxUI.this.comboBox.repaint();

            configureArrowButtonStraightSide();
          }
        });
      }

      if (SubstanceLookAndFeel.COMBO_BOX_POPUP_FLYOUT_ORIENTATION
          .equals(propertyName)) {
        ((SubstanceDropDownButton) arrowButton)
            .setIcon(SubstanceCoreUtilities
                .getArrowIcon(
                    arrowButton,
                    SubstanceCoreUtilities
                        .getPopupFlyoutOrientation(SubstanceComboBoxUI.this.comboBox)));

      }

      if ("font".equals(propertyName)) {
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            if (comboBox != null)
              comboBox.updateUI();
          }
        });
      }

      if ("background".equals(propertyName)) {
        if (comboBox.isEditable()) {
          comboBox.getEditor().getEditorComponent().setBackground(
              comboBox.getBackground());
          popup.getList().setBackground(comboBox.getBackground());
        }
      }

      if ("editable".equals(propertyName)) {
        updateComboBoxBorder();
        isMinimumSizeDirty = true;
      }

      if ("enabled".equals(propertyName)) {
        SubstanceComboBoxUI.this.transitionModel.setEnabled(comboBox
            .isEnabled());
      }
      // Do not call super - fix for bug 63
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.swing.plaf.basic.BasicComboBoxUI#createPopup()
   */
  @Override
  protected ComboPopup createPopup() {
    final ComboPopup sPopup = new SubstanceComboPopup(this.comboBox);

    final ComponentOrientation currOrientation = this.comboBox
        .getComponentOrientation();

    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        if (SubstanceComboBoxUI.this.comboBox == null)
          return;

        if (sPopup instanceof Component) {
          final Component cPopup = (Component) sPopup;
          cPopup.applyComponentOrientation(currOrientation);
          cPopup.doLayout();
        }
        ListCellRenderer cellRenderer = SubstanceComboBoxUI.this.comboBox
            .getRenderer();
        if (cellRenderer instanceof Component) {
          ((Component) cellRenderer)
              .applyComponentOrientation(currOrientation);
        }
        ComboBoxEditor editor = SubstanceComboBoxUI.this.comboBox
            .getEditor();
        if ((editor != null) && (editor.getEditorComponent() != null)) {
          (editor.getEditorComponent())
              .applyComponentOrientation(currOrientation);
        }
        SubstanceComboBoxUI.this.comboBox.repaint();
      }
    });
    return sPopup;
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.swing.plaf.basic.BasicComboBoxUI#paint(java.awt.Graphics,
   * javax.swing.JComponent)
   */
  @Override
  public void paint(Graphics g, JComponent c) {
    Graphics2D graphics = (Graphics2D) g.create();
    int width = this.comboBox.getWidth();
    int height = this.comboBox.getHeight();
    Insets insets = this.comboBox.getInsets();

    int componentFontSize = SubstanceSizeUtils
        .getComponentFontSize(this.comboBox);
    if (this.comboBox.isEditable()) {
      int borderDelta = (int) Math.floor(SubstanceSizeUtils
          .getBorderStrokeWidth(componentFontSize));
      Shape contour = SubstanceOutlineUtilities
          .getBaseOutline(
              width,
              height,
              Math
                  .max(
                      0,
                      2.0f
                          * SubstanceSizeUtils
                              .getClassicButtonCornerRadius(componentFontSize)
                          - borderDelta), null,
              borderDelta);

      graphics.setColor(SubstanceTextUtilities
          .getTextBackgroundFillColor(this.comboBox));
      graphics.fill(contour);
    } else {
      this.delegate.updateBackground(graphics, this.comboBox,
          this.transitionModel);

      Icon icon = this.uneditableArrowIcon;
      int iw = icon.getIconWidth();
      int ih = icon.getIconHeight();
      int origButtonWidth = SubstanceSizeUtils
          .getScrollBarWidth(componentFontSize);
      if (this.comboBox.getComponentOrientation().isLeftToRight()) {
        int iconX = width - origButtonWidth - insets.right / 2
            + (origButtonWidth - iw) / 2;
        int iconY = insets.top
            + (height - insets.top - insets.bottom - ih) / 2;
        icon.paintIcon(this.comboBox, graphics, iconX, iconY);
      } else {
        int iconX = insets.left / 2 + (origButtonWidth - iw) / 2;
        int iconY = insets.top
            + (height - insets.top - insets.bottom - ih) / 2;
        icon.paintIcon(this.comboBox, graphics, iconX, iconY);
      }
    }

    hasFocus = comboBox.hasFocus();
    if (!comboBox.isEditable()) {
      Rectangle r = rectangleForCurrentValue();

      ListCellRenderer renderer = this.comboBox.getRenderer();
      Component rendererComponent;
      if (hasFocus) {
        rendererComponent = renderer.getListCellRendererComponent(
            this.listBox, this.comboBox.getSelectedItem(), -1,
            true, hasFocus);
      } else {
        rendererComponent = renderer.getListCellRendererComponent(
            this.listBox, this.comboBox.getSelectedItem(), -1,
            false, hasFocus);
      }
      rendererComponent.setFont(this.comboBox.getFont());

      // Fix for 4238829: should lay out the JPanel.
      boolean shouldValidate = false;
      if (rendererComponent instanceof JPanel) {
        shouldValidate = true;
      }

      // SubstanceCoreUtilities.workaroundBug6576507(graphics);

      if (this.comboBox.getComponentOrientation().isLeftToRight()) {
        this.currentValuePane.paintComponent(graphics,
            rendererComponent, this.comboBox, r.x, r.y, r.width,
            r.height, shouldValidate);
      } else {
        this.currentValuePane.paintComponent(graphics,
            rendererComponent, this.comboBox, r.x, r.y, r.width,
            r.height, shouldValidate);
      }
    }

    if (!this.comboBox.isEditable()) {
      Rectangle r = new Rectangle(insets.left, layoutInsets.top, width
          - insets.left - insets.right, height - layoutInsets.top
          - layoutInsets.bottom);
      this.paintFocus(graphics, r);
    }

    graphics.dispose();
  }

  /**
   * Paints the focus indication.
   *
   * @param g
   *            Graphics.
   * @param bounds
   *            Bounds for text.
   */
  protected void paintFocus(Graphics g, Rectangle bounds) {
    int fontSize = SubstanceSizeUtils.getComponentFontSize(this.comboBox);
    int focusRingPadding = SubstanceSizeUtils.getFocusRingPadding(fontSize) / 2;
    int x = bounds.x;
    int y = bounds.y;
    Graphics2D g2d = (Graphics2D) g.create();
    g2d.translate(x, y);

    SubstanceCoreUtilities.paintFocus(g2d, this.comboBox, this.comboBox,
        this, SubstanceOutlineUtilities.getBaseOutline(bounds.width,
            bounds.height, SubstanceSizeUtils
                .getClassicButtonCornerRadius(fontSize), null,
            0), bounds, 1.0f, focusRingPadding);

    g2d.dispose();
  }

  /**
   * Returns the popup of the associated combobox.
   *
   * @return The popup of the associated combobox.
   */
  public ComboPopup getPopup() {
    return this.popup;
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.swing.plaf.basic.BasicComboBoxUI#configureArrowButton()
   */
  @Override
  public void configureArrowButton() {
    super.configureArrowButton();
    // Mustang decided to make the arrow button focusable on
    // focusable comboboxes
    this.arrowButton.setFocusable(false);

    // this.substanceFocusListener = new FocusListener() {
    // public void focusGained(FocusEvent e) {
    // arrowButton.setSelected(true);
    // }
    //
    // public void focusLost(FocusEvent e) {
    // arrowButton.setSelected(false);
    // }
    // };
    // this.arrowButton.setSelected(this.comboBox.hasFocus());
    // this.comboBox.addFocusListener(this.substanceFocusListener);

    this.configureArrowButtonStraightSide();
  }

  /**
   * Configures the straight side of the arrow button.
   */
  protected void configureArrowButtonStraightSide() {
    this.arrowButton.putClientProperty(
        SubstanceLookAndFeel.BUTTON_SIDE_PROPERTY, this.comboBox
            .getComponentOrientation().isLeftToRight() ? Side.LEFT
            : Side.RIGHT);
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.swing.plaf.basic.BasicComboBoxUI#unconfigureArrowButton()
   */
  @Override
  public void unconfigureArrowButton() {
    // this.comboBox.removeFocusListener(this.substanceFocusListener);
    // this.substanceFocusListener = null;
    super.unconfigureArrowButton();
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.swing.plaf.basic.BasicComboBoxUI#configureEditor()
   */
  @Override
  protected void configureEditor() {
    super.configureEditor();
    // This for Mustang - setting Substance once again adds a border on
    // the text field in the combo editor.
    if (this.editor instanceof JComponent) {
      Insets ins = SubstanceSizeUtils
          .getComboTextBorderInsets(SubstanceSizeUtils
              .getComponentFontSize(this.editor));
      ((JComponent) this.editor).setBorder(new EmptyBorder(ins.top,
          ins.left, ins.bottom, ins.right));
      this.editor.setBackground(this.comboBox.getBackground());
      // ((JComponent) this.editor).setBorder(new LineBorder(Color.red));
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see javax.swing.plaf.basic.BasicComboBoxUI#createEditor()
   */
  @Override
  protected ComboBoxEditor createEditor() {
    return new SubstanceComboBoxEditor.UIResource();
  }

  private void updateComboBoxBorder() {
    Border b = this.comboBox.getBorder();
    if (b == null || b instanceof UIResource) {
      int comboFontSize = SubstanceSizeUtils
          .getComponentFontSize(this.comboBox);
      Insets comboBorderInsets = SubstanceSizeUtils
          .getComboBorderInsets(comboFontSize);
      if (this.comboBox.isEditable()) {
        this.comboBox.setBorder(new SubstanceTextComponentBorder(
            comboBorderInsets));
      } else {
        this.comboBox
            .setBorder(new BorderUIResource.EmptyBorderUIResource(
                comboBorderInsets));
        // BasicComboBoxUI does not invalidate display size when
        // combo becomes uneditable. However, this is not good
        // in Substance which has different preferred size for
        // editable and uneditable combos. Calling the method below
        // will trigger the path in BasicComboBoxUI.Handler that
        // will invalidate the cached sizes.
        this.comboBox.setPrototypeDisplayValue(this.comboBox
            .getPrototypeDisplayValue());
      }
      this.layoutInsets = SubstanceSizeUtils
          .getComboLayoutInsets(comboFontSize);
    } else {
      this.layoutInsets = new Insets(0, 0, 0, 0);
    }
  }

  @Override
  public StateTransitionTracker getTransitionTracker() {
    return this.stateTransitionTracker;
  }

  @Override
  public boolean isInside(MouseEvent me) {
    if (!SubstanceLookAndFeel.isCurrentLookAndFeel()) {
      return false;
    }
    SubstanceButtonShaper shaper = ClassicButtonShaper.INSTANCE;
    if (shaper == null)
      return false;
    Shape contour = SubstanceOutlineUtilities.getBaseOutline(this.comboBox,
        SubstanceSizeUtils
            .getClassicButtonCornerRadius(SubstanceSizeUtils
                .getComponentFontSize(this.comboBox)), null);
    return contour.contains(me.getPoint());
  }
}
TOP

Related Classes of org.pushingpixels.substance.internal.ui.SubstanceComboBoxUI

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.