Как получить х и у окна программы в Java? - PullRequest
6 голосов
/ 23 мая 2011

Есть ли способ для меня получить значения X и Y окна в Java? Я прочитал, что мне придется использовать время выполнения, так как Java не может связываться напрямую, однако я не очень уверен, как это сделать. Может кто-нибудь указать мне некоторые ссылки / советы о том, как получить это?

Ответы [ 3 ]

19 голосов
/ 23 мая 2011

Чтобы получить координаты 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.

7 голосов
/ 23 мая 2011

Это легко сделать с помощью конечного пользователя.Просто заставьте их щелкнуть точку на снимке экрана.

EG

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 . . .
0 голосов
/ 31 декабря 2018

Немного опоздал на вечеринку здесь, но добавлю это, чтобы потенциально сэкономить немного времени другим.Если вы используете более свежую версию JNA, то WindowUtils.getAllWindows() сделает это намного проще.

На данный момент я использую самые последние стабильные версии из следующих местоположений maven:

JNA Platform - net.java.dev.jna: jna-platform: 5.2.0

JNA Core - net.java.dev.jna: jna: 5.2.0

Java 8 Lambda (Правка: прямоугольник является заполнителем и должен быть окончательным или эффективнымокончательная работа в лямбдеразличные пропорции).

//import java.awt.Robot;
g2d.drawImage(new Robot().createScreenCapture(rect), 0, 0, getWidth(), getHeight(), this);
...