Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4465870

JTabbedPane: can't intercept mouse events when using scrolled tabs

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Won't Fix
    • Affects Version/s: 1.4.0
    • Fix Version/s: None
    • Component/s: client-libs
    • Labels:

      Description



      Name: bsC130419 Date: 06/04/2001


      java version "1.4.0-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b65)
      Java HotSpot(TM) Client VM (build 1.4.0-beta-b65, mixed mode)

      In following code, I have created a subclass of JTabbedPane in
      order to associate right-click popup menus with the tabs:

      //===== sample code =============================================

      import java.awt.BorderLayout;
      import java.awt.event.*;
      import javax.swing.*;

      public class TabbedPaneTest extends JFrame
      {
        MyTabbedPane tabPane;
        
        public TabbedPaneTest(int layoutPolicy)
        {
          setTitle("TabbedPaneTest");
          setBounds(50,50,400,300);
          setDefaultCloseOperation(EXIT_ON_CLOSE);
          tabPane = new MyTabbedPane(JTabbedPane.TOP, layoutPolicy);
          tabPane.addTab("Tab one", new JPanel());
          tabPane.addTab("Tab two", new JPanel());
          getContentPane().add(tabPane, BorderLayout.CENTER);
          setVisible(true);
        }

        public static void main(String[] argv)
        {
          int policy = JTabbedPane.WRAP_TAB_LAYOUT;
          if (argv.length > 0 && "scrolled".equals(argv[0]))
          {
            policy = JTabbedPane.SCROLL_TAB_LAYOUT;
          }
          new TabbedPaneTest(policy);
        }
        
        
        class MyTabbedPane extends JTabbedPane
        {
          public MyTabbedPane(int tabPlacement, int layoutPolicy)
          {
            super(tabPlacement, layoutPolicy);
          }
          
          protected void processMouseEvent(MouseEvent evt)
          {
            if (evt.getID() == MouseEvent.MOUSE_PRESSED
                && evt.getButton() == MouseEvent.BUTTON3)
            {
              int index = indexAtLocation(evt.getX(), evt.getY());
              getTabPopup(index).show(this, evt.getX(), evt.getY());
            }
            else
            {
              super.processMouseEvent(evt);
            }
          }
        
          private JPopupMenu getTabPopup(final int index)
          {
            String title = getTitleAt(index);
        
            JPopupMenu pm = new JPopupMenu();
            JMenuItem close = new JMenuItem("Remove " + title);
            close.addActionListener(new ActionListener()
            {
              public void actionPerformed(ActionEvent evt)
              {
                remove(index);
              }
            });
            pm.add(close);
        
            return pm;
          }
        }
      }

      //===============================================================

      Compile the code and run it using the default wrapped tab layout:

         % java TabbedPaneTest

      A frame containing a tabbed pane with two tabs appears. Right-
      click on either of the tabs, and a popup menu appears, giving you
      the option of removing that tab. Now close the frame and rerun
      the program in scrolled mode:

         % java TabbedPaneTest scrolled

      This time, right-clicking on a tab doesn't bring up a menu; it
      just selects the tab, the same as left- or middle-clicking does.
      The problem is that the mouse event is now being generated, not
      by the tabbed pane itself, but by the ScrollableTabSupport object,
      which is a private instance of a private inner class of
      BasicTabbedPaneUI. There is simply no way to get at this thing to
      intercept its events or to attach listeners to it.

      This means that developers who want to let their users choose
      between wrapped and scrolled tab layouts will either have to warn
      them that any right-click functions (like popup menus) will only be
      available in wrapped mode, or just not include those functions for
      the sake of consistency. Anything you can do in one mode should be
      doable in both.


      You might provide a callback method in JTabbedPane for subclassers
      to override if they so choose:


        protected void rightButtonPressed(MouseEvent evt) {}


      ...and rewrite the MouseHandler to something like this:


        public class MouseHandler extends MouseAdapter
        {
          public void mousePressed(MouseEvent e)
          {
            if (!tabPane.isEnabled())
            {
              return;
            }
            if (e.getButton() == MouseEvent.BUTTON1)
            {
              int tabIndex = getTabAtLocation(e.getX(), e.getY());
              if (tabIndex >= 0 && tabPane.isEnabledAt(tabIndex))
              {
                if (tabIndex == tabPane.getSelectedIndex())
                {
                  if (tabPane.isRequestFocusEnabled())
                  {
                    tabPane.requestFocus();
                    tabPane.repaint(rects[tabIndex]);
                  }
                }
                else
                {
                  tabPane.setSelectedIndex(tabIndex);
                }
              }
            }
            else if (e.getButton() == MouseEvent.BUTTON3)
            {
              tabPane.rightButtonClicked(e);
            }
          }
        }
      (Review ID: 125727)
      ======================================================================

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                joutwatesunw Joshua Outwater (Inactive)
                Reporter:
                bstrathesunw Bill Strathearn (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: