bug7123767.java revision 5349
5349N/A/*
5349N/A * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
5349N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5349N/A *
5349N/A * This code is free software; you can redistribute it and/or modify it
5349N/A * under the terms of the GNU General Public License version 2 only, as
5349N/A * published by the Free Software Foundation.
5349N/A *
5349N/A * This code is distributed in the hope that it will be useful, but WITHOUT
5349N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5349N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5349N/A * version 2 for more details (a copy is included in the LICENSE file that
5349N/A * accompanied this code).
5349N/A *
5349N/A * You should have received a copy of the GNU General Public License version
5349N/A * 2 along with this work; if not, write to the Free Software Foundation,
5349N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5349N/A *
5349N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
5349N/A * or visit www.oracle.com if you need additional information or have any
5349N/A * questions.
5349N/A */
5349N/A
5349N/A/* @test
5349N/A @bug 7123767
5349N/A @summary Wrong tooltip location in Multi-Monitor configurations
5349N/A @author Vladislav Karnaukhov
5349N/A @run main bug7123767
5349N/A*/
5349N/A
5349N/Aimport sun.awt.SunToolkit;
5349N/A
5349N/Aimport javax.swing.*;
5349N/Aimport javax.swing.plaf.metal.MetalLookAndFeel;
5349N/Aimport java.awt.*;
5349N/Aimport java.awt.event.MouseEvent;
5349N/Aimport java.lang.reflect.InvocationTargetException;
5349N/A
5349N/Apublic class bug7123767 extends JFrame {
5349N/A
5349N/A private static class TestFactory extends PopupFactory {
5349N/A
5349N/A private static TestFactory newFactory = new TestFactory();
5349N/A private static PopupFactory oldFactory;
5349N/A
5349N/A private TestFactory() {
5349N/A super();
5349N/A }
5349N/A
5349N/A public static void install() {
5349N/A if (oldFactory == null) {
5349N/A oldFactory = getSharedInstance();
5349N/A setSharedInstance(newFactory);
5349N/A }
5349N/A }
5349N/A
5349N/A public static void uninstall() {
5349N/A if (oldFactory != null) {
5349N/A setSharedInstance(oldFactory);
5349N/A }
5349N/A }
5349N/A
5349N/A // Actual test happens here
5349N/A public Popup getPopup(Component owner, Component contents, int x, int y) {
5349N/A GraphicsConfiguration mouseGC = testGC(MouseInfo.getPointerInfo().getLocation());
5349N/A if (mouseGC == null) {
5349N/A throw new RuntimeException("Can't find GraphicsConfiguration that mouse pointer belongs to");
5349N/A }
5349N/A
5349N/A GraphicsConfiguration tipGC = testGC(new Point(x, y));
5349N/A if (tipGC == null) {
5349N/A throw new RuntimeException("Can't find GraphicsConfiguration that tip belongs to");
5349N/A }
5349N/A
5349N/A if (!mouseGC.equals(tipGC)) {
5349N/A throw new RuntimeException("Mouse and tip GCs are not equal");
5349N/A }
5349N/A
5349N/A return super.getPopup(owner, contents, x, y);
5349N/A }
5349N/A
5349N/A private static GraphicsConfiguration testGC(Point pt) {
5349N/A GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
5349N/A GraphicsDevice[] devices = environment.getScreenDevices();
5349N/A for (GraphicsDevice device : devices) {
5349N/A GraphicsConfiguration[] configs = device.getConfigurations();
5349N/A for (GraphicsConfiguration config : configs) {
5349N/A Rectangle rect = config.getBounds();
5349N/A Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(config);
5349N/A adjustInsets(rect, insets);
5349N/A if (rect.contains(pt))
5349N/A return config;
5349N/A }
5349N/A }
5349N/A
5349N/A return null;
5349N/A }
5349N/A }
5349N/A
5349N/A private static final int MARGIN = 10;
5349N/A private static bug7123767 frame;
5349N/A private static Robot robot;
5349N/A
5349N/A public static void main(String[] args) throws Exception {
5349N/A UIManager.setLookAndFeel(new MetalLookAndFeel());
5349N/A setUp();
5349N/A testToolTip();
5349N/A TestFactory.uninstall();
5349N/A }
5349N/A
5349N/A // Creates a window that is stretched across all available monitors
5349N/A // and adds itself as ContainerListener to track tooltips drawing
5349N/A private bug7123767() {
5349N/A super();
5349N/A
5349N/A ToolTipManager.sharedInstance().setInitialDelay(0);
5349N/A setDefaultCloseOperation(DISPOSE_ON_CLOSE);
5349N/A TestFactory.install();
5349N/A
5349N/A JLabel label1 = new JLabel("no preferred location");
5349N/A label1.setToolTipText("tip");
5349N/A add(label1, BorderLayout.WEST);
5349N/A
5349N/A JLabel label2 = new JLabel("preferred location (20000, 20000)") {
5349N/A public Point getToolTipLocation(MouseEvent event) {
5349N/A return new Point(20000, 20000);
5349N/A }
5349N/A };
5349N/A
5349N/A label2.setToolTipText("tip");
5349N/A add(label2, BorderLayout.EAST);
5349N/A
5349N/A setUndecorated(true);
5349N/A pack();
5349N/A
5349N/A Rectangle rect = new Rectangle();
5349N/A GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
5349N/A GraphicsDevice[] devices = environment.getScreenDevices();
5349N/A for (GraphicsDevice device : devices) {
5349N/A GraphicsConfiguration[] configs = device.getConfigurations();
5349N/A for (GraphicsConfiguration config : configs) {
5349N/A Insets localInsets = Toolkit.getDefaultToolkit().getScreenInsets(config);
5349N/A Rectangle localRect = config.getBounds();
5349N/A adjustInsets(localRect, localInsets);
5349N/A rect.add(localRect);
5349N/A }
5349N/A }
5349N/A setBounds(rect);
5349N/A }
5349N/A
5349N/A private static void setUp() throws InterruptedException, InvocationTargetException {
5349N/A SwingUtilities.invokeAndWait(new Runnable() {
5349N/A @Override
5349N/A public void run() {
5349N/A frame = new bug7123767();
5349N/A frame.setVisible(true);
5349N/A }
5349N/A });
5349N/A }
5349N/A
5349N/A // Moves mouse pointer to the corners of every GraphicsConfiguration
5349N/A private static void testToolTip() throws AWTException {
5349N/A SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
5349N/A toolkit.realSync();
5349N/A
5349N/A GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
5349N/A GraphicsDevice[] devices = environment.getScreenDevices();
5349N/A for (GraphicsDevice device : devices) {
5349N/A GraphicsConfiguration[] configs = device.getConfigurations();
5349N/A for (GraphicsConfiguration config : configs) {
5349N/A Rectangle rect = config.getBounds();
5349N/A Insets insets = toolkit.getScreenInsets(config);
5349N/A adjustInsets(rect, insets);
5349N/A
5349N/A // Upper left
5349N/A glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
5349N/A rect.x + MARGIN, rect.y + MARGIN);
5349N/A toolkit.realSync();
5349N/A
5349N/A // Lower left
5349N/A glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
5349N/A rect.x + MARGIN, rect.y + rect.height - MARGIN);
5349N/A toolkit.realSync();
5349N/A
5349N/A // Upper right
5349N/A glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
5349N/A rect.x + rect.width - MARGIN, rect.y + MARGIN);
5349N/A toolkit.realSync();
5349N/A
5349N/A // Lower right
5349N/A glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
5349N/A rect.x + rect.width - MARGIN, rect.y + rect.height - MARGIN);
5349N/A toolkit.realSync();
5349N/A }
5349N/A }
5349N/A }
5349N/A
5349N/A private static void glide(int x0, int y0, int x1, int y1) throws AWTException {
5349N/A if (robot == null) {
5349N/A robot = new Robot();
5349N/A robot.setAutoDelay(20);
5349N/A }
5349N/A
5349N/A float dmax = (float) Math.max(Math.abs(x1 - x0), Math.abs(y1 - y0));
5349N/A float dx = (x1 - x0) / dmax;
5349N/A float dy = (y1 - y0) / dmax;
5349N/A
5349N/A robot.mouseMove(x0, y0);
5349N/A for (int i = 1; i <= dmax; i += 10) {
5349N/A robot.mouseMove((int) (x0 + dx * i), (int) (y0 + dy * i));
5349N/A }
5349N/A }
5349N/A
5349N/A private static void adjustInsets(Rectangle rect, final Insets insets) {
5349N/A rect.x += insets.left;
5349N/A rect.y += insets.top;
5349N/A rect.width -= (insets.left + insets.right);
5349N/A rect.height -= (insets.top + insets.bottom);
5349N/A }
5349N/A}