Problem with SwingUtilities.getLocationOnScreen();
I have the following code inside an ActionListener on the JButton "support". the cl.across.text is an other JTextArea inside my GUI. The problem is with the results given for point pt1. The Frame is 600x600, the button is at the middle buttom while the JTextArea is at the middle r开发者_如何转开发ight. The result of the print command is: java.awt.Point[x=501,y=187] java.awt.Point[x=370,y=1062] Now the first coordinates are correct(checked with MouseListener) but the second one are totally out of range, they are outside my Frame even(consider it 600 and y=1062). Any advise how to get the right ones, cause I need to make a Robot which presses is, and that is my only idea to get it with resizing GUI.
Code:
Point pt=new Point(cl.across.text.getLocation());
SwingUtilities.convertPointToScreen(pt, cl.across.text);
Point pt1=new Point(support.getLocation());
SwingUtilities.convertPointToScreen(pt1, support);
System.out.println(pt+" "+pt1);
I think the reason why you are getting incorrect point coordinates is the incorrect use of the method SwingUtilities.convertPointToScreen(point, component);
.
Do not worry I made the same mistake when I used this method for the first time. :)
From the description of the method Component.getLocation() we get that it returns: "an instance of Point representing the top-left corner of the component's bounds in the coordinate space of the component's parent"
Therefore, as the component argument we need to give its parent object, e.g. SwingUtilities.convertPointToScreen(point, component.getParent());
Thus for your case you would have:
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);
Example: In this example you can see how getLocationOnScreen() is 'good enough' to get a robot to do its job, and it returns the same result as that returned by 'correctly' used SwingUtilities.convertPointToScreen()
method.
To see it working start the example and take your hands off the mouse and wait for few seconds.
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);
}
}
}
The 'pt' is a screen coordinates point. So you want to use SwingUtilities.convertPointFromScreen(pt, frame) to convert it to the coordinates of your Frame.
精彩评论