#java #runtime #coordinates #jna #awtrobot
#java #среда выполнения #координаты #jna #awtrobot
Вопрос:
Есть ли способ для меня получить значения X и Y окна на Java? Я читал, что мне придется использовать среду выполнения, поскольку java не может напрямую связываться, однако я не очень уверен в том, как это сделать. Кто-нибудь может указать мне несколько ссылок / советов о том, как это получить?
Комментарии:
1. Расположение окна на экране? Какое окно? Текущая Java (Swing?) приложение (в каком случае getLocationOnScreen() будет работать) или окно другого несвязанного приложения? Если последнее, то я бы рассмотрел возможность использования JNA для решения этой проблемы.
2. Извините, что не конкретизирую… О любом другом несвязанном приложении.
Ответ №1:
Чтобы получить позиции x и y «любого другого несвязанного приложения», вам придется запросить ОС, а это означает, что, скорее всего, используется либо JNI, JNA, либо какая-либо другая утилита для создания сценариев, такая как AutoIt (если Windows). Я рекомендую либо JNA, либо скриптовую утилиту, поскольку обе они намного проще в использовании, чем JNI (по моему ограниченному опыту), но для их использования вам нужно загрузить некоторый код и интегрировать его с вашим Java-приложением.
РЕДАКТИРОВАТЬ 1 Я не эксперт по JNA, но я немного повозился с этим, и это то, что у меня есть, чтобы получить координаты окна для некоторого именованного окна:
import java.util.Arrays;
import com.sun.jna.*;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.win32.*;
public class GetWindowRect {
public interface User32 extends StdCallLibrary {
User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class,
W32APIOptions.DEFAULT_OPTIONS);
HWND FindWindow(String lpClassName, String lpWindowName);
int GetWindowRect(HWND handle, int[] rect);
}
public static int[] getRect(String windowName) throws WindowNotFoundException,
GetWindowRectException {
HWND hwnd = User32.INSTANCE.FindWindow(null, windowName);
if (hwnd == null) {
throw new WindowNotFoundException("", windowName);
}
int[] rect = {0, 0, 0, 0};
int result = User32.INSTANCE.GetWindowRect(hwnd, rect);
if (result == 0) {
throw new GetWindowRectException(windowName);
}
return rect;
}
@SuppressWarnings("serial")
public static class WindowNotFoundException extends Exception {
public WindowNotFoundException(String className, String windowName) {
super(String.format("Window null for className: %s; windowName: %s",
className, windowName));
}
}
@SuppressWarnings("serial")
public static class GetWindowRectException extends Exception {
public GetWindowRectException(String windowName) {
super("Window Rect not found for " windowName);
}
}
public static void main(String[] args) {
String windowName = "Document - WordPad";
int[] rect;
try {
rect = GetWindowRect.getRect(windowName);
System.out.printf("The corner locations for the window "%s" are %s",
windowName, Arrays.toString(rect));
} catch (GetWindowRect.WindowNotFoundException e) {
e.printStackTrace();
} catch (GetWindowRect.GetWindowRectException e) {
e.printStackTrace();
}
}
}
Конечно, чтобы это сработало, библиотеки JNA должны быть загружены и размещены в пути к классам Java или в пути сборки вашей IDE.
Комментарии:
1. как насчет Ubuntu или любого другого рабочего стола Linux?
2. User32 уже является частью библиотеки jna-platform (по крайней мере, в версии 5.3.1)
Ответ №2:
Это легко сделать с помощью конечного пользователя. Просто попросите их щелкнуть по точке на снимке экрана.
Например
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
/** Getting a point of interest on the screen.
Requires the MotivatedEndUser API - sold separately. */
class GetScreenPoint {
public static void main(String[] args) throws Exception {
Robot robot = new Robot();
final Dimension screenSize = Toolkit.getDefaultToolkit().
getScreenSize();
final BufferedImage screen = robot.createScreenCapture(
new Rectangle(screenSize));
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JLabel screenLabel = new JLabel(new ImageIcon(screen));
JScrollPane screenScroll = new JScrollPane(screenLabel);
screenScroll.setPreferredSize(new Dimension(
(int)(screenSize.getWidth()/2),
(int)(screenSize.getHeight()/2)));
final Point pointOfInterest = new Point();
JPanel panel = new JPanel(new BorderLayout());
panel.add(screenScroll, BorderLayout.CENTER);
final JLabel pointLabel = new JLabel(
"Click on any point in the screen shot!");
panel.add(pointLabel, BorderLayout.SOUTH);
screenLabel.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
pointOfInterest.setLocation(me.getPoint());
pointLabel.setText(
"Point: "
pointOfInterest.getX()
"x"
pointOfInterest.getY());
}
});
JOptionPane.showMessageDialog(null, panel);
System.out.println("Point of interest: " pointOfInterest);
}
});
}
}
Типичный вывод
Point of interest: java.awt.Point[x=342,y=43]
Press any key to continue . . .
Ответ №3:
Немного опоздал на вечеринку, но добавлю это, чтобы потенциально сэкономить другим немного времени. Если вы используете более свежую версию JNA, то WindowUtils.getAllWindows()
это значительно упростит выполнение.
Я использую самые последние стабильные версии на момент этого поста из следующих расположений maven:
Платформа JNA — net.java.dev.jna: jna-платформа: 5.2.0
Ядро JNA — net.java.dev.jna: jna: 5.2.0
Java 8 Lambda (Редактировать: rect является заполнителем и должен быть окончательным или эффективно окончательным для работы в lambda)
//Find IntelliJ IDEA Window
//import java.awt.Rectangle;
final Rectangle rect = new Rectangle(0, 0, 0, 0); //needs to be final or effectively final for lambda
WindowUtils.getAllWindows(true).forEach(desktopWindow -> {
if (desktopWindow.getTitle().contains("IDEA")) {
rect.setRect(desktopWindow.getLocAndSize());
}
});
Другая Java
//Find IntelliJ IDEA Window
Rectangle rect = null;
for (DesktopWindow desktopWindow : WindowUtils.getAllWindows(true)) {
if (desktopWindow.getTitle().contains("IDEA")) {
rect = desktopWindow.getLocAndSize();
}
}
Затем в JPanel вы можете нарисовать захваченное изображение по размеру (растянет изображение, если разные соотношения сторон).
//import java.awt.Robot;
g2d.drawImage(new Robot().createScreenCapture(rect), 0, 0, getWidth(), getHeight(), this);
Комментарии:
1. если я сделаю выше, я просто получу «Эта платформа пока не поддерживается», поскольку именно это делает код: github.com/java-native-access/jna/blob /…