Java SwingUtilities.getLocationOnScreen()有问题;

Java SwingUtilities.getLocationOnScreen()有问题;,java,swing,actionlistener,Java,Swing,Actionlistener,我在JButton“support”上的ActionListener中有以下代码。cl.cross.text是GUI中的另一个JTextArea。问题在于针对点pt1给出的结果。框架为600x600,按钮位于中间按钮,而JTextArea位于中间右侧。打印命令的结果是: java.awt.Point[x=501,y=187]java.awt.Point[x=370,y=1062] 现在,第一个坐标是正确的(用MouseListener检查),但第二个坐标完全超出范围,它们甚至超出了我的帧(假设它

我在JButton“support”上的ActionListener中有以下代码。cl.cross.text是GUI中的另一个JTextArea。问题在于针对点pt1给出的结果。框架为600x600,按钮位于中间按钮,而JTextArea位于中间右侧。打印命令的结果是: java.awt.Point[x=501,y=187]java.awt.Point[x=370,y=1062] 现在,第一个坐标是正确的(用MouseListener检查),但第二个坐标完全超出范围,它们甚至超出了我的帧(假设它是600,y=1062)。 任何建议如何得到正确的,因为我需要做一个机器人,按下是,这是我唯一的想法得到它的大小调整GUI

代码:


“pt”是屏幕坐标点。因此,您希望使用SwingUtilities.convertPointFromScreen(pt,frame)将其转换为帧的坐标。

我认为您获得不正确点坐标的原因是方法的使用不正确。
SwingUtilities.convertPointToScreen(点,组件)

别担心,我第一次使用这种方法时也犯了同样的错误。:)

从对该方法的描述中,我们可以看到它返回:“一个点实例,表示组件父级坐标空间中组件边界的左上角”

因此,作为组件参数,我们需要给出它的父对象,例如,
SwingUtilities.convertPointToScreen(point,component.getParent())

因此,对于您的情况,您应该:

Point pt=new Point(cl.across.text.getLocation());
SwingUtilities.convertPointToScreen(pt, cl.across.text.getParent());
Point pt1=new Point(support.getLocation());
SwingUtilities.convertPointToScreen(pt1, support.getParent());
System.out.println(pt+" "+pt1);
示例:在此示例中,您可以看到getLocationOnScreen()如何“足够好”让机器人完成其工作,并且它返回的结果与“正确”使用的
SwingUtilities.convertPointToScreen()方法返回的结果相同

要看到它工作,请启动示例并将手从鼠标上拿开,然后等待几秒钟

import java.awt.AWTException;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class RobotLocOnScreenTest{
    public static void main(String[] args){
        final JTextArea ta = new JTextArea(21, 12);
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run(){
                JFrame f = new JFrame();
                JPanel p = new JPanel();
                JTextField tf = new JTextField("asadasdasd", 15);
                p.add(tf);
                p.add(ta);
                p.add(new JTextField(11));
                f.setContentPane(p);
                f.setSize(800, 600);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setVisible(true);
                //request focus so the text field tf has it first
                tf.requestFocusInWindow();
            }
        });
        /* A hack to allow the GUI to build so we can see all robot's operations on the area 
        * and avoid the IllegalComponentStateException exception thrown by
        * Component.getLocationOnScreen() method when the component is not showing.
        */
        try{
            Thread.sleep(2000);
        }catch(InterruptedException ex) {
            Logger.getLogger(RobotLocOnScreenTest.class.getName()).log(Level.SEVERE, null, ex);
        }
        findAndOperateOnTextArea(ta);           
    }

    private static void findAndOperateOnTextArea(JTextArea ta){
        try{
            Robot robot = new Robot();
            Point taLOSP = ta.getLocationOnScreen();
            Point taLPBad = ta.getLocation();
            SwingUtilities.convertPointToScreen(taLPBad, ta);           
            Point taLPGood = ta.getLocation();
            SwingUtilities.convertPointToScreen(taLPGood, ta.getParent());
            System.out.println("ta.getLocationOnScreen()=" + taLOSP 
                    + "; taLPBad=" + taLPBad+"; taLPGood="+taLPGood);           
            robot.mouseMove(taLOSP.x, taLOSP.y);
            robot.delay(1111);
            robot.mousePress(InputEvent.BUTTON1_MASK);
            robot.mouseRelease(InputEvent.BUTTON1_MASK);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_0);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_1);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_2);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_3);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_4);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_5);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_6);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_7);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_8);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_9);
        }catch(AWTException ex){
            Logger.getLogger(RobotLocOnScreenTest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

发布演示问题的SSCCE()。你为什么需要一个机器人。每当你需要一个机器人来生成事件时,听起来都是一个糟糕的设计。正因为如此。我想使鼠标单击执行两次,因此我需要生成一个MouseEvent。但我确实需要屏幕坐标,因为Robot moveMouse()将屏幕坐标作为参数。您的描述要求的值介于0到600之间,即帧坐标中的值。是的,您可以使用convertPoint(To/From)屏幕的两种方法根据需要在屏幕和帧(或鼠标或其他组件)坐标之间进行转换。要从一个组件转换到另一个组件坐标,首先要将它转换到屏幕上,然后再转换到另一个组件。是的,这就回答并解决了它。我只是想说一句,在我从网上读到的API中,两种方法的描述都很糟糕,甚至没有包括左上角的内容。无论如何,非常感谢:)
import java.awt.AWTException;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class RobotLocOnScreenTest{
    public static void main(String[] args){
        final JTextArea ta = new JTextArea(21, 12);
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run(){
                JFrame f = new JFrame();
                JPanel p = new JPanel();
                JTextField tf = new JTextField("asadasdasd", 15);
                p.add(tf);
                p.add(ta);
                p.add(new JTextField(11));
                f.setContentPane(p);
                f.setSize(800, 600);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setVisible(true);
                //request focus so the text field tf has it first
                tf.requestFocusInWindow();
            }
        });
        /* A hack to allow the GUI to build so we can see all robot's operations on the area 
        * and avoid the IllegalComponentStateException exception thrown by
        * Component.getLocationOnScreen() method when the component is not showing.
        */
        try{
            Thread.sleep(2000);
        }catch(InterruptedException ex) {
            Logger.getLogger(RobotLocOnScreenTest.class.getName()).log(Level.SEVERE, null, ex);
        }
        findAndOperateOnTextArea(ta);           
    }

    private static void findAndOperateOnTextArea(JTextArea ta){
        try{
            Robot robot = new Robot();
            Point taLOSP = ta.getLocationOnScreen();
            Point taLPBad = ta.getLocation();
            SwingUtilities.convertPointToScreen(taLPBad, ta);           
            Point taLPGood = ta.getLocation();
            SwingUtilities.convertPointToScreen(taLPGood, ta.getParent());
            System.out.println("ta.getLocationOnScreen()=" + taLOSP 
                    + "; taLPBad=" + taLPBad+"; taLPGood="+taLPGood);           
            robot.mouseMove(taLOSP.x, taLOSP.y);
            robot.delay(1111);
            robot.mousePress(InputEvent.BUTTON1_MASK);
            robot.mouseRelease(InputEvent.BUTTON1_MASK);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_0);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_1);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_2);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_3);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_4);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_5);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_6);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_7);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_8);
            robot.delay(333);
            robot.keyPress(KeyEvent.VK_9);
        }catch(AWTException ex){
            Logger.getLogger(RobotLocOnScreenTest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}