有 Java 编程相关的问题?

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

java如何使JSplitPane在鼠标悬停时自动展开?

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

我试图模仿Android版移动Youtube或Weebly的编辑器的效果。对于那些不知道的人来说,这两种布局在左边都有菜单,当鼠标悬停在上面时,菜单会展开。然后,鼠标离开该区域后,菜单再次收缩,消失在视野之外

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

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

任何帮助都将不胜感激,谢谢


共 (2) 个答案

  1. # 1 楼答案

    有两个基本问题

    1. 您需要检测鼠标何时悬停在分隔符上,以及
    2. 当“菜单”存在时

    第二个相对简单,您可以使用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);
                }
            });
        }
    
    }
    
  2. # 2 楼答案

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

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

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

    查看官方教程页面,了解:^{}包括其他事件侦听器