gt:     protected MouseListener createMouseListener() {
context: /*
   * Copyright 2002-2007 Sun Microsystems, Inc.  All Rights Reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Sun designates this
   * particular file as subject to the "Classpath" exception as provided
   * by Sun in the LICENSE file that accompanied this code.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   * CA 95054 USA or visit www.sun.com if you need additional information or
   * have any questions.
   */
  
  package javax.swing.plaf.synth;
  
  import javax.swing.*;
  import javax.swing.plaf.*;
  import javax.swing.plaf.basic.*;
  import javax.swing.text.View;
  
  import java.awt.*;
  import java.awt.event.*;
  import java.beans.PropertyChangeListener;
  import java.beans.PropertyChangeEvent;
  import sun.swing.SwingUtilities2;
  
  /**
   * Provides the Synth L&F UI delegate for
   * {@link javax.swing.JTabbedPane}.
   *
   * <p>Looks up the {@code selectedTabPadInsets} property from the Style,
   * which represents additional insets for the selected tab.
   *
   * @author Scott Violet
   * @since 1.7
   */
  public class SynthTabbedPaneUI extends BasicTabbedPaneUI
                                 implements PropertyChangeListener, SynthUI {
  
      /**
       * <p>If non-zero, tabOverlap indicates the amount that the tab bounds
       * should be altered such that they would overlap with a tab on either the
       * leading or trailing end of a run (ie: in TOP, this would be on the left
       * or right).</p>
  
       * <p>A positive overlap indicates that tabs should overlap right/down,
       * while a negative overlap indicates tha tabs should overlap left/up.</p>
       *
       * <p>When tabOverlap is specified, it both changes the x position and width
       * of the tab if in TOP or BOTTOM placement, and changes the y position and
       * height if in LEFT or RIGHT placement.</p>
       *
       * <p>This is done for the following reason. Consider a run of 10 tabs.
       * There are 9 gaps between these tabs. If you specified a tabOverlap of
       * "-1", then each of the tabs "x" values will be shifted left. This leaves
       * 9 pixels of space to the right of the right-most tab unpainted. So, each
       * tab's width is also extended by 1 pixel to make up the difference.</p>
       *
       * <p>This property respects the RTL component orientation.</p>
       */
      private int tabOverlap = 0;
  
      /**
       * When a tabbed pane has multiple rows of tabs, this indicates whether
       * the tabs in the upper row(s) should extend to the base of the tab area,
       * or whether they should remain at their normal tab height. This does not
       * affect the bounds of the tabs, only the bounds of area painted by the
       * tabs. The text position does not change. The result is that the bottom
       * border of the upper row of tabs becomes fully obscured by the lower tabs,
       * resulting in a cleaner look.
       */
      private boolean extendTabsToBase = false;
  
      private SynthContext tabAreaContext;
      private SynthContext tabContext;
      private SynthContext tabContentContext;
  
      private SynthStyle style;
      private SynthStyle tabStyle;
      private SynthStyle tabAreaStyle;
      private SynthStyle tabContentStyle;
  
      private Rectangle textRect;
      private Rectangle iconRect;
  
      private Rectangle tabAreaBounds = new Rectangle();
  
      //added for the Nimbus look and feel, where the tab area is painted differently depending on the
      //state for the selected tab
      private boolean tabAreaStatesMatchSelectedTab = false;
      //added for the Nimbus LAF to ensure that the labels don't move whether the tab is selected or not
      private boolean nudgeSelectedLabel = true;
  
      private boolean selectedTabIsPressed = false;
  
      /**
       * Creates a new UI object for the given component.
       *
       * @param c component to create UI object for
       * @return the UI object
       */
      public static ComponentUI createUI(JComponent c) {
          return new SynthTabbedPaneUI();
      }
  
      private SynthTabbedPaneUI() {
          textRect = new Rectangle();
          iconRect = new Rectangle();
      }
  
      private boolean scrollableTabLayoutEnabled() {
          return (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT);
      }
  
      /**
       * @inheritDoc
       */
      @Override
      protected void installDefaults() {
          updateStyle(tabPane);
      }
  
      private void updateStyle(JTabbedPane c) {
          SynthContext context = getContext(c, ENABLED);
          SynthStyle oldStyle = style;
          style = SynthLookAndFeel.updateStyle(context, this);
          // Add properties other than JComponent colors, Borders and
          // opacity settings here:
          if (style != oldStyle) {
              tabRunOverlay =
                  style.getInt(context, "TabbedPane.tabRunOverlay", 0);
              tabOverlap = style.getInt(context, "TabbedPane.tabOverlap", 0);
              extendTabsToBase = style.getBoolean(context,
                      "TabbedPane.extendTabsToBase", false);
              textIconGap = style.getInt(context, "TabbedPane.textIconGap", 0);
              selectedTabPadInsets = (Insets)style.get(context,
                  "TabbedPane.selectedTabPadInsets");
              if (selectedTabPadInsets == null) {
                  selectedTabPadInsets = new Insets(0, 0, 0, 0);
              }
              tabAreaStatesMatchSelectedTab = style.getBoolean(context,
                      "TabbedPane.tabAreaStatesMatchSelectedTab", false);
              nudgeSelectedLabel = style.getBoolean(context,
                      "TabbedPane.nudgeSelectedLabel", true);
              if (oldStyle != null) {
                  uninstallKeyboardActions();
                  installKeyboardActions();
              }
          }
          context.dispose();
  
          if (tabContext != null) {
              tabContext.dispose();
          }
          tabContext = getContext(c, Region.TABBED_PANE_TAB, ENABLED);
          this.tabStyle = SynthLookAndFeel.updateStyle(tabContext, this);
          tabInsets = tabStyle.getInsets(tabContext, null);
  
  
          if (tabAreaContext != null) {
              tabAreaContext.dispose();
          }
          tabAreaContext = getContext(c, Region.TABBED_PANE_TAB_AREA, ENABLED);
          this.tabAreaStyle = SynthLookAndFeel.updateStyle(tabAreaContext, this);
          tabAreaInsets = tabAreaStyle.getInsets(tabAreaContext, null);
  
  
          if (tabContentContext != null) {
              tabContentContext.dispose();
          }
          tabContentContext = getContext(c, Region.TABBED_PANE_CONTENT, ENABLED);
          this.tabContentStyle = SynthLookAndFeel.updateStyle(tabContentContext,
                                                              this);
          contentBorderInsets =
              tabContentStyle.getInsets(tabContentContext, null);
      }
  
      /**
       * @inheritDoc
       */
      @Override
      protected void installListeners() {
          super.installListeners();
          tabPane.addPropertyChangeListener(this);
      }
  
      /**
       * @inheritDoc
       */
      @Override
      protected void uninstallListeners() {
          super.uninstallListeners();
          tabPane.removePropertyChangeListener(this);
      }
  
      /**
       * @inheritDoc
       */
      @Override
      protected void uninstallDefaults() {
          SynthContext context = getContext(tabPane, ENABLED);
          style.uninstallDefaults(context);
          context.dispose();
          style = null;
  
          tabStyle.uninstallDefaults(tabContext);
          tabContext.dispose();
          tabContext = null;
          tabStyle = null;
  
          tabAreaStyle.uninstallDefaults(tabAreaContext);
          tabAreaContext.dispose();
          tabAreaContext = null;
          tabAreaStyle = null;
  
          tabContentStyle.uninstallDefaults(tabContentContext);
          tabContentContext.dispose();
          tabContentContext = null;
          tabContentStyle = null;
      }
  
      /**
       * @inheritDoc
       */
      @Override
      public SynthContext getContext(JComponent c) {
          return getContext(c, SynthLookAndFeel.getComponentState(c));
      }
  
      private SynthContext getContext(JComponent c, int state) {
          return SynthContext.getContext(SynthContext.class, c,
                      SynthLookAndFeel.getRegion(c),style, state);
      }
  
      private SynthContext getContext(JComponent c, Region subregion, int state){
          SynthStyle style = null;
          Class klass = SynthContext.class;
  
          if (subregion == Region.TABBED_PANE_TAB) {
              style = tabStyle;
          }
          else if (subregion == Region.TABBED_PANE_TAB_AREA) {
              style = tabAreaStyle;
          }
          else if (subregion == Region.TABBED_PANE_CONTENT) {
              style = tabContentStyle;
          }
          return SynthContext.getContext(klass, c, subregion, style, state);
      }
  
      /**
       * @inheritDoc
       */
      @Override
      protected JButton createScrollButton(int direction) {
          // added for Nimbus LAF so that it can use the basic arrow buttons
          // UIManager is queried directly here because this is called before
          // updateStyle is called so the style can not be queried directly
          if (UIManager.getBoolean("TabbedPane.useBasicArrows")) {
              JButton btn = super.createScrollButton(direction);
              btn.setBorder(BorderFactory.createEmptyBorder());
              return btn;
          }
          return new SynthScrollableTabButton(direction);
      }
  
      /**
       * @inheritDoc
       */
      @Override
      public void propertyChange(PropertyChangeEvent e) {
          if (SynthLookAndFeel.shouldUpdateStyle(e)) {
              updateStyle(tabPane);
          }
      }
  
      /**
       * @inheritDoc
       *
       * Overridden to keep track of whether the selected tab is also pressed.
       */
      @Override
  