我想制作一个具有Swing
布局的Java程序,其中左侧有一个菜单,当鼠标悬停在菜单区域上时会展开,但在鼠标离开后会自动收缩。
我正试图模仿Android版的移动Youtube或Weebly的编辑器的效果。对于那些不知道的人来说,这两种布局的左侧都有菜单,当鼠标悬停在它们上面时,菜单就会展开。然后,鼠标离开该区域后,菜单再次收缩,并且不在视图中。
我能够成功地创建包含菜单的JSplitPane
,但我不知道如何在用户的鼠标悬停在JSplitPane
组件上时使其自动展开,也不知道如何使其在鼠标离开该区域后收缩。
如果有人想知道为什么:这种类型的菜单对用户来说很容易使用,但因为它在不需要的时候会隐藏起来,所以我可以有更多的空间来放置程序的主要部分。
任何帮助都将不胜感激,谢谢!
我们使用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
包括其他事件监听器。
有两个基本问题。。。
- 您需要检测鼠标何时悬停在分隔符上
- 当它存在时,"菜单"
第二个相对简单,您可以使用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);
}
});
}
}