2012-08-25 5 views
7

처음으로 클릭 할 때까지 JMenuBar가 JMenuItem을 선택한 것으로 표시하거나 JMenu 팝업을 표시하지 않습니다. JMenuBar을 클릭하면 모든 항목이 마우스를 움직입니다.호버시 JMenuBar 활성화

초기 클릭은 무시하고 마우스를 올리면 자동으로 활성화됩니다. 이것을 할 수있는 방법이 있습니까?

+3

왜 이렇게하고 싶으십니까? 모든 응용 프로그램의 모든 메뉴 모음은 다음과 같이 작동합니다. – Robin

+0

내 메뉴에는 사용자 정의 모양이 있으며이 동작은 더 자연스럽게 적용됩니다. 또한, 나는이 행동이 사용자를 위해 훨씬 더 상호 작용한다고 믿습니다. – springcorn

답변

9

길은 JMenuMouseListener을 추가하고 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); 
    } 
} 
+0

mouseEntered 리스너에 대해 알고 있는데 어떻게 mousentered에서 전체 JMenuBar를 활성화합니까? – springcorn

+0

위의 편집 된 파일 –

+0

Thanks. 저를 올바른 방향으로 올려 놓았지만, 클릭을 개별적으로 강제하는 것이 아니라 jMenuBar.activate()와 같은 간단한 방법이 있었으면합니다. JMenuItem에 대해서는 doClick() 대신에이 동작을 생성하는 최선의 방법은 setArmed (true)라고 할 수 있습니다. – springcorn

1

로마 C의를 JMenuBar의 일부로 하위 MenuItems를 사용하여 메뉴를 닫습니다.

실행 중 ((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 내에서 액세스 할 수있는 가치를 어떻게 모니터링, 나에게 약간의 테스트를했다 - 그러나 그것은 치료를한다! 심지어 중첩 된 메뉴와 함께 :) 많은 사람들이이 예제를 매우 유용하게 사용하기를 바랍니다.