끔찍한 해킹이 필요 없습니다. Java 내의 CSS를 사용하여 하위 메뉴가있는 MenuBar 자동 숨기기를 구현할 수 있습니다. Parent + Children 드롭 다운 메뉴에서 mouseover opening과 mouseOut 클로저를 사용하여 다른 사람들이 사용할 수 있도록 각 부분에 대한 설명과 함께 완전히 작동하는 예제를 만들었습니다.
사람들이 목격 한 일반적인 문제는 ((JMenu) e.getSource())를 실행하는 것입니다. doClick(); mouseEntered는 JMenu 부모 중 하나에 대한 클릭을 시뮬레이트하지만 MouseExited 메서드에 단순히 추가 할 수는 없습니다. MouseListener는 자식 MenuItems 및 JMenu 부모에 연결되어야하기 때문에. (MenuBar에 대한 일반적인 할당에서는 수행하지 않습니다 - 부모 JMenu 객체에만 붙임).
또한 마우스가 전체 메뉴 구조 (예 : 하위 메뉴 드롭 다운)를 떠난 경우에만 MouseExit 수신기에서 "닫기"메서드를 실행하려고하면 문제가 발생합니다.다음은
가 완벽하게 작동 대답은 내 실제 응용 프로그램에서 가져온 것입니다 :
내가 마우스 아웃에 가까운 메뉴를 해결하는 방법은 추적 할 생성자의 상단에 부울 변수 "isMouseOut"를 실행하는 것이 었습니다 , 그리고 사용자가 메뉴와 상호 작용할 때 여러 개의 MouseIn-MouseOut 이벤트를 추적하기 위해 좀 더 OO 친숙한 방식으로 MouseListener를 할당하십시오. boolean "isMouseOut"상태에 따라 동작하는 별도의 menuClear 메서드를 호출합니다. 이 클래스는 MouseListener를 구현합니다. 이것이 그 방법입니다.
먼저이 배열에 모든 메뉴 항목을 추가하는 ArrayList를 만듭니다. 그래서 같이 : MenuBar을위한
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);
다음에() 루프를 사용하여 모든 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);
,
은 별도의 단계로는 JMenu 부모에있는 MouseListener를 추가
이제 아이는 menuItem 요소 모두가 부모 JMenu를 요소와의 MenuBar 자체에 분리되어 자신의 청취자를 가지고
for (Component c : menuBar.getComponents()) {
if (c instanceof JMenu) {
c.addMouseListener(ml);
}
}
- 파악하는 것이 중요하다 MouseOver (이 예제에서는 3x JMenu 부모)에서 메뉴를 자동으로 열 수 있도록 MouseListener() 인스턴스화 내의 객체 유형 또한 자식 예외 오류를 피하고 메뉴 구조의 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();
}
}
};
위는 그들 만이 하위 메뉴 드롭 다운에 대한 트리거과 마찬가지로 마우스가 (이 예에서는 3 배)이 JMenu를 '부모'로 클릭 시뮬레이션합니다. timerMenuClear() 메소드는 어떤 selectedpath 포인트는 실제로 마우스의 시점에서 방송했습니다 비워 MenuSelectionManager에 다음과 같이 요청합니다
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 내에서 액세스 할 수있는 가치를 어떻게 모니터링, 나에게 약간의 테스트를했다 - 그러나 그것은 치료를한다! 심지어 중첩 된 메뉴와 함께 :) 많은 사람들이이 예제를 매우 유용하게 사용하기를 바랍니다.
아아는 끔찍한 해킹은 우리가해야했을 것입니다. 데모를 좋아하지만 프로젝트에 다른 프레임 워크를 추가하는 것은이 시점에서 일어나지 않을 것입니다. 제안을 주셔서 감사합니다. – bikesandcode