6/25/2016

Removing Unwanted Tab Selection in JTabbedPane

JTabbedPane is  a Jcomponent under java swing. The JTabbedPane can have several tabs. 
There is a little bit confusion over left and right mouse click events. The confused scenario is when the user right clicks on one of the tabs, it is  set as the selected tab. It is too confusing when we need to display the right click popup menu for the selected tab. When the user needs to right click and get the pop up menu for selected tab, then it changes the selected tab because of the right click.

So here is the proper solution.
First we need to identify whether the mouse event comes from the right click or the left click.
If it is a left click, then simply change the selected tab, if it is a right click, then we need to display the popup menu or do nothing.
In order to do that we need to remove the unwanted tab selection when we click on the right mouse button.
That Mouse Listener comes under the JTabbedPane UI object. It is better to override rather than remove it for future code updates.

The BasicTabbedPaneUI  has an inner class called Handler. That handler class overrides the Mouse Listener. To stop the right click tab selection and show pop up menu, we need to override this method in BasicTabbedPaneUI,

protected MouseListener createMouseListener() {
    return getHandler();
}
To get a better look and feel we should override SynthTabbedPaneUI class as well. SynthTabbedPaneUI extends BasicTabbedPaneUI.
So our inner class is like this,

private class SynthTabbedPaneUIWrapper extends SynthTabbedPaneUI {
 private MouseAdapter menuAdapter;

 /**
  * this will return the pop up menu adapter.
  *
  * @return menuAdapter - MouseAdapter
  */
 private MouseAdapter getMenuAdapter() {
  if (menuAdapter == null) {
   menuAdapter =
    new MouseAdapter() {
     @Override
     public void mouseReleased(final MouseEvent e) {
      final JTabbedPane tabbedPane = (JTabbedPane) e.getSource();

      //show only PopupMenu for right click.
      if (!tabbedPane.isEnabled() || SwingUtilities.isRightMouseButton(e)) {
       if (e.isPopupTrigger() && (e.getClickCount() == 1)) {
        //show popup menu functions goes here
       }

       return;
      }

      //change the selected tab when left click.
      changeTabItemSelection(e);
     }
    };
  }

  return menuAdapter;
 }

 /**
  * Used to Change the tab item selection when right clicked or double clicked.
  *
  * @param e - MouseEvent
  */
 private void changeTabItemSelection(final MouseEvent e) {
  final JTabbedPane tabbedPane = (JTabbedPane) e.getSource();
  final int tabIndex = tabbedPane.getUI().tabForCoordinate(tabbedPane, e.getX(), e.getY());

  if ((tabIndex >= 0) && tabbedPane.isEnabledAt(tabIndex)) {
   if ((tabIndex == tabbedPane.getSelectedIndex()) && tabbedPane.isRequestFocusEnabled()) {
    tabbedPane.requestFocus();
    tabbedPane.repaint(tabbedPane.getUI().getTabBounds(tabbedPane, tabIndex));
   } else {
    tabbedPane.setSelectedIndex(tabIndex);
   }
  }
 }

 @Override
 protected MouseListener createMouseListener() {
  return getMenuAdapter();
 }
} 

After that we can set our custom UI object into TabbedPane.

tabbedPane.setUI(new SynthTabbedPaneUIWrapper());
Here is my stackoverflow related answer for this type of problem. 

0 comments:

Post a Comment