mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-20 11:50:25 +00:00
8176448: [macos] Popups in JCombobox and Choice have incorrect location in multiscreen systems
Reviewed-by: alexsch, azvegint
This commit is contained in:
parent
e2b50eff2b
commit
2c6eb1441f
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,18 +25,29 @@
|
||||
|
||||
package com.apple.laf;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.*;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.plaf.basic.BasicComboPopup;
|
||||
|
||||
import sun.lwawt.macosx.CPlatformWindow;
|
||||
|
||||
@SuppressWarnings("serial") // Superclass is not serializable across versions
|
||||
class AquaComboBoxPopup extends BasicComboPopup {
|
||||
final class AquaComboBoxPopup extends BasicComboPopup {
|
||||
static final int FOCUS_RING_PAD_LEFT = 6;
|
||||
static final int FOCUS_RING_PAD_RIGHT = 6;
|
||||
static final int FOCUS_RING_PAD_BOTTOM = 5;
|
||||
@ -201,9 +212,6 @@ class AquaComboBoxPopup extends BasicComboPopup {
|
||||
//System.err.println("GetBestScreenBounds p: "+ p.x + ", " + p.y);
|
||||
final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
final GraphicsDevice[] gs = ge.getScreenDevices();
|
||||
//System.err.println(" gs.length = " + gs.length);
|
||||
final Rectangle comboBoxBounds = comboBox.getBounds();
|
||||
|
||||
for (final GraphicsDevice gd : gs) {
|
||||
final GraphicsConfiguration[] gc = gd.getConfigurations();
|
||||
for (final GraphicsConfiguration element0 : gc) {
|
||||
@ -215,15 +223,14 @@ class AquaComboBoxPopup extends BasicComboPopup {
|
||||
}
|
||||
|
||||
// Hmm. Origin's off screen, but is any part on?
|
||||
final Rectangle comboBoxBounds = comboBox.getBounds();
|
||||
comboBoxBounds.setLocation(p);
|
||||
for (final GraphicsDevice gd : gs) {
|
||||
final GraphicsConfiguration[] gc = gd.getConfigurations();
|
||||
for (final GraphicsConfiguration element0 : gc) {
|
||||
final Rectangle gcBounds = element0.getBounds();
|
||||
if (gcBounds.intersects(comboBoxBounds)) {
|
||||
if (gcBounds.contains(p)) {
|
||||
return getAvailableScreenArea(gcBounds, element0);
|
||||
}
|
||||
return getAvailableScreenArea(gcBounds, element0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -234,8 +241,15 @@ class AquaComboBoxPopup extends BasicComboPopup {
|
||||
private Rectangle getAvailableScreenArea(Rectangle bounds,
|
||||
GraphicsConfiguration gc) {
|
||||
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
|
||||
return new Rectangle(0, insets.top, bounds.width,
|
||||
bounds.height - insets.top);
|
||||
return new Rectangle(bounds.x + insets.left, bounds.y + insets.top,
|
||||
bounds.width - insets.left - insets.right,
|
||||
bounds.height - insets.top - insets.bottom);
|
||||
}
|
||||
|
||||
private int getComboBoxEdge(int py, boolean bottom) {
|
||||
int offset = bottom ? 9 : -9;
|
||||
// if py is less than new y we have a clipped combo, so leave it alone.
|
||||
return Math.min((py / 2) + offset, py);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -246,7 +260,7 @@ class AquaComboBoxPopup extends BasicComboPopup {
|
||||
if (isPopdown && !isTableCellEditor) {
|
||||
// place the popup just below the button, which is
|
||||
// near the center of a large combo box
|
||||
py = Math.min((py / 2) + 9, py); // if py is less than new y we have a clipped combo, so leave it alone.
|
||||
py = getComboBoxEdge(py, true);
|
||||
}
|
||||
|
||||
// px & py are relative to the combo box
|
||||
@ -291,8 +305,12 @@ class AquaComboBoxPopup extends BasicComboPopup {
|
||||
// Make sure it's all on the screen - shift it by the amount it's off
|
||||
p.x += px;
|
||||
p.y += py; // Screen location of px & py
|
||||
if (p.x < scrBounds.x) px -= (p.x + scrBounds.x);
|
||||
if (p.y < scrBounds.y) py -= (p.y + scrBounds.y);
|
||||
if (p.x < scrBounds.x) {
|
||||
px = px + (scrBounds.x - p.x);
|
||||
}
|
||||
if (p.y < scrBounds.y) {
|
||||
py = py + (scrBounds.y - p.y);
|
||||
}
|
||||
|
||||
final Point top = new Point(0, 0);
|
||||
SwingUtilities.convertPointFromScreen(top, comboBox);
|
||||
@ -324,22 +342,27 @@ class AquaComboBoxPopup extends BasicComboPopup {
|
||||
}
|
||||
|
||||
final Rectangle r = new Rectangle(px, py, pw, ph);
|
||||
if (py + ph > scrBounds.y + scrBounds.height) {
|
||||
if (ph <= -scrBounds.y ) {
|
||||
// popup goes above
|
||||
r.y = -ph ;
|
||||
} else {
|
||||
// a full screen height popup
|
||||
r.y = scrBounds.y + Math.max(0, (scrBounds.height - ph) / 2 );
|
||||
r.height = Math.min(scrBounds.height, ph);
|
||||
}
|
||||
if (r.y + r.height < top.y + scrBounds.y + scrBounds.height) {
|
||||
return r;
|
||||
}
|
||||
// Check whether it goes below the bottom of the screen, if so flip it
|
||||
int newY = getComboBoxEdge(comboBoxBounds.height, false) - ph - comboBoxInsets.top;
|
||||
if (newY > top.y + scrBounds.y) {
|
||||
return new Rectangle(px, newY, r.width, r.height);
|
||||
} else {
|
||||
// There are no place at top, move popup to the center of the screen
|
||||
r.y = top.y + scrBounds.y + Math.max(0, (scrBounds.height - ph) / 2 );
|
||||
r.height = Math.min(scrBounds.height, ph);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// The one to use when itemCount <= maxRowCount. Size never adjusts for arrows
|
||||
// We want it positioned so the selected item is right above the combo box
|
||||
protected Rectangle computePopupBoundsForMenu(final int px, final int py, final int pw, final int ph, final int itemCount, final Rectangle scrBounds) {
|
||||
protected Rectangle computePopupBoundsForMenu(final int px, final int py,
|
||||
final int pw, final int ph,
|
||||
final int itemCount,
|
||||
final Rectangle scrBounds) {
|
||||
//System.err.println("computePopupBoundsForMenu: " + px + "," + py + " " + pw + "," + ph);
|
||||
//System.err.println("itemCount: " +itemCount +" src: "+ scrBounds);
|
||||
int elementSize = 0; //kDefaultItemSize;
|
||||
|
||||
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.Choice;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.InputEvent;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8176448
|
||||
* @run main/timeout=300 ChoicePopupLocation
|
||||
*/
|
||||
public final class ChoicePopupLocation {
|
||||
|
||||
private static final int SIZE = 350;
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
GraphicsDevice[] sds = ge.getScreenDevices();
|
||||
Point left = null;
|
||||
for (GraphicsDevice sd : sds) {
|
||||
GraphicsConfiguration gc = sd.getDefaultConfiguration();
|
||||
Rectangle bounds = gc.getBounds();
|
||||
if (left == null || left.x > bounds.x) {
|
||||
left = new Point(bounds.x, bounds.y + bounds.height / 2);
|
||||
}
|
||||
|
||||
Point point = new Point(bounds.x, bounds.y);
|
||||
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
|
||||
while (point.y < bounds.y + bounds.height - insets.bottom - SIZE ) {
|
||||
while (point.x < bounds.x + bounds.width - insets.right - SIZE) {
|
||||
test(point);
|
||||
point.translate(bounds.width / 5, 0);
|
||||
}
|
||||
point.setLocation(bounds.x, point.y + bounds.height / 5);
|
||||
}
|
||||
|
||||
}
|
||||
if (left != null) {
|
||||
left.translate(-50, 0);
|
||||
test(left);
|
||||
}
|
||||
}
|
||||
|
||||
private static void test(final Point tmp) throws Exception {
|
||||
Choice choice = new Choice();
|
||||
for (int i = 1; i < 7; i++) {
|
||||
choice.add("Long-long-long-long-long text in the item-" + i);
|
||||
}
|
||||
Frame frame = new Frame();
|
||||
try {
|
||||
frame.setAlwaysOnTop(true);
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(choice);
|
||||
frame.pack();
|
||||
frame.setSize(frame.getWidth(), SIZE);
|
||||
frame.setVisible(true);
|
||||
frame.setLocation(tmp.x, tmp.y);
|
||||
openPopup(choice);
|
||||
} finally {
|
||||
frame.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static void openPopup(final Choice choice) throws Exception {
|
||||
Robot robot = new Robot();
|
||||
robot.setAutoDelay(100);
|
||||
robot.setAutoWaitForIdle(true);
|
||||
robot.waitForIdle();
|
||||
Point pt = choice.getLocationOnScreen();
|
||||
robot.mouseMove(pt.x + choice.getWidth() / 2,
|
||||
pt.y + choice.getHeight() / 2);
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
int x = pt.x + choice.getWidth() / 2;
|
||||
int y = pt.y + choice.getHeight() / 2 + 70;
|
||||
robot.mouseMove(x, y);
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.waitForIdle();
|
||||
if (choice.getSelectedIndex() == 0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,77 +24,78 @@
|
||||
/*
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 7072653 8144161
|
||||
* @bug 7072653 8144161 8176448
|
||||
* @summary JComboBox popup mispositioned if its height exceeds the screen height
|
||||
* @run main bug7072653
|
||||
*/
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
import javax.swing.event.PopupMenuListener;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
import javax.swing.event.PopupMenuListener;
|
||||
|
||||
public class bug7072653 {
|
||||
|
||||
private static JComboBox combobox;
|
||||
private static JFrame frame;
|
||||
private static Robot robot;
|
||||
private static volatile String errorString = "";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
robot.delay(100);
|
||||
UIManager.LookAndFeelInfo[] lookAndFeelArray
|
||||
= UIManager.getInstalledLookAndFeels();
|
||||
for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) {
|
||||
executeCase(lookAndFeelItem.getClassName());
|
||||
robot.delay(1000);
|
||||
}
|
||||
if (!"".equals(errorString)) {
|
||||
|
||||
throw new RuntimeException("Error Log:\n" + errorString);
|
||||
GraphicsEnvironment ge =
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
UIManager.LookAndFeelInfo[] lookAndFeelArray =
|
||||
UIManager.getInstalledLookAndFeels();
|
||||
for (GraphicsDevice sd : ge.getScreenDevices()) {
|
||||
for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) {
|
||||
executeCase(lookAndFeelItem.getClassName(), sd);
|
||||
robot.waitForIdle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void executeCase(String lookAndFeelString) throws Exception {
|
||||
private static void executeCase(String lookAndFeelString, GraphicsDevice sd)
|
||||
throws Exception {
|
||||
if (tryLookAndFeel(lookAndFeelString)) {
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
setup(lookAndFeelString);
|
||||
test();
|
||||
} catch (Exception ex) {
|
||||
errorString += "\n";
|
||||
errorString += Arrays.toString(ex.getStackTrace());
|
||||
}
|
||||
finally {
|
||||
frame.dispose();
|
||||
}
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
try {
|
||||
setup(lookAndFeelString, sd);
|
||||
test();
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
} finally {
|
||||
frame.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void setup(String lookAndFeelString)
|
||||
private static void setup(String lookAndFeelString, GraphicsDevice sd)
|
||||
throws Exception {
|
||||
|
||||
frame = new JFrame("JComboBox Test " + lookAndFeelString);
|
||||
GraphicsConfiguration gc = sd.getDefaultConfiguration();
|
||||
Rectangle gcBounds = gc.getBounds();
|
||||
frame = new JFrame("JComboBox Test " + lookAndFeelString, gc);
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.setSize(320, 200);
|
||||
frame.setSize(400, 200);
|
||||
frame.getContentPane().setLayout(new FlowLayout());
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setLocation(
|
||||
gcBounds.x + gcBounds.width / 2 - frame.getWidth() / 2,
|
||||
gcBounds.y + gcBounds.height / 2 - frame.getHeight() / 2);
|
||||
|
||||
combobox = new JComboBox(new DefaultComboBoxModel() {
|
||||
@Override
|
||||
public Object getElementAt(int index) {
|
||||
@ -108,6 +109,7 @@ public class bug7072653 {
|
||||
});
|
||||
|
||||
combobox.setMaximumRowCount(100);
|
||||
combobox.putClientProperty("JComboBox.isPopDown", true);
|
||||
frame.getContentPane().add(combobox);
|
||||
frame.setVisible(true);
|
||||
combobox.addPopupMenuListener(new PopupMenuListener() {
|
||||
@ -120,30 +122,24 @@ public class bug7072653 {
|
||||
int height = 0;
|
||||
for (Window window : JFrame.getWindows()) {
|
||||
if (Window.Type.POPUP == window.getType()) {
|
||||
height = window.getSize().height;
|
||||
break;
|
||||
if (window.getOwner().isVisible()) {
|
||||
height = window.getSize().height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
GraphicsConfiguration gc
|
||||
= combobox.getGraphicsConfiguration();
|
||||
Insets screenInsets = Toolkit.getDefaultToolkit()
|
||||
.getScreenInsets(gc);
|
||||
GraphicsConfiguration gc = combobox.getGraphicsConfiguration();
|
||||
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
|
||||
int gcHeight = gc.getBounds().height;
|
||||
if (lookAndFeelString.contains("aqua")) {
|
||||
gcHeight = gcHeight - screenInsets.top;
|
||||
//For Aqua LAF
|
||||
} else {
|
||||
gcHeight = gcHeight - screenInsets.top
|
||||
- screenInsets.bottom;
|
||||
}
|
||||
gcHeight = gcHeight - insets.top - insets.bottom;
|
||||
if (height == gcHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
String exception = "Popup window height "
|
||||
+ "For LookAndFeel" + lookAndFeelString + " is wrong"
|
||||
+ "\nShould be " + height + "Actually " + gcHeight;
|
||||
errorString += exception;
|
||||
+ "\nShould be " + gcHeight + ", Actually " + height;
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.InputEvent;
|
||||
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8176448
|
||||
* @run main/timeout=600 JComboBoxPopupLocation
|
||||
*/
|
||||
public final class JComboBoxPopupLocation {
|
||||
|
||||
private static final int SIZE = 300;
|
||||
public static final String PROPERTY_NAME = "JComboBox.isPopDown";
|
||||
private static volatile Robot robot;
|
||||
private static volatile JComboBox<String> comboBox;
|
||||
private static volatile JFrame frame;
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
robot = new Robot();
|
||||
robot.setAutoDelay(100);
|
||||
robot.setAutoWaitForIdle(true);
|
||||
GraphicsEnvironment ge =
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
GraphicsDevice[] sds = ge.getScreenDevices();
|
||||
UIManager.LookAndFeelInfo[] lookAndFeelArray =
|
||||
UIManager.getInstalledLookAndFeels();
|
||||
for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) {
|
||||
System.setProperty(PROPERTY_NAME, "true");
|
||||
step(sds, lookAndFeelItem);
|
||||
if (lookAndFeelItem.getClassName().contains("Aqua")) {
|
||||
System.setProperty(PROPERTY_NAME, "false");
|
||||
step(sds, lookAndFeelItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void step(GraphicsDevice[] sds,
|
||||
UIManager.LookAndFeelInfo lookAndFeelItem)
|
||||
throws Exception {
|
||||
UIManager.setLookAndFeel(lookAndFeelItem.getClassName());
|
||||
Point left = null;
|
||||
for (final GraphicsDevice sd : sds) {
|
||||
GraphicsConfiguration gc = sd.getDefaultConfiguration();
|
||||
Rectangle bounds = gc.getBounds();
|
||||
if (left == null || left.x > bounds.x) {
|
||||
left = new Point(bounds.x, bounds.y + bounds.height / 2);
|
||||
}
|
||||
Point point = new Point(bounds.x, bounds.y);
|
||||
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
|
||||
while (point.y < bounds.y + bounds.height - insets.bottom - SIZE ) {
|
||||
while (point.x < bounds.x + bounds.width - insets.right - SIZE) {
|
||||
try {
|
||||
EventQueue.invokeAndWait(() -> {
|
||||
setup(point);
|
||||
});
|
||||
robot.waitForIdle();
|
||||
test(comboBox);
|
||||
robot.waitForIdle();
|
||||
validate(comboBox);
|
||||
robot.waitForIdle();
|
||||
point.translate(bounds.width / 5, 0);
|
||||
} finally {
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
point.setLocation(bounds.x, point.y + bounds.height / 5);
|
||||
}
|
||||
}
|
||||
if (left != null) {
|
||||
final Point finalLeft = left;
|
||||
finalLeft.translate(-50, 0);
|
||||
try {
|
||||
EventQueue.invokeAndWait(() -> {
|
||||
setup(finalLeft);
|
||||
});
|
||||
robot.waitForIdle();
|
||||
test(comboBox);
|
||||
robot.waitForIdle();
|
||||
validate(comboBox);
|
||||
} finally {
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void dispose() throws Exception {
|
||||
EventQueue.invokeAndWait(() -> {
|
||||
if (frame != null) {
|
||||
frame.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void setup(final Point tmp) {
|
||||
comboBox = new JComboBox<>();
|
||||
for (int i = 1; i < 7; i++) {
|
||||
comboBox.addItem("Long-long-long-long-long text in the item-" + i);
|
||||
}
|
||||
String property = System.getProperty(PROPERTY_NAME);
|
||||
comboBox.putClientProperty(PROPERTY_NAME, Boolean.valueOf(property));
|
||||
frame = new JFrame();
|
||||
frame.setAlwaysOnTop(true);
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(comboBox);
|
||||
frame.pack();
|
||||
frame.setSize(frame.getWidth(), SIZE);
|
||||
frame.setVisible(true);
|
||||
frame.setLocation(tmp.x, tmp.y);
|
||||
}
|
||||
|
||||
private static void test(final JComboBox comboBox) throws Exception {
|
||||
Point pt = comboBox.getLocationOnScreen();
|
||||
robot.mouseMove(pt.x + comboBox.getWidth() / 2,
|
||||
pt.y + comboBox.getHeight() / 2);
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
int x = pt.x + comboBox.getWidth() / 2;
|
||||
int y = pt.y + comboBox.getHeight() / 2 + 70;
|
||||
robot.mouseMove(x, y);
|
||||
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
||||
}
|
||||
|
||||
private static void validate(final JComboBox comboBox) throws Exception {
|
||||
EventQueue.invokeAndWait(() -> {
|
||||
if (comboBox.getSelectedIndex() == 0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user