JMenuBar沒有開始顯示JMenuItem s被選中或顯示JMenu彈出式窗口,直到第一次點擊。在JMenuBar中單擊某處後,所有這些項目都會響應鼠標懸停。在懸停時激活JMenuBar
我想繞過所需的初始點擊並在鼠標懸停後自動激活它。有沒有辦法做到這一點?
JMenuBar沒有開始顯示JMenuItem s被選中或顯示JMenu彈出式窗口,直到第一次點擊。在JMenuBar中單擊某處後,所有這些項目都會響應鼠標懸停。在懸停時激活JMenuBar
我想繞過所需的初始點擊並在鼠標懸停後自動激活它。有沒有辦法做到這一點?
方法是在JMenu
上添加一個MouseListener
,並收聽事件mouseEntered
。在事件處理程序中,您只需使用doClick
單擊它。例如,
jMenuFile.addMouseListener(new MouseListener(){
public void mouseEntered(MouseEvent e) {
jMenuFile.doClick();
}
...
});
一旦以編程方式點擊鼠標進入,它會自動打開彈出菜單。要激活整個JMenuBar
,您必須在每個JMenu
上添加一個偵聽器。爲此,最好分別創建一個偵聽器對象。
我有欄上兩個菜單項,所以我所做的:
MouseListener ml = new MouseListener(){
public void mouseClicked(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {
((JMenu)e.getSource()).doClick();
}
};
jMenuFile.addMouseListener(ml);
jMenuHelp.addMouseListener(ml);
如果你有欄上這麼多的菜單項,你可以遍歷它:
for (Component c: jMenuBar1.getComponents()) {
if (c instanceof JMenu){
c.addMouseListener(ml);
}
}
我瞭解mouseEntered監聽器,但是如何從mousentered激活整個JMenuBar? – springcorn
剛纔編輯 –
謝謝。這讓我走上了正軌,但我想我希望有一個更簡單的方法來做到這一點,如jMenuBar.activate(),而不是單獨強制點擊。對於JMenuItem,您不能調用doClick(),而是我相信生成此行爲的最佳方式是setArmed(true) – springcorn
羅馬C'S初始和接受的答案不會自動關閉帶有子菜單項的菜單作爲JMenuBar的一部分。運行一個((JMenu)e.getSource())。doClick();在鼠標輸入模擬單擊到JMenu父母之一,但不能簡單地添加到mouseExited方法,因爲MouseListener需要附加到子菜單項以及JMenu父母。 (它不會在正常分配給MenuBar時執行 - 只附加到父JMenu對象)。
此外,由於嘗試讓MouseExit偵聽器在鼠標離開整個Menu結構(即子菜單下拉列表)時觸發「close」方法,因此出現問題。
下面是從我的生活應用程序採取了一個有效的答案:
我解決了關閉鼠標在菜單的方法是在構造頂部運行布爾變量「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內訪問 - 但它適用於一種享受!即使嵌套菜單:)我希望很多人發現這個完整的例子非常有用。
你爲什麼要這麼做的很好的理由?所有應用程序中的所有菜單欄都表現得如此 – Robin
那麼我的菜單具有自定義外觀,而且這種行爲更適合自然。另外,我相信這種行爲對於用戶來說更加互動。 – springcorn