有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JTabbedPane的java MouseeEvent

我想显示一个小弹出菜单,当你右键点击一个标签,现在这是工作正常,但当你右键点击它也选择了该标签,这是不需要的

所以我的想法是创建一个新类,扩展JTabbedPane并重新编码这些鼠标事件。问题是我不知道从哪里开始,我正在浏览它的source,但我找不到处理鼠标事件的部分

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());
        }
    }
});  

共 (4) 个答案

  1. # 1 楼答案

    小心:前面是肮脏的黑客!我推荐它的唯一原因是,我考虑了Basic Tab床单的处理程序中的一个错误(右键按下)。

    其基本思想是抓取用户界面安装的监听器,将其移除,封装到自定义监听器中,该监听器将除右键之外的所有内容委托给原始监听器,并将其添加到窗格中:

    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);
        }
    
    }
    
  2. # 2 楼答案

    一种可能的解决方法是为每个选项卡设置自定义选项卡组件——请参阅JTabbedPane#setTabComponentAt(…)。将鼠标处理程序添加到自定义选项卡组件中,并将左键单击事件重新修补到选项卡窗格中,如http://www.jyloo.com/news/?pubId=1315817317000所述

    自定义选项卡组件可以是一个简单的JLabel(用于选项卡标题)或多个组件的容器。根据您的要求,您可以添加箭头按钮,通过左键单击相关按钮打开弹出菜单

  3. # 3 楼答案

    当你点击鼠标右键时,这篇文章将有助于移除不需要的标签选择。 Stop right click Event on JTabbedPane

    我喜欢添加更多关于删除鼠标侦听器的内容。 尝试重写该方法,而不是删除它。这对以后的代码更新更好

    问题是BasicTabbedPaneUI的内部类名为Handler。该处理程序类重写鼠标侦听器。 要停止右键单击选项卡选择并显示弹出菜单;我们需要在BasicTabbedPaneUI中重写这个方法

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

    为了获得更好的外观和感觉,我们应该覆盖SynthTabbedPaneUI类。 SynthTabbedPaneUI是扩展的BasicTabbedPaneUI

    所以我们的内心世界是这样的

    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();
      }
    }
    

    之后,我们可以将自定义UI对象设置为TabbedPane

     tabbedPane.setUI(new SynthTabbedPaneUIWrapper());