Активировать JMenuBar при наведении
JMenuBar не начинает показыватьJMenuItem S как выбранный или отображать всплывающие окнаJMenu , пока на него не нажмут. После того, как вы нажмете где-нибудь в JMenuBar, все эти элементы реагируют на наведение курсора мыши.
Я хотел бы обойти обязательный начальный щелчок и активировать его автоматически при наведении мыши. Есть ли способ сделать это?
2 ответов:
Способ состоит в том, чтобы добавить
MouseListenerнаJMenuи слушать события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); } }
Первоначальный и принятый ответ романа с не будет автоматически закрывать меню с дочерними меню как часть JMenuBar.
Запуск a ((JMenu)e. getSource ()).doClick (); на mouseEntered имитирует щелчок в один из родителей JMenu, но не может быть просто добавлен в метод mouseExited, так как MouseListener должен быть присоединен к дочерним MenuItems, а также к родителям JMenu. (Чего он не делает в обычном назначении к MenuBar-только прикрепление к родительскому JMenu объекты).
Кроме того, проблема возникает из-за попытки заставить прослушиватель MouseExit запускать метод "close" только тогда, когда мышь покинула всю структуру меню (т. е. дочерние раскрывающиеся меню).
Ниже приведен полностью рабочий ответ, взятый из моего живого приложения:
Способ, которым я решил меню close on mouse out, состоял в том, чтобы запустить булеву переменную "isMouseOut" в верхней части конструктора, чтобы отслеживать, а затем выделить MouseListener более удобным способом, чтобы следите за несколькими событиями MouseIn-MouseOut, когда пользователь взаимодействует с меню. Который вызывает отдельный метод menuClear, действующий на состояние булева "isMouseOut". Класс реализует MouseListener. Вот как это делается.
Создайте ArrayList, добавив сначала все пункты меню в этот массив. Вот так:
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);Затем выполните итерацию над arrayList на этом этапе, добавив MouseListener, используя цикл for ():
for (Component c : aMenuItms) { if (c instanceof JMenuItem) { c.addMouseListener(ml); } }Теперь установите jmenu родителей для MenuBar:
// 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);Затем добавьте выпадающее меню 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); } }Теперь, когда дочерние элементы menuItem все имеют свои собственные прослушиватели, которые отделены от родительских элементов JMenu и самого MenuBar-важно определить тип объекта в экземпляре MouseListener (), чтобы вы получили автоматическое открытие меню при наведении курсора мыши (в этом примере 3x JMenu родители), но также избегает ошибок дочерних исключений и позволяет четко идентифицировать mouseOUT структуры меню, не пытаясь контролировать, где находится положение мыши. Муселистер выглядит следующим образом:
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 'родители' (3x в этом примере), поскольку они являются триггерами для выпадающих меню дочернего. Метод timerMenuClear() вызывает MenuSelectionManager, чтобы очистить любую выбранную точку пути, которая была в реальном времени во время реального времени. mouseOUT:
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 во время его разработки - но это работает здорово! даже с вложенными меню:) я надеюсь, что многие найдут этот полный пример очень полезным.
Comments