你也可以添加一个透明的面板区域到窗口中,附上一份单独的MouseListener该区域面板,这样就可以使一个无形的菜单出现!但这个想法并未包含在我的例子中。
下面是从我的生活应用程序采取了一个有效的自动隐藏分层菜单栏:
我解决了鼠标在菜单关闭的方法是在构造顶部运行布尔变量“isMouseOut”保持跟踪,然后以更友好的OO方式分配MouseListener,以便跟踪用户与菜单交互时的多个MouseIn-MouseOut事件。它调用一个单独的menuClear方法来处理布尔型“isMouseOut”的状态。该类实现MouseListener。这是如何完成的。
创建一个ArrayList,首先将所有菜单项添加到该数组中。像这样:
for (Component c : aMenuItms) {
if (c instanceof JMenuItem) {
c.addMouseListener(ml);
}
}
现在设置JMenu的父母为菜单栏:
// Now set JMenu parents on MenuBar
final JMenu mnFile = new JMenu("File");
menuBar.add(mnFile).setFont(menuFont);
final JMenu mnView = new JMenu("View");
menuBar.add(mnView).setFont(menuFont);
final JMenu mnHelp = new JMenu("Help");
menuBar.add(mnHelp).setFont(menuFont);
Font menuFont = new Font("Arial", Font.PLAIN, 12);
JMenuBar menuBar = new JMenuBar();
getContentPane().add(menuBar, BorderLayout.NORTH);
// Array of MenuItems
ArrayList<JMenuItem> aMenuItms = new ArrayList<JMenuItem>();
JMenuItem mntmRefresh = new JMenuItem("Refresh");
JMenuItem mntmNew = new JMenuItem("New");
JMenuItem mntmNormal = new JMenuItem("Normal");
JMenuItem mntmMax = new JMenuItem("Max");
JMenuItem mntmStatus = new JMenuItem("Status");
JMenuItem mntmFeedback = new JMenuItem("Send Feedback");
JMenuItem mntmEtsyTWebsite = new JMenuItem("EtsyT website");
JMenuItem mntmAbout = new JMenuItem("About");
aMenuItms.add(mntmRefresh);
aMenuItms.add(mntmNew);
aMenuItms.add(mntmNormal);
aMenuItms.add(mntmMax);
aMenuItms.add(mntmStatus);
aMenuItms.add(mntmFeedback);
aMenuItms.add(mntmEtsyTWebsite);
aMenuItms.add(mntmAbout);
那么在这个阶段使用for()循环添加的MouseListener在ArrayList的迭代然后将下拉菜单项子项添加到JMenu父项:
// Now set menuItems as children of JMenu parents
mnFile.add(mntmRefresh).setFont(menuFont);
mnFile.add(mntmNew).setFont(menuFont);
mnView.add(mntmNormal).setFont(menuFont);
mnView.add(mntmMax).setFont(menuFont);
mnHelp.add(mntmStatus).setFont(menuFont);
mnHelp.add(mntmFeedback).setFont(menuFont);
mnHelp.add(mntmEtsyTWebsite).setFont(menuFont);
mnHelp.add(mntmAbout).setFont(menuFont);
添加mouseListeners到JMenu父母作为单独的步骤:
for (Component c : menuBar.getComponents()) {
if (c instanceof JMenu) {
c.addMouseListener(ml);
}
}
现在孩子菜单项元素都有自己的听众,是独立于母公司JMenu的元素和菜单栏本身 - 识别是很重要的MouseListener()实例中的对象类型,以便您可以在鼠标悬停时获得菜单自动打开(在本例中为3x JMenu父项),但也避免子例外错误,并允许清理识别菜单结构的mouseOUT,而不尝试监视鼠标位置是。该的MouseListener如下:
MouseListener ml = new MouseListener() {
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
isMouseOut = true;
timerMenuClear();
}
public void mouseEntered(MouseEvent e) {
isMouseOut = false;
Object eSource = e.getSource();
if(eSource == mnHelp || eSource == mnView || eSource == mnFile){
((JMenu) eSource).doClick();
}
}
};
以上只是模拟鼠标点击进入JMenu的父母(3次在这个例子中),因为它们是为孩子菜单的下拉列表中的触发器。该timerMenuClear()方法调用的对象MenuSelectionManager清空任何selectedpath点是活在真实的鼠标移开时:
public void timerMenuClear(){
ActionListener task = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(isMouseOut == true){
System.out.println("Timer");
MenuSelectionManager.defaultManager().clearSelectedPath();
}
}
};
//Delay timer half a second to ensure real mouseOUT
Timer timer = new Timer(1000, task);
timer.setInitialDelay(500);
timer.setRepeats(false);
timer.start();
}
我花了一个小测试,监测什么样的价值观,我可以在其发展过程中的JVM内访问 - 但它适用于一种享受!即使嵌套菜单:)我希望很多人发现这个完整的例子非常有用。
我想过尝试在getJMenuBar()。isSelected()方法中添加一个条件,但不幸的是,即使将选择放入另一个组件,选择模型也不会更新回false,之后消失。 – Gnoupi 2010-05-26 10:17:00