1 /*
   2   test
   3   @bug 6390326
   4   @summary REGRESSION: Broken mouse behaviour of menus partially outside the main window.
   5   @author oleg.sukhodolsky: area=awt-drab
   6   @run applet AutomaticAppletTest.html
   7 */
   8 
   9 /**
  10  * MenuDragEvents.java
  11  *
  12  * summary: REGRESSION: Broken mouse behaviour of menus partially outside the main window.
  13  */
  14 
  15 import java.applet.Applet;
  16 import java.awt.AWTEvent;
  17 import java.awt.AWTException;
  18 import java.awt.BorderLayout;
  19 import java.awt.Point;
  20 import java.awt.Robot;
  21 import java.awt.Toolkit;
  22 
  23 import java.awt.event.ActionEvent;
  24 import java.awt.event.ActionListener;
  25 import java.awt.event.AWTEventListener;
  26 import java.awt.event.InputEvent;
  27 import java.awt.event.KeyEvent;
  28 import java.awt.event.MouseEvent;
  29 
  30 import javax.swing.JFrame;
  31 import javax.swing.JMenu;
  32 import javax.swing.JMenuBar;
  33 import javax.swing.JMenuItem;
  34 import javax.swing.WindowConstants;
  35 
  36 import javax.swing.event.MenuDragMouseEvent;
  37 import javax.swing.event.MenuDragMouseListener;
  38 
  39 import sun.awt.SunToolkit;
  40 
  41 public class MenuDragEvents extends Applet
  42 {
  43     //Declare things used in the test, like buttons and labels here
  44     boolean mouseDragged = false;
  45     boolean mouseEntered = false;
  46     boolean mouseReleased = false;
  47     boolean actionReceived = false;
  48 
  49     public void init()
  50     {
  51         // Set up the environment -- set the layout manager, add
  52         // buttons, etc.
  53 
  54         setLayout (new BorderLayout ());
  55 
  56     }//End  init()
  57 
  58     public void start ()
  59     {
  60         //Get things going.  Request focus, set size, et cetera
  61         setSize (200,200);
  62         setVisible(true);
  63         validate();
  64 
  65         Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
  66                 public void eventDispatched(AWTEvent event) {
  67                     int id = event.getID();
  68                     if (id == MouseEvent.MOUSE_ENTERED || id == MouseEvent.MOUSE_EXITED) {
  69                         System.err.println(event);
  70                     }
  71                 }
  72             }, AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
  73         JMenuBar mb = new JMenuBar();
  74 
  75         JMenu m = new JMenu("A Menu");
  76         mb.add(m);
  77 
  78         JMenuItem i = new JMenuItem("A menu item",KeyEvent.VK_A);
  79         m.add(i);
  80 
  81         m = new JMenu("Another Menu");
  82         mb.add(m);
  83         i = new JMenuItem("Yet another menu item",KeyEvent.VK_Y);
  84         m.add(i);
  85         i.addMenuDragMouseListener(new MenuDragMouseListener() {
  86                 public void menuDragMouseDragged(MenuDragMouseEvent e) {
  87                     System.err.println(e);
  88                     mouseDragged = true;
  89                 }
  90                 public void menuDragMouseEntered(MenuDragMouseEvent e) {
  91                     System.err.println(e);
  92                     mouseEntered = true;
  93                 }
  94                 public void menuDragMouseReleased(MenuDragMouseEvent e) {
  95                     System.err.println(e);
  96                     mouseReleased = true;
  97                 }
  98                 // perhaps we need to test mouse exited too
  99                 // but this doesn't work even with tiger
 100                 public void menuDragMouseExited(MenuDragMouseEvent e) {
 101                     System.err.println(e);
 102                 }
 103             });
 104 
 105         i.addActionListener(new ActionListener() {
 106                 public void actionPerformed(ActionEvent ae) {
 107                     System.err.println(ae);
 108                     actionReceived = true;
 109                 }
 110             });
 111 
 112         JFrame frame = new JFrame("Menu");
 113         frame.setJMenuBar(mb);
 114         frame.setSize(200, 200);
 115         frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
 116         frame.setVisible(true);
 117 
 118         Robot r = null;
 119         try {
 120             r = new Robot();
 121         }
 122         catch (AWTException ae) {
 123             throw new RuntimeException(ae);
 124         }
 125 
 126         SunToolkit tk = (SunToolkit) Toolkit.getDefaultToolkit();
 127         tk.realSync();
 128 
 129         Point loc = m.getLocationOnScreen();
 130         loc.x += m.getWidth() / 2;
 131         loc.y += m.getHeight() / 2;
 132         r.mouseMove(loc.x, loc.y);
 133         r.mousePress(InputEvent.BUTTON1_MASK);
 134 
 135         tk.realSync();
 136 
 137         Point loc2 = i.getLocationOnScreen();
 138         loc2.x += i.getWidth() / 2;
 139         loc2.y += i.getHeight() / 2;
 140 
 141         // move from menu on menubar to menu item
 142         dragMouse(r, loc, loc2);
 143         r.mouseRelease(InputEvent.BUTTON1_MASK);
 144         tk.realSync();
 145 
 146         if (!mouseEntered || !mouseDragged || !mouseReleased || !actionReceived) {
 147             throw new RuntimeException("we expected to receive both mouseEntered and MouseDragged ("
 148                                        + mouseEntered + ", " + mouseDragged + ", " + mouseReleased
 149                                        + ", " + actionReceived + ")");
 150         }
 151 
 152         System.out.println("Test passed");
 153     }// start()
 154 
 155     void dragMouse(Robot r, Point from, Point to) {
 156         final int n_step = 10;
 157         int step_x = (to.x - from.x) / n_step;
 158         int step_y = (to.y - from.y) / n_step;
 159         int x = from.x;
 160         int y = from.y;
 161         for (int idx = 0; idx < n_step; idx++) {
 162             x += step_x;
 163             y += step_y;
 164             r.mouseMove(x, y);
 165             r.delay(10);
 166         }
 167         if (x != to.x || y != to.y) {
 168             r.mouseMove(to.x, to.y);
 169             r.delay(10);
 170         }
 171     }
 172 
 173 }// class MenuDragEvents