2012-08-25 37 views
7

JMenuBar không bắt đầu hiển thị JMenuItem s khi được chọn hoặc hiển thị các quảng cáo JMenu cho đến khi được nhấp lần đầu tiên. Sau khi bạn nhấp vào một nơi nào đó trong JMenuBar, tất cả các mục này sẽ phản hồi với các trình di chuột.Kích hoạt JMenuBar trên di chuột

Tôi muốn bỏ qua nhấp chuột ban đầu được yêu cầu và kích hoạt tự động khi di chuột. Có cách nào để làm việc này không?

+3

Bất kỳ lý do chính đáng nào khiến bạn muốn thực hiện việc này? Tất cả các thanh menu trong tất cả các ứng dụng đều hoạt động như thế – Robin

+0

Trình đơn của tôi có giao diện tùy chỉnh và hành vi này phù hợp với nó một cách tự nhiên hơn. Ngoài ra, tôi tin rằng hành vi này tương tác nhiều hơn cho người dùng. – springcorn

Trả lời

9

Cách thêm MouseListener trên JMenu và nghe sự kiện mouseEntered. Trong trình xử lý sự kiện, bạn chỉ cần nhấp vào nó bằng cách sử dụng doClick. Ví dụ:

jMenuFile.addMouseListener(new MouseListener(){ 
    public void mouseEntered(MouseEvent e) { 
     jMenuFile.doClick(); 
    } 
    ... 
}); 

Khi nhấp chuột được lập trình trên chuột, nó sẽ tự động mở menu bật lên. Để kích hoạt toàn bộ JMenuBar, bạn phải thêm người nghe trên mỗi JMenu. Với mục đích này, tốt hơn là tạo riêng một đối tượng nghe.

Tôi có hai mục menu trên thanh, vì vậy tôi đã làm:

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); 

Nếu bạn có rất nhiều các mục menu trên thanh, bạn chỉ có thể lặp nó:

for (Component c: jMenuBar1.getComponents()) { 
    if (c instanceof JMenu){ 
     c.addMouseListener(ml); 
    } 
} 
+0

Tôi hiểu người nghe mouseEntered nhưng làm thế nào để bạn kích hoạt toàn bộ JMenuBar từ những người đã biết? – springcorn

+0

vừa chỉnh sửa ở trên –

+0

Cảm ơn. Điều đó đặt tôi vào đúng hướng, nhưng tôi đoán tôi đã hy vọng có một cách đơn giản hơn để làm điều này như jMenuBar.activate(), chứ không phải là cá nhân buộc nhấp chuột. Đối với JMenuItem bạn không thể gọi doClick() thay vào đó tôi tin rằng cách tốt nhất để tạo ra hành vi này được setArmed (true) – springcorn

1

La Mã C câu trả lời ban đầu và được chấp nhận sẽ không AUTO Đóng menu với MenuItem con như một phần của JMenuBar.

Chạy ((JMenu) e.getSource()). DoClick(); trên chuộtNhập mô phỏng nhấp chuột vào một trong các bậc cha mẹ của JMenu nhưng không thể chỉ đơn giản là được thêm vào phương pháp mouseExited vì MouseListener cần phải được gắn vào MenuItems con cũng như các phụ huynh JMenu. (Mà nó không làm trong việc gán thông thường cho MenuBar - chỉ gắn vào các đối tượng JMenu mẹ).

Ngoài ra, một vấn đề phát sinh do cố gắng để người nghe MouseExit kích hoạt phương thức "đóng" CHỈ khi chuột đã rời khỏi toàn bộ cấu trúc Trình đơn (tức là menu thả xuống Trình đơn con).

Dưới đây là một câu trả lời hoàn toàn làm việc lấy từ ứng dụng trực tiếp của tôi:

Con đường tôi giải quyết menu gần trên chuột ra là để chạy một biến boolean "isMouseOut" ở phía trên cùng của các nhà xây dựng để theo dõi và sau đó phân bổ MouseListener theo cách thân thiện hơn với OO để theo dõi nhiều sự kiện MouseIn-MouseOut khi người dùng tương tác với trình đơn. Mà các cuộc gọi một trình đơn riêng biệt phương pháp Delete hành động theo trạng thái của boolean "isMouseOut". Lớp thực hiện MouseListener. Đây là cách mà nó được hoàn thành.

Tạo một ArrayList thêm tất cả các mục menu vào mảng này trước tiên.Cũng giống như vậy:

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); 

sau đó lặp qua các ArrayList ở giai đoạn này thêm một MouseListener sử dụng cho() vòng lặp:

for (Component c : aMenuItms) { 
     if (c instanceof JMenuItem) { 
      c.addMouseListener(ml); 
     } 
    } 

Bây giờ đặt cha mẹ JMenu cho thanh menu:

// 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); 

Sau đó, thêm menu thả xuốngMục trẻ em vào cha mẹ của 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); 

Thêm mouseListeners để các bậc phụ huynh JMenu như một bước riêng biệt:

for (Component c : menuBar.getComponents()) { 
     if (c instanceof JMenu) { 
      c.addMouseListener(ml); 
     } 
    } 

Bây giờ các yếu tố MenuItem con tất cả đều có thính giả của riêng họ mà là riêng biệt đến các yếu tố phụ huynh JMenu và thanh menu riêng của mình - Điều quan trọng là xác định loại đối tượng trong quá trình khởi tạo MouseListener() để bạn tự động mở menu khi di chuột qua (trong ví dụ này là cha mẹ JMenu 3x) NHƯNG CSONG tránh lỗi ngoại lệ của trẻ và cho phép nhận dạng sạch mouseOUT của cấu trúc menu mà không cần theo dõi vị trí vị trí chuột là. MouseListener như sau:

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(); 
      } 
     } 
    }; 

Ở trên chỉ mô phỏng chuột vào JMenu 'cha mẹ' (3x trong ví dụ này) vì chúng là trình kích hoạt cho menu thả xuống của trình đơn con. Phương pháp timerMenuClear() gọi trên MenuSelectionManager để trống bất cứ điểm selectedpath đã sống tại thời điểm mouseout thực:

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(); 
} 

Nó đã cho tôi một thử nghiệm nhỏ, theo dõi những giá trị nào tôi có thể truy cập vào bên trong JVM quá trình phát triển của nó - nhưng nó hoạt động một điều trị! ngay cả với các menu lồng nhau :) Tôi hy vọng nhiều người thấy ví dụ đầy đủ này rất hữu ích.

Các vấn đề liên quan