8213535: Windows HiDPI html lightweight tooltips are truncated
Reviewed-by: kizune
This commit is contained in:
parent
2c868d6101
commit
a1b5e01003
src/java.desktop/share/classes/javax/swing
test/jdk/javax/swing
GraphicsConfigNotifier
JPopupMenu/6800513
JToolTip/4846413
PopupFactory/6276087
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2020, 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,12 +25,18 @@
|
||||
|
||||
package javax.swing;
|
||||
|
||||
import sun.awt.EmbeddedFrame;
|
||||
import sun.awt.OSInfo;
|
||||
import sun.swing.SwingAccessor;
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.awt.*;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Panel;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.security.AccessController;
|
||||
@ -38,6 +44,11 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import sun.awt.EmbeddedFrame;
|
||||
import sun.awt.OSInfo;
|
||||
import sun.swing.SwingAccessor;
|
||||
|
||||
import static javax.swing.ClientPropertyKey.PopupFactory_FORCE_HEAVYWEIGHT_POPUP;
|
||||
|
||||
/**
|
||||
@ -826,13 +837,12 @@ public class PopupFactory {
|
||||
} else {
|
||||
parent.add(component);
|
||||
}
|
||||
pack();
|
||||
component.setVisible(true);
|
||||
}
|
||||
|
||||
Component createComponent(Component owner) {
|
||||
JComponent component = new JPanel(new BorderLayout(), true);
|
||||
|
||||
component.setOpaque(true);
|
||||
return component;
|
||||
return new JPanel(new BorderLayout(), true);
|
||||
}
|
||||
|
||||
//
|
||||
@ -847,11 +857,10 @@ public class PopupFactory {
|
||||
super.reset(owner, contents, ownerX, ownerY);
|
||||
|
||||
JComponent component = (JComponent)getComponent();
|
||||
|
||||
component.setOpaque(contents.isOpaque());
|
||||
component.setVisible(false);
|
||||
component.setLocation(ownerX, ownerY);
|
||||
component.setOpaque(contents.isOpaque());
|
||||
component.add(contents, BorderLayout.CENTER);
|
||||
contents.invalidate();
|
||||
pack();
|
||||
}
|
||||
}
|
||||
@ -960,27 +969,22 @@ public class PopupFactory {
|
||||
(parent!=null)) {
|
||||
parent = parent.getParent();
|
||||
}
|
||||
// Set the visibility to false before adding to workaround a
|
||||
// bug in Solaris in which the Popup gets added at the wrong
|
||||
// location, which will result in a mouseExit, which will then
|
||||
// result in the ToolTip being removed.
|
||||
if (parent instanceof RootPaneContainer) {
|
||||
parent = ((RootPaneContainer)parent).getLayeredPane();
|
||||
Point p = SwingUtilities.convertScreenLocationToParent(parent,
|
||||
x, y);
|
||||
component.setVisible(false);
|
||||
component.setLocation(p.x, p.y);
|
||||
parent.add(component, JLayeredPane.POPUP_LAYER,
|
||||
0);
|
||||
} else {
|
||||
Point p = SwingUtilities.convertScreenLocationToParent(parent,
|
||||
x, y);
|
||||
|
||||
component.setLocation(p.x, p.y);
|
||||
component.setVisible(false);
|
||||
if (parent instanceof RootPaneContainer) {
|
||||
parent = ((RootPaneContainer) parent).getLayeredPane();
|
||||
}
|
||||
|
||||
Point p = SwingUtilities.convertScreenLocationToParent(parent,
|
||||
x, y);
|
||||
component.setLocation(p.x, p.y);
|
||||
if (parent instanceof JLayeredPane) {
|
||||
parent.add(component, JLayeredPane.POPUP_LAYER, 0);
|
||||
} else {
|
||||
parent.add(component);
|
||||
}
|
||||
pack();
|
||||
component.setVisible(true);
|
||||
component.revalidate();
|
||||
}
|
||||
|
||||
Component createComponent(Component owner) {
|
||||
@ -1004,11 +1008,9 @@ public class PopupFactory {
|
||||
super.reset(owner, contents, ownerX, ownerY);
|
||||
|
||||
Component component = getComponent();
|
||||
|
||||
component.setVisible(false);
|
||||
component.setLocation(ownerX, ownerY);
|
||||
rootPane.getContentPane().add(contents, BorderLayout.CENTER);
|
||||
contents.invalidate();
|
||||
component.validate();
|
||||
pack();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2020, 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
|
||||
@ -21,7 +21,6 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.FlowLayout;
|
||||
@ -33,6 +32,7 @@ import java.util.concurrent.Callable;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JFormattedTextField;
|
||||
import javax.swing.JFrame;
|
||||
@ -48,25 +48,30 @@ import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JToolTip;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.Popup;
|
||||
import javax.swing.PopupFactory;
|
||||
import javax.swing.SpinnerListModel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
|
||||
import sun.swing.MenuItemLayoutHelper;
|
||||
|
||||
import static javax.swing.UIManager.getInstalledLookAndFeels;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @key headful
|
||||
* @bug 8201552 8213843
|
||||
* @bug 8201552 8213843 8213535
|
||||
* @summary Initial layout of the component should use correct graphics config.
|
||||
* It is checked by SwingUtilities.updateComponentTreeUI(), if layout
|
||||
* was correct the call to updateComponentTreeUI() will be no-op.
|
||||
* @modules java.desktop/sun.swing
|
||||
* @compile -encoding utf-8 StalePreferredSize.java
|
||||
* @run main/othervm/timeout=200 StalePreferredSize
|
||||
* @run main/othervm/timeout=200 -Dsun.java2d.uiScale=1 StalePreferredSize
|
||||
* @run main/othervm/timeout=200 -Dsun.java2d.uiScale=2.25 StalePreferredSize
|
||||
* @run main/othervm/timeout=400 StalePreferredSize
|
||||
* @run main/othervm/timeout=400 -Dsun.java2d.uiScale=1 StalePreferredSize
|
||||
* @run main/othervm/timeout=400 -Dsun.java2d.uiScale=2.25 StalePreferredSize
|
||||
*/
|
||||
public final class StalePreferredSize {
|
||||
|
||||
@ -82,20 +87,26 @@ public final class StalePreferredSize {
|
||||
"Съешь ещё этих мягких французских булок да выпей же чаю"};
|
||||
|
||||
static JFrame frame;
|
||||
static Component component;
|
||||
static Popup popup;
|
||||
static JComponent component;
|
||||
static int typeFont = 0; // 0 - default, 1 - bold, 2 - italic
|
||||
static boolean addViaPopup;
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
for (final UIManager.LookAndFeelInfo laf : getInstalledLookAndFeels()) {
|
||||
EventQueue.invokeAndWait(() -> setLookAndFeel(laf));
|
||||
for (typeFont = 0; typeFont < 3; typeFont++) {
|
||||
System.err.println("typeFont = " + typeFont);
|
||||
for (final boolean html : new boolean[]{true, false}) {
|
||||
for (String text : TEXT) {
|
||||
if (html) {
|
||||
text = "<html>" + text + "</html>";
|
||||
for (boolean usePopup : new boolean[]{true, false}) {
|
||||
addViaPopup = usePopup;
|
||||
System.err.println("Use popup: " + usePopup);
|
||||
for (final boolean html : new boolean[]{true, false}) {
|
||||
for (String text : TEXT) {
|
||||
if (html) {
|
||||
text = "<html>" + text + "</html>";
|
||||
}
|
||||
test(text);
|
||||
}
|
||||
test(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,7 +116,7 @@ public final class StalePreferredSize {
|
||||
private static void test(String text) throws Exception {
|
||||
System.err.println("text = " + text);
|
||||
// Each Callable create a component to be tested
|
||||
final List<Callable<Component>> comps = List.of(
|
||||
final List<Callable<JComponent>> comps = List.of(
|
||||
() -> new JLabel(text),
|
||||
() -> new JButton(text),
|
||||
() -> new JMenuItem(text),
|
||||
@ -136,12 +147,12 @@ public final class StalePreferredSize {
|
||||
}
|
||||
);
|
||||
|
||||
for (final Callable<Component> creator : comps) {
|
||||
for (final Callable<JComponent> creator : comps) {
|
||||
checkComponent(creator);
|
||||
}
|
||||
}
|
||||
|
||||
static void checkComponent(Callable<Component> creator) throws Exception {
|
||||
static void checkComponent(Callable<JComponent> creator) throws Exception {
|
||||
EventQueue.invokeAndWait(() -> {
|
||||
|
||||
try {
|
||||
@ -150,6 +161,7 @@ public final class StalePreferredSize {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
component.setEnabled(false); // minimize paint/focus events amount
|
||||
Font font = component.getFont();
|
||||
if (typeFont == 1) {
|
||||
component.setFont(new Font(font.deriveFont(Font.BOLD).getAttributes()));
|
||||
@ -159,14 +171,35 @@ public final class StalePreferredSize {
|
||||
}
|
||||
|
||||
frame = new JFrame();
|
||||
// incorrect initial insets may ruin our size calculation
|
||||
frame.setUndecorated(true); // TODO JDK-8244388
|
||||
frame.setLayout(new FlowLayout());
|
||||
frame.add(new JScrollPane(component));
|
||||
frame.setSize(300, 100);
|
||||
frame.setSize(700, 400);
|
||||
frame.setLocationRelativeTo(null);
|
||||
if (addViaPopup) {
|
||||
// doing our best to show lightweight or mediumweight popup
|
||||
int x = frame.getX() + 50;
|
||||
int y = frame.getY() + 200;
|
||||
PopupFactory factory = PopupFactory.getSharedInstance();
|
||||
popup = factory.getPopup(frame, component, x, y);
|
||||
if (component instanceof JMenuItem) {
|
||||
// TODO JDK-8244400
|
||||
MenuItemLayoutHelper.clearUsedParentClientProperties((JMenuItem)component);
|
||||
}
|
||||
} else {
|
||||
frame.add(new JScrollPane(component));
|
||||
}
|
||||
frame.setVisible(true);
|
||||
if (popup != null) {
|
||||
popup.show();
|
||||
}
|
||||
});
|
||||
|
||||
EventQueue.invokeAndWait(() -> {
|
||||
if (!component.isValid()) {
|
||||
dispose();
|
||||
throw new RuntimeException("Component must be valid");
|
||||
}
|
||||
|
||||
// After the frame was shown we change nothing, so current layout
|
||||
// should be optimal and updateComponentTreeUI() should be no-op
|
||||
@ -179,7 +212,7 @@ public final class StalePreferredSize {
|
||||
component.setFont(component.getFont().deriveFont(35f));
|
||||
Dimension last = component.getPreferredSize();
|
||||
|
||||
frame.dispose();
|
||||
dispose();
|
||||
|
||||
if (!Objects.equals(before, after)) {
|
||||
System.err.println("Component: " + component);
|
||||
@ -197,6 +230,14 @@ public final class StalePreferredSize {
|
||||
});
|
||||
}
|
||||
|
||||
private static void dispose() {
|
||||
if (popup != null) {
|
||||
popup.hide();
|
||||
popup = null;
|
||||
}
|
||||
frame.dispose();
|
||||
}
|
||||
|
||||
private static void setLookAndFeel(final UIManager.LookAndFeelInfo laf) {
|
||||
try {
|
||||
UIManager.setLookAndFeel(laf.getClassName());
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2012 Red Hat, Inc. All Rights Reserved.
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2020, 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
|
||||
@ -131,6 +131,7 @@ public class bug6800513 {
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.setJMenuBar(menuBar);
|
||||
frame.setSize(500, 500);
|
||||
frame.setLocationRelativeTo(null);
|
||||
|
||||
PopupListener listener = new PopupListener();
|
||||
menu.getPopupMenu().addPropertyChangeListener(listener);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2020, 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
|
||||
@ -114,6 +114,7 @@ public class bug4846413 {
|
||||
JFrame frame = new JFrame("Test");
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.setSize(200, 200);
|
||||
frame.setLocationRelativeTo(null);
|
||||
|
||||
button = new JButton("Press me");
|
||||
button.setToolTipText("test");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2020, 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
|
||||
@ -53,6 +53,7 @@ public class NonOpaquePopupMenuTest extends JFrame {
|
||||
fileMenu.getPopupMenu().setOpaque(false);
|
||||
|
||||
setSize(new Dimension(640, 480));
|
||||
setLocationRelativeTo(null);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user