Timotheus
Timotheus

Reputation: 2340

MouseEvent of JTabbedPane

I want to show a small popup menu when you right-click a tab, now this is working fine but when you right click it also selects that tab which is unwanted.

So my idea was to make a new class, extend JTabbedPane and recode those mouse events. Problem is that I have no idea where to start, I was browsing its source but I can't find what part is handeling the mouseEvents.

Tabs.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent me) {
        if(me.getButton()==3){
            int tabNr = ((TabbedPaneUI)Tabs.getUI()).tabForCoordinate(Tabs, me.getX(), me.getY());
            Component clickedTab = EventsConfig.window.MainTabs.getComponentAt(tabNr);
            newMenu(clickedTab, me.getX(), me.getY());
        }
    }
});  

Upvotes: 2

Views: 4384

Answers (4)

YAS_Bangamuwage
YAS_Bangamuwage

Reputation: 194

This article will helpful for removing unwanted tab selection when you click right mouse button. Stop right click Event on JTabbedPane

I liked to add more about removing Mouse Listeners. Try to override the method rather than removing it. It's better for future code updates.

The problem is BasicTabbedPaneUI's have inner class called Handler. That handler class override Mouse Listener. To stop right click tab selection and show pop up menu; we need to override this method in BasicTabbedPaneUI,

protected MouseListener createMouseListener() {
    return getHandler();
}

To get better look and feel we should override SynthTabbedPaneUI class. SynthTabbedPaneUI is extends BasicTabbedPaneUI.

So our inner class is like this,

private class SynthTabbedPaneUIWrapper extends SynthTabbedPaneUI
{
   private MouseAdapter menuAdapter;

   private MouseAdapter getMenuAdapter()
   {
    if (menuAdapter == null)
    {
      menuAdapter =
         new MouseAdapter()
        {
           @Override
           public void mouseReleased(final MouseEvent e)
           {
              //implement to stop right click tab selection
              //implement to show pop up menu
           }
        };
    }
  }

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

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

 tabbedPane.setUI(new SynthTabbedPaneUIWrapper());

Upvotes: 0

wzberger
wzberger

Reputation: 933

A possible workaround is to set your custom tab component for each tab - see JTabbedPane#setTabComponentAt(...). Add a mouse handler to your custom tab component and redispatch left click events to the tabbedPane as described at http://www.jyloo.com/news/?pubId=1315817317000.

The custom tab component can be a simple JLabel (used for the tab title) or a container for multiple components. Depending on your requirements you can e.g. add an arrow button which will open a popup menu by left clicking the related button.

Upvotes: 1

kleopatra
kleopatra

Reputation: 51525

Beware: dirty hack ahead! The only reason I recommend it, is that I consider the behaviour (select on right press) a bug in the BasicTabbedPaneUI's Handler.

The basic idea is to grab the listener installed by the ui, remove it, wrap into a custom listener which delegates everything except a right pressed to the original and add that to the pane:

private void installMouseListenerWrapper(JComponent tabbedPane) {
    MouseListener handler = findUIMouseListener(tabbedPane);
    tabbedPane.removeMouseListener(handler);
    tabbedPane.addMouseListener(new MouseListenerWrapper(handler));
}

private MouseListener findUIMouseListener(JComponent tabbedPane) {
    MouseListener[] listeners = tabbedPane.getMouseListeners();
    for (MouseListener l : listeners) {
        if (l.getClass().getName().contains("$Handler")) {
            return l;
        }
    }
    return null;
}

public static class MouseListenerWrapper implements MouseListener {

    private MouseListener delegate;

    public MouseListenerWrapper(MouseListener delegate) {
        this.delegate = delegate;
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        delegate.mouseClicked(e);
    }

    @Override
    public void mousePressed(MouseEvent e) {
        if (SwingUtilities.isRightMouseButton(e)) return;
        delegate.mousePressed(e);
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        delegate.mouseReleased(e);
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        delegate.mouseEntered(e);
    }

    @Override
    public void mouseExited(MouseEvent e) {
        delegate.mouseExited(e);
    }

}

Upvotes: 4

mKorbel
mKorbel

Reputation: 109813

then you have to add JPopupMenu (or JToolTip on MouseHoverOver ) to the JTabbedPane

Upvotes: 1

Related Questions