如何让鼠标悬停时JSplitPane自动扩展?

时间:2013-11-27 19:14:27

标签: java swing mouseevent jscrollpane jsplitpane

我想制作一个带有Swing布局的Java程序,左边有一个菜单,当鼠标悬停在菜单区域上时会展开,但鼠标离开后自动收缩。

我试图模仿像Android的移动Youtube或者Weebly的编辑器这样的效果。对于那些不知道的人来说,两个布局都有左边的菜单,当鼠标悬停在它们上面时会扩展。然后在鼠标离开该区域后,菜单再次收缩并且不在视野范围内。

我能够成功创建包含我的菜单的JSplitPane,但我不知道当用户的鼠标悬停在JSplitPane组件上时如何使其自动展开,或者如何使其合同鼠标离开该区域后。

如果有人想知道原因:这种类型的菜单很容易供用户使用,但因为它在不需要时隐藏起来,所以我可以为程序的主要部分留出更多空间。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

好好利用jSplitPan.setDividerLocation(location);:设置分隔符的位置。 location - 指定特定于UI的值(通常为像素数)的int。

jSplitPane1.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseMoved(MouseEvent evt) {
                // use evt.getSource() if needed
                jSplitPan1.setDividerLocation(location);
            }
        });

您可能需要稍微智能地计算分频器位置。提示:通过计算相关的首选大小提示。相关部分应由您发现。

查看官方教程页面,了解:How to use MouseMotionListeners包括其他事件监听器。

答案 1 :(得分:2)

有两个基本问题......

  1. 您需要检测鼠标悬停在分隔线上的时间和
  2. 如果存在“菜单”
  3. 第二个相对简单,您可以使用MouseListener并监控mouseExit事件,在鼠标离开时设置拆分窗格分隔线的位置。

    这很复杂,好像用户通过跨越分隔符存在“菜单”,这可能会触发“菜单”再次显示...

    第一个问题更复杂,因为JSplitPane包含三个组件,左侧和右侧组件,还有一个分隔器组件。 JSplitPane实际上不允许访问分隔符,这是相当烦人的,因为它使用它自己的鼠标侦听器,它会阻止鼠标事件进入分裂本身。

    相反,您需要通过UI委托获得对它的访问权。

    一旦你设置了鼠标监听器,你需要确保只有在菜单被隐藏时才显示菜单,为此,我只需检查“菜单”组件的大小

    例如......

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Insets;
    import java.awt.Rectangle;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.awt.event.MouseMotionAdapter;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JSplitPane;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.plaf.basic.BasicSplitPaneDivider;
    import javax.swing.plaf.basic.BasicSplitPaneUI;
    
    public class TestSpltPane {
    
        public static void main(String[] args) {
            new TestSpltPane();
        }
    
        public TestSpltPane() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    final JPanel left = new JPanel();
                    left.setBackground(Color.RED);
                    left.setPreferredSize(new Dimension(100, 100));
                    JPanel right = new JPanel();
                    right.setBackground(Color.BLUE);
                    right.setPreferredSize(new Dimension(100, 100));
                    final JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, right);
                    sp.setDividerLocation(0);
    
                    BasicSplitPaneDivider divider = ((BasicSplitPaneUI) sp.getUI()).getDivider();
                    divider.addMouseListener(new MouseAdapter() {
    
                        @Override
                        public void mouseEntered(MouseEvent e) {
                            if (left.getWidth() == 0) {
                                sp.setDividerLocation(100);
                            }
                        }
    
                    });
    
                    left.addMouseListener(new MouseAdapter() {
    
                        @Override
                        public void mouseExited(MouseEvent e) {
                            sp.setDividerLocation(0);
                        }
    
                    });
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(sp);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
    }