AWT Bug in Component.getLocationOnScreen()

Ebenius

Top Contributor
Huhu liebes Forum,

kann mal bitte jemand der ein Windows oder einen Mäc zur Hand hat diesen Quelltext kompilieren und bei sich probieren?
Java:
/* (@)LocationOnScreenBugFun.java */

/* Copyright 2012 Sebastian Haufe

 * Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       [url]http://www.apache.org/licenses/LICENSE-2.0[/url]

 * Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License. */

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Window;
import java.awt.event.ActionEvent;

import javax.swing.*;

/**
 * Demonstrates how location and locationOnScreen work differently on my
 * Ubuntu 11.10 with Java 1.6.0_26-b03.
 * 
 * @version $Revision$ as of $Date$
 * @author Sebastian Haufe
 */
public class LocationOnScreenBugFun {

  /** Creates the GUI. Call on EDT, only! */
  static void createAndShowGui() {
    final JPanel contentPane = new JPanel(new BorderLayout(6, 6));
    contentPane.add(new JButton(new AbstractAction("Relocate") {

      private static final long serialVersionUID = 1L;

      public void actionPerformed(ActionEvent e) {
        final Component button = (Component) e.getSource();
        final Window w = SwingUtilities.getWindowAncestor(button);
        System.out.printf("Old location:   %s%n ... on screen: %s%n",
              w.getLocation(), w.getLocationOnScreen());
        final int screenWidth = w.getToolkit().getScreenSize().width;
        w.setLocation(screenWidth - w.getWidth(), 0);
        System.out.printf("New location:   %s%n ... on screen: %s%n",
              w.getLocation(), w.getLocationOnScreen());
      }
    }));

    final JFrame f = new JFrame("Test Frame: LocationOnScreenBugFun"); //$NON-NLS-1$
    f.setContentPane(contentPane);
    f.pack();
    f.setLocation(0, 0);
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.setVisible(true);
  }

  /** @param args ignored */
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

      public void run() {
        createAndShowGui();
      }
    });
  }
}

Bei mir gibt das Programm beim Druck auf den Knopf das aus:
Code:
Old location:   java.awt.Point[x=0,y=0]
 ... on screen: java.awt.Point[x=0,y=0]
New location:   java.awt.Point[x=3740,y=0]
 ... on screen: java.awt.Point[x=0,y=0]
Bei Euch auch?

Das Problem führt bei mir reproduzierbar dazu, dass [c]childDialog.setLocationRelativeTo(parentFrame)[/c] nicht richtig funktioniert, wenn das [c]parentFrame[/c] zuvor geändert wurde. Erst wenn die EventQueue zwischen der Änderung der Location des [c]parentFrame[/c]s und dem [c]childDialog.setLocationRelativeTo(parentFrame)[/c] Events abarbeiten konnte, funktioniert das. Mit anderen Worten, das funktioniert nicht richtig :noe::
Java:
SwingUtilities.invokeLater(new Runnable() {
  @Override
  public void run() {
    parentFrame.setLocation(newLocation)
    childDialog.setLocationRelativeTo(parentFrame);
  }
});
Aber das funktioniert :bahnhof::
Java:
SwingUtilities.invokeLater(new Runnable() {
  @Override
  public void run() {
    parentFrame.setLocation(newLocation)
  }
});
// The EventQueue now processes all pending events before setLocationRelativeTo() is called
SwingUtilities.invokeLater(new Runnable() {
  @Override
  public void run() {
    childDialog.setLocationRelativeTo(parentFrame);
  }
});

Ebenius
 
ne, bei mir spuckt er das erwartete Ergebnis aus: (win7)

Code:
Old location:   java.awt.Point[x=0,y=0]
 ... on screen: java.awt.Point[x=0,y=0]
New location:   java.awt.Point[x=1788,y=0]
 ... on screen: java.awt.Point[x=1788,y=0]

du hast auch 2 Monitore angeschlossen...oder?
 
Zuletzt bearbeitet:
ne, bei mir spuckt er das erwartete Ergebnis aus: (win7)
[…]
du hast auch 2 Monitore angeschlossen...oder?
Ich hatte es schon befürchtet. Ja, ich hab zwei Monitore. Aber auch mit nur einem:
Code:
Old location:   java.awt.Point[x=0,y=0]
 ... on screen: java.awt.Point[x=0,y=0]
New location:   java.awt.Point[x=1818,y=0]
 ... on screen: java.awt.Point[x=0,y=0]
Danke sehr.

Hat noch jemand nen Mac?

Ebenius
 
Win7, 2 Monitore

Code:
Old location:   java.awt.Point[x=0,y=0]
 ... on screen: java.awt.Point[x=0,y=0]
New location:   java.awt.Point[x=1796,y=0]
 ... on screen: java.awt.Point[x=1796,y=0]

Linux (Debian), Laptop ohne zusätzlicher Monitor:
Code:
Old location:   java.awt.Point[x=0,y=0]
 ... on screen: java.awt.Point[x=0,y=0]
New location:   java.awt.Point[x=1296,y=0]
 ... on screen: java.awt.Point[x=0,y=0]

hth
 
Code:
Old location:   java.awt.Point[x=0,y=0]
 ... on screen: java.awt.Point[x=0,y=0]
New location:   java.awt.Point[x=1797,y=0]
 ... on screen: java.awt.Point[x=1797,y=0]

Allerdings weit ausm Fenster raus ^^
 
Hi,
ich weiß nicht obs dir hilft, aber wenn ich den Code wie folgt abändere funktionierts bei mir wie erwartet:
Java:
        w.setLocation(screenWidth - w.getWidth(), 0);
        w.setVisible(false);
        w.setVisible(true);

Code:
Old location:   java.awt.Point[x=57,y=24]
 ... on screen: java.awt.Point[x=57,y=24]
New location:   java.awt.Point[x=3742,y=0]
 ... on screen: java.awt.Point[x=3742,y=24]

Ubuntu 11.10 mitm OpenJDK 6.

EDIT:
Nein, das war nicht ganz richtig. So funktionierts auch nur sehr selten, war grad wohl nur Zufall 😉
Aber so funktionierts zuverlässig:
Java:
w.setLocation(screenWidth - w.getWidth(), 0);
try { Thread.sleep(50); } catch (InterruptedException e1) { }
Aber ob das so soll?
 
Zuletzt bearbeitet von einem Moderator:

Neue Themen


Zurück
Oben