Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8230461

Wrong position of JPopupMenu when multiple displays with different DPI are used

XMLWordPrintable

    • 9
    • x86_64
    • windows_10

      A DESCRIPTION OF THE PROBLEM :
      Using two displays with different scaling factors, one is scaled at 200% and the other at 100%.
      The primary diplay is the one with the scaling factor of 200%.
      The frame should not be maximixed at startup.
      When the frame is dragged to the second monitor and the button is pressed, the popup menu will not be shown near the button, but will be shown on the wrong display.
      The name of the action added in the popup has to be big enough to overflow JFrame's bounds.

      The problem seems to affect all the components that extend javax.swing.JWindow and their size is bigger than the size of the parent JFrame.

      In this case because of the length of the text, the JPopupMenu is an instance of javax.swing.Popup.HeavyWeightWindow



      REGRESSION : Last worked in version 8u221

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      The frame should not be maximixed at startup.
      Run the attached code and drag the frame from primary display (with scale factor of 200%) to secondary diplay (with scale factor of 100%).
      Press the _BUTTON_. The popup menu should be shown near the button, but is wrongly painted on the primary display.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The popup menu should be show near the button.
      ACTUAL -
      The popup menu is shown on the wrong display.

      ---------- BEGIN SOURCE ----------
      import java.awt.GridBagConstraints;
      import java.awt.GridBagLayout;
      import java.awt.event.ActionEvent;

      import javax.swing.AbstractAction;
      import javax.swing.JButton;
      import javax.swing.JFrame;
      import javax.swing.JPanel;
      import javax.swing.JPopupMenu;

      /**
       * Components that extend javax.swing.JWindow are not shown in correct location when
       * the system uses 2 displays with different scaling factors.
       *
       * First display (also set as primary) has a scaling factor of 200%
       * Second display has no scaling factor (uses the default value of 100%).
       *
       * How to reproduce:
       * The JFrame is shown on primary display.
       * Move the frame to the second monitor, without maximizing it.
       * Press the button.
       * The popup menu will be show on primary monitor.
       */
      public class JPopupDisplayedInWrongPosition extends JFrame {

        /**
         * Main class.
         * @param args
         * @throws Exception
         */
        public static void main(String[] args) throws Exception {

          final JFrame frame = new JFrame("Frame title");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          
          JPopupMenu popup = new JPopupMenu();
          popup.add(new AbstractAction("An action with name big enough to overflow JFrame's bounds") {
            @Override
            public void actionPerformed(ActionEvent e) {
            }
          });
          
          JButton jButton = new JButton("BUTON");
          jButton.addActionListener(e -> popup.show(jButton, 0, jButton.getHeight()));
          
          JPanel panel = new JPanel(new GridBagLayout());
          GridBagConstraints c = new GridBagConstraints();
          c.gridx = 0;
          c.gridy = 0;
          c.fill = GridBagConstraints.NONE;
          panel.add(jButton, c);
          frame.getContentPane().add(panel);
          
          frame.setSize(300, 300);
          frame.setVisible(true);
        }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      No workaround.

      FREQUENCY : always


            psadhukhan Prasanta Sadhukhan
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: