JDK-6446582 : Window.setLocationRelativeTo(Component) broken for non-xinerama multi-head sys
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_8
  • CPU: sparc
  • Submitted: 2006-07-06
  • Updated: 2011-05-18
  • Resolved: 2011-05-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b19Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_05-b05)
Java HotSpot(TM) Client VM (build 1.5.0_05-b05, mixed mode, sharing)
(others)

ADDITIONAL OS VERSION INFORMATION :
Solaris 8
Red Hat Linux Fedora Core 4
(at least)

EXTRA RELEVANT SYSTEM CONFIGURATION :
Non-xinerama X-windows configuration.

A DESCRIPTION OF THE PROBLEM :
calling the Window.setLocationRelativeTo(Component) method on a window located on a screen different from that of the supplied Component results in the window being placed on the screen it was originally created on (though at a seemingly correct relative location). If, for example, a JDialog is created using a null owner and is subsequently displayed, it will always appear on the same screen as its (invisible) owner frame. This prevents re-use of dialogues in multiple head systems as they may appear on the wrong screen.

So, either Window.setLocationRelativeTo(Component c) is broken, or the API docs need to state this limitation.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a JFrame on the non-default screen. Create an ownerless JDialog. Call the dialog's setLocationRelativeTo method, passing it the JFrame. Call the JDialog's setVisible(true) method.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
dialog appears centered on JFrame
ACTUAL -
dialog appears on default screen (not the screen JFrame is on)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class TestCase {
        public TestCase() {
                GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
                GraphicsDevice[] gs = ge.getScreenDevices();

                if (gs.length<2) {
                        System.out.println("Not multi-head environment, test not valid!");
                        System.exit(1);
                }

                final JDialog dialog=new JDialog();
                JButton button=new JButton("Close");
                button.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                                dialog.dispose();
                        }
                });
                dialog.getContentPane().add(button);
                dialog.pack();

                for (int i=0; i<gs.length; i++) {
                        JFrame frame=new JFrame("Frame "+i,gs[i].getDefaultConfiguration());
                        button=new JButton("Open Dialog");
                        button.addActionListener(new ButtonActionListener(frame,dialog));
                        frame.getContentPane().add(button);
                        frame.pack();
                        frame.show();
                }
        }
        private static class ButtonActionListener implements ActionListener {
                JFrame frame;
                JDialog dialog;
                public ButtonActionListener(JFrame frame,JDialog dialog) {
                        super();
                        this.frame=frame;
                        this.dialog=dialog;
                }
                public void actionPerformed(ActionEvent e) {
                        dialog.setLocationRelativeTo(frame);
                        dialog.show();
                }
        }
        public static void main(String args[]) {
                new TestCase();
        }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Do not re-use dialogs across different screens. Do not create ownerless dialogs.

Comments
EVALUATION This issue is addressed with the fix for 6232687.
23-07-2007

EVALUATION I don't think that the described behaviour of setLocationRelativeTo() is wrong. As there is no way to change component's (and dialog's too) graphics config, this method can't move the dialog to another screen. However, this fact should be reflected in the specification.
06-07-2006

EVALUATION should mention this issue in spec
06-07-2006