Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/javax/swing/JMenu/8071705/bug8071705.java
38854 views
/*1* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 807170526* @summary Java application menu misbehaves when running multiple screen stacked vertically27* @build bug807170528* @run main/othervm bug807170529*/3031import java.awt.Dimension;32import java.awt.GraphicsConfiguration;33import java.awt.GraphicsDevice;34import java.awt.GraphicsEnvironment;35import java.awt.Point;36import java.awt.Rectangle;37import java.awt.Toolkit;38import java.awt.event.ComponentAdapter;39import java.awt.event.ComponentEvent;40import java.awt.event.KeyEvent;41import java.util.concurrent.CountDownLatch;4243import javax.swing.JFrame;44import javax.swing.JMenu;45import javax.swing.JMenuBar;46import javax.swing.JMenuItem;47import javax.swing.JPopupMenu;48import javax.swing.SwingUtilities;49import javax.swing.UIManager;5051public class bug8071705 {5253public static void main(String[] args) throws Exception {5455final CountDownLatch latch = new CountDownLatch(1);56final boolean [] result = new boolean[1];5758SwingUtilities.invokeLater(new Runnable() {59@Override60public void run() {61JFrame frame = createGUI();62GraphicsDevice[] devices = checkScreens();6364// check if we have more than one and if they are stacked65// vertically66GraphicsDevice device = checkConfigs(devices);67if (device == null) {68// just pass the test69frame.dispose();70result[0] = true;71latch.countDown();72} else {73FrameListener listener =74new FrameListener(device, latch, result);75frame.addComponentListener(listener);76frame.setVisible(true);77}78}79});8081latch.await();8283if (result[0] == false) {84throw new RuntimeException("popup menu rendered in wrong position");85}8687System.out.println("OK");88}8990private static GraphicsDevice[] checkScreens() {91GraphicsEnvironment ge =92GraphicsEnvironment.getLocalGraphicsEnvironment();93return ge.getScreenDevices();94}9596private static JFrame createGUI() {97JMenuBar menuBar = new JMenuBar();98JMenu menu = new JMenu("Some menu");99menuBar.add(menu);100101for (int i = 0; i < 10; i++) {102menu.add(new JMenuItem("Some menu #" + i));103}104105JFrame frame = new JFrame();106frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);107frame.setMinimumSize(new Dimension(200, 200));108frame.setJMenuBar(menuBar);109return frame;110}111112private static GraphicsDevice checkConfigs(GraphicsDevice[] devices) {113114GraphicsDevice correctDevice = null;115if (devices.length < 2) {116return correctDevice;117}118119Toolkit toolkit = Toolkit.getDefaultToolkit();120Rectangle screenBounds = new Rectangle(toolkit.getScreenSize());121int halfScreen = screenBounds.height/2;122123for(int i = 0; i < devices.length; i++) {124if(devices[i].getType() == GraphicsDevice.TYPE_RASTER_SCREEN) {125GraphicsConfiguration conf =126devices[i].getDefaultConfiguration();127Rectangle bounds = conf.getBounds();128if (bounds.y >= halfScreen) {129// found130correctDevice = devices[i];131break;132}133}134}135return correctDevice;136}137138private static class FrameListener extends ComponentAdapter {139140private GraphicsDevice device;141private CountDownLatch latch;142private boolean [] result;143public FrameListener(GraphicsDevice device,144CountDownLatch latch,145boolean [] result)146{147this.device = device;148this.latch = latch;149this.result = result;150}151152@Override153public void componentShown(ComponentEvent e) {154JFrame frame = (JFrame) e.getComponent();155156runActualTest(device, latch, frame, result);157158frame.setVisible(false);159frame.dispose();160latch.countDown();161}162}163164private static Rectangle setLocation(JFrame frame, GraphicsDevice device) {165GraphicsConfiguration conf = device.getDefaultConfiguration();166Rectangle bounds = conf.getBounds();167168// put just below half screen169int x = bounds.x + bounds.width/2;170int y = bounds.y + bounds.height/2;171frame.setLocation(x, y);172173return bounds;174}175176private static void runActualTest(GraphicsDevice device,177CountDownLatch latch,178JFrame frame,179boolean [] result)180{181Rectangle screenBounds = setLocation(frame, device);182JMenu menu = frame.getJMenuBar().getMenu(0);183menu.doClick();184185Point location = menu.getLocationOnScreen();186JPopupMenu pm = menu.getPopupMenu();187Dimension pmSize = pm.getSize();188189int yOffset = UIManager.getInt("Menu.submenuPopupOffsetY");190int height = location.y + yOffset + pmSize.height + menu.getHeight();191int available = screenBounds.y + screenBounds.height - height;192if (available > 0) {193Point origin = pm.getLocationOnScreen();194if (origin.y < location.y) {195// growing upward, wrong!196result[0] = false;197} else {198// growing downward, ok!199result[0] = true;200}201} else {202// there is no space, growing upward would be ok, so we pass203result[0] = true;204}205}206}207208209