Hi,
here is another small patch which makes JTabbedPane behave more like in the RI.
This fixes:
- changing the placement should result in a specific behavior in regard to the
current scroll location (see comment in PropertyChangeHandler.propertyChange)

- in SCROLL_TAB_LAYOUT mode the tabs are in a sub-component. This means that a
MouseListener installed on the JTabbedPane is normally not triggered if
something happens in that area. I fixed that by adding a logic into the tabbed
pane's own MouseHanlder (which is installed on the internal subcomponent, too)
that recognizes such a situation and redispatches a properly modified MouseEvent
to the JTabbedPane. With that patch my PopupMenu-enhanced JTabbedPane demo
(yay!) works now more like on the RI.

Still need to figure out how they make it react on actions in the content area 
...

2006-08-17  Robert Schuster  <[EMAIL PROTECTED]>

        * javax/swing/plaf/basic/BasicTabbedPaneUI.java:
        (MouseHandler.mouseReleased): Implemented.
        (MouseHandler.mousePressed): Added delegation to tabbed pane.
        (MouseHandler.mouseEntered): Dito.
        (MouseHandler.mouseExited): Dito.
        (MouseHandler.mouseMoved): Dito.
        (MouseHandler.redispatchEvent): New method.
        (PropertyChangeHandler.propertyChange): Added extra block level,
        added code to handle tab placement changes, added comment.
        (updateViewPosition): Set unneeded coordinate to 0, added comment.

cya
Robert
Index: javax/swing/plaf/basic/BasicTabbedPaneUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java,v
retrieving revision 1.51
diff -u -r1.51 BasicTabbedPaneUI.java
--- javax/swing/plaf/basic/BasicTabbedPaneUI.java	15 Aug 2006 23:46:47 -0000	1.51
+++ javax/swing/plaf/basic/BasicTabbedPaneUI.java	16 Aug 2006 22:48:29 -0000
@@ -252,7 +252,16 @@
   {
     public void mouseReleased(MouseEvent e)
     {
-     // Nothing to do here. 
+      Object s = e.getSource();
+
+      // Event may originate from the viewport in
+      // SCROLL_TAB_LAYOUT mode. It is redisptached
+      // through the tabbed pane then.
+      if (tabPane != e.getSource())
+        {
+          redispatchEvent(e);
+          e.setSource(s);
+        }
     }
     
     /**
@@ -264,6 +273,16 @@
     public void mousePressed(MouseEvent e)
     {
       Object s = e.getSource();
+
+      // Event may originate from the viewport in
+      // SCROLL_TAB_LAYOUT mode. It is redisptached
+      // through the tabbed pane then.
+      if (tabPane != e.getSource())
+        {
+          redispatchEvent(e);
+          e.setSource(s);
+        }
+      
       int placement = tabPane.getTabPlacement();
     
       if (s == incrButton)
@@ -361,11 +380,22 @@
      * Receives notification when the mouse pointer has entered the tabbed
      * pane.
      *
-     * @param ev the mouse event
+     * @param e the mouse event
      */
-    public void mouseEntered(MouseEvent ev)
+    public void mouseEntered(MouseEvent e)
     {
-      int tabIndex = tabForCoordinate(tabPane, ev.getX(), ev.getY());
+      Object s = e.getSource();
+
+      // Event may originate from the viewport in
+      // SCROLL_TAB_LAYOUT mode. It is redisptached
+      // through the tabbed pane then.
+      if (tabPane != e.getSource())
+        {
+          redispatchEvent(e);
+          e.setSource(s);
+        }
+      
+      int tabIndex = tabForCoordinate(tabPane, e.getX(), e.getY());
       setRolloverTab(tabIndex);
     }
 
@@ -373,10 +403,21 @@
      * Receives notification when the mouse pointer has exited the tabbed
      * pane.
      *
-     * @param ev the mouse event
+     * @param e the mouse event
      */
-    public void mouseExited(MouseEvent ev)
+    public void mouseExited(MouseEvent e)
     {
+      Object s = e.getSource();
+
+      // Event may originate from the viewport in
+      // SCROLL_TAB_LAYOUT mode. It is redisptached
+      // through the tabbed pane then.
+      if (tabPane != e.getSource())
+        {
+          redispatchEvent(e);
+          e.setSource(s);
+        }
+      
       setRolloverTab(-1);
     }
 
@@ -388,9 +429,37 @@
      */
     public void mouseMoved(MouseEvent ev)
     {
+      Object s = ev.getSource();
+
+      if (tabPane != ev.getSource())
+        {
+          ev.setSource(tabPane);
+          tabPane.dispatchEvent(ev);
+          
+          ev.setSource(s);
+        }
+
       int tabIndex = tabForCoordinate(tabPane, ev.getX(), ev.getY());
       setRolloverTab(tabIndex);
     }
+    
+    /** Modifies the mouse event to originate from 
+     * the tabbed pane and redispatches it.
+     * 
+     * @param me
+     */
+    void redispatchEvent(MouseEvent me)
+    {
+      me.setSource(tabPane);
+      Point viewPos = viewport.getViewPosition();
+      viewPos.x -= viewport.getX();
+      viewPos.y -= viewport.getY();
+      me.translatePoint(-viewPos.x, -viewPos.y);
+      tabPane.dispatchEvent(me);
+      
+      me.translatePoint(viewPos.x, viewPos.y);
+    }
+    
   }
 
   /**
@@ -410,20 +479,56 @@
      */
     public void propertyChange(PropertyChangeEvent e)
     {
-      if (e.getPropertyName().equals("tabLayoutPolicy"))
-        {
-          currentScrollLocation = currentScrollOffset = 0;
-          
-          layoutManager = createLayoutManager();
-          
-          tabPane.setLayout(layoutManager);
-        }
-      else if (e.getPropertyName().equals("tabPlacement")
-          && tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
+      out:
         {
-          incrButton = createIncreaseButton();
-          decrButton = createDecreaseButton();
+          if (e.getPropertyName().equals("tabLayoutPolicy"))
+            {
+              currentScrollLocation = currentScrollOffset = 0;
+              
+              layoutManager = createLayoutManager();
+              
+              tabPane.setLayout(layoutManager);
+            }
+          else if (e.getPropertyName().equals("tabPlacement")
+                   && tabPane.getTabLayoutPolicy() 
+                   == JTabbedPane.SCROLL_TAB_LAYOUT)
+            {
+              incrButton = createIncreaseButton();
+              decrButton = createDecreaseButton();
+              
+              // If the tab placement value was changed of a tabbed pane
+              // in SCROLL_TAB_LAYOUT mode we investigate the change to
+              // implement the following behavior which was observed in
+              // the RI:
+              // The scrolling offset will be reset if we change to
+              // a direction which is orthogonal to the current
+              // direction and stays the same if it is parallel.
+              
+              int oldPlacement = ((Integer) e.getOldValue()).intValue();
+              int newPlacement = ((Integer) e.getNewValue()).intValue();
+              switch (newPlacement)
+                {
+                  case JTabbedPane.TOP:
+                  case JTabbedPane.BOTTOM:
+                    if (oldPlacement == JTabbedPane.TOP
+                        || oldPlacement == JTabbedPane.BOTTOM)
+                      break out;
+                  
+                    currentScrollOffset = getTabAreaInsets(newPlacement).left;
+                    break;
+                  default:
+                    if (oldPlacement == JTabbedPane.LEFT
+                       || oldPlacement == JTabbedPane.RIGHT)
+                      break out;
+                  
+                    currentScrollOffset = getTabAreaInsets(newPlacement).top;
+                }
+              
+              updateViewPosition();
+              updateButtons();
+            }
         }
+    
       tabPane.revalidate();
       tabPane.repaint();
     }
@@ -1906,15 +2011,19 @@
   final void updateViewPosition()
   {
     Point p = viewport.getViewPosition();
-  
+    
+    // The unneeded coordinate must be set to zero
+    // in order to correctly handle placement changes.
     switch (tabPane.getTabPlacement())
     {
       case JTabbedPane.LEFT:
       case JTabbedPane.RIGHT:
+        p.x = 0;
         p.y = currentScrollOffset;
         break;
       default:
         p.x = currentScrollOffset;
+        p.y = 0;
     }
     
     viewport.setViewPosition(p);

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to