1 /*
   2  * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 /* @test
  24    @bug 4634626
  25    @summary Implement context popup menus for components
  26    @author Alexander Zuev
  27    @library ../../../../lib/testlibrary
  28    @build ExtendedRobot
  29    @run applet bug4634626.html
  30 */
  31 import javax.swing.*;
  32 import java.awt.event.*;
  33 import java.awt.*;
  34 
  35 public class bug4634626 extends JApplet {
  36 
  37     public boolean passed = true;
  38     public boolean done = false;
  39 
  40     public JFrame mainFrame = new JFrame("Bug4634626");
  41     public JRootPane rootPane = mainFrame.getRootPane();
  42     public JPanel contentPane = new JPanel();
  43     public JButton nopButton = new JButton("No popup button");
  44     public JTextArea someText = new JTextArea("Some text here", 20, 10);
  45     public JButton popButton = new JButton("Button with the popup");
  46 
  47     public JPopupMenu btnPopup = new JPopupMenu();
  48     public JPopupMenu commonPopup = new JPopupMenu();
  49     static public Error toBeThrown = null;
  50     static int popTrig = MouseEvent.BUTTON3_MASK;
  51     static boolean popt = false;
  52 
  53     public static class MouseWatcher extends MouseAdapter {
  54         public void mousePressed(MouseEvent e) {
  55             if(e.isPopupTrigger()) popt = true;
  56             if(e.getComponent() != null &&
  57                e.getComponent() instanceof JComponent &&
  58                e.isPopupTrigger() &&
  59                ((JComponent)e.getComponent()).getComponentPopupMenu() != null) {
  60                 toBeThrown =
  61                   new Error("The event got thru the component with popup: "
  62                   + e);
  63             }
  64         }
  65         public void mouseReleased(MouseEvent e) {
  66             if(e.isPopupTrigger()) popt = true;
  67             if(e.getComponent() != null &&
  68                e.getComponent() instanceof JComponent &&
  69                e.isPopupTrigger() &&
  70                ((JComponent)e.getComponent()).getComponentPopupMenu() != null) {
  71                 toBeThrown =
  72                   new Error("The event got thru the component with popup: "
  73                   + e);
  74             }
  75             if(toBeThrown != null) {
  76                 throw(toBeThrown);
  77             }
  78         }
  79     }
  80 
  81     public static MouseWatcher mouser = new MouseWatcher();
  82 
  83     public void init() {
  84 
  85         try {
  86             popButton.setComponentPopupMenu(null);
  87             popButton.setComponentPopupMenu(null);
  88             popButton.setComponentPopupMenu(btnPopup);
  89             popButton.setComponentPopupMenu(null);
  90         } catch(Exception ex) {
  91             System.err.println("Unexpected exception was thrown by " +
  92                                "setComponentPopupMenu() method: " + ex);
  93         }
  94         btnPopup.add("Button 1");
  95         btnPopup.add("Button 2");
  96         btnPopup.add("Button 3");
  97         popButton.setComponentPopupMenu(btnPopup);
  98         popButton.addMouseListener(mouser);
  99         commonPopup.add("One");
 100         commonPopup.add("Two");
 101         commonPopup.add("Three");
 102 
 103         contentPane.setLayout(new BorderLayout());
 104         contentPane.setComponentPopupMenu(commonPopup);
 105         contentPane.addMouseListener(mouser);
 106         contentPane.add(nopButton, BorderLayout.NORTH);
 107         nopButton.addMouseListener(mouser);
 108         contentPane.add(popButton, BorderLayout.SOUTH);
 109         someText.addMouseListener(mouser);
 110         contentPane.add(someText, BorderLayout.CENTER);
 111         mainFrame.setContentPane(contentPane);
 112 
 113         mainFrame.pack();
 114         mainFrame.setLocation(50, 50);
 115 
 116         mainFrame.addWindowListener(new TestStateListener());
 117         mainFrame.setVisible(true);
 118 
 119         while(!done) Thread.yield();
 120 
 121         if(!passed) {
 122             throw new RuntimeException("Test failed");
 123         }
 124 
 125     }
 126 
 127     public class TestStateListener extends WindowAdapter {
 128         public void windowOpened(WindowEvent ev) {
 129             try {
 130                 ev.getWindow().toFront();
 131                 ev.getWindow().requestFocus();
 132                 new Thread(new RobotThread()).start();
 133             } catch (Exception ex) {
 134                 throw new RuntimeException("Thread Exception");
 135             }
 136         }
 137     }
 138 
 139     class RobotThread implements Runnable {
 140         public void run() {
 141             ExtendedRobot robo;
 142             try {
 143                 robo = new ExtendedRobot();
 144             }catch(Exception ex) {
 145                 ex.printStackTrace();
 146                 throw new RuntimeException("Cannot create Robot");
 147             }
 148             robo.setAutoDelay(100);
 149             robo.waitForIdle();
 150 
 151             // Determine working popup trigger event
 152             clickMouseOn(robo, nopButton, popTrig);
 153             robo.waitForIdle();
 154             robo.delay(500);
 155             if(!popt) popTrig = MouseEvent.BUTTON2_MASK;
 156 
 157             // Inheritance is OFF by default. Popup should not appear.
 158             clickMouseOn(robo, someText, popTrig);
 159 
 160             // Set inheritance ON watch for popup.
 161             someText.setInheritsPopupMenu(true);
 162             clickMouseOn(robo, someText, popTrig);
 163             robo.waitForIdle();
 164             robo.delay(500);
 165             if(!commonPopup.isVisible()) {
 166                 toBeThrown = new Error("Popup should be visible");
 167                 passed = false;
 168             }
 169             // Dispose popup.
 170             robo.type(KeyEvent.VK_ESCAPE);
 171             robo.waitForIdle();
 172             someText.setInheritsPopupMenu(false);
 173 
 174             // Button with popup assigned. Wathch for popup.
 175             clickMouseOn(robo, popButton, popTrig);
 176             robo.waitForIdle();
 177             robo.delay(500);
 178             if(!btnPopup.isVisible()) {
 179                 toBeThrown = new Error("Popup should be visible");
 180                 passed = false;
 181             }
 182             // Dispose popup.
 183             robo.type(KeyEvent.VK_ESCAPE);
 184             // Test finished.
 185             done = true;
 186         }
 187     }
 188 
 189 
 190 
 191     public void destroy() {
 192         if(!passed) {
 193             throw(toBeThrown);
 194         }
 195     }
 196     private void clickMouseOn(ExtendedRobot robot, Component c, int button) {
 197         java.awt.Point p = c.getLocationOnScreen();
 198         java.awt.Dimension size = c.getSize();
 199         p.x += size.width / 2;
 200         p.y += size.height / 2;
 201         robot.mouseMove(p.x, p.y);
 202         robot.delay(100);
 203         robot.click(button);
 204     }
 205 }