14

Robot は AWT ライブラリの一部ですが、他のほとんどのライブラリとはかなり異なっているようです。Swing と Java Native Access (JNA) および Robot を組み合わせて、Java が一部の MS Windows/Citrix 作業プログラムを駆動できるようにする Swing GUI を作成しています。私の直感では、Robot は「プラットフォームのネイティブ入力キュー」でイベントをキューに入れるので、私が最後にやりたいことは EDT で実行することですが、一方で、AWT および Swing ライブラリのほとんどのクラスは、Swing イベントスレッドで実行する必要があります。ですから、これを明確にするために、できるだけ具体的な質問をさせてください。

ロボットのメソッド (特に、キーの押下と解放、マウスの移動、マウスの押下と解放) は、Swing イベント ディスパッチ スレッド (EDT) で実行する必要がありますか?

4

3 に答える 3

10

あなたが言及したRobotメソッドは、EDT で実行しないでください。ソース コードを調べると、これらの「イベント」メソッドにはそれぞれ 1 つの共通点 (afterEvent呼び出し)があることがわかりました。

public synchronized void keyPress(int keycode) {
    checkKeycodeArgument(keycode);
    peer.keyPress(keycode);
    afterEvent();
}

public synchronized void mousePress(int buttons) {
    checkButtonsArgument(buttons);
    peer.mousePress(buttons);
    afterEvent();
}

// etc

private void afterEvent() {
    autoWaitForIdle();
    autoDelay();
}

private void autoWaitForIdle() {
    if (isAutoWaitForIdle) {
        waitForIdle();
    }
}

public synchronized void waitForIdle() {
    checkNotDispatchThread();
    /* snip */
}

private void checkNotDispatchThread() {
    if (EventQueue.isDispatchThread()) {
        throw new IllegalThreadStateException("Cannot call method from the event dispatcher thread");
    }
}

Robot.isAutoWaitForIdleisのときに EDT でこれらのメソッドのいずれかを呼び出すとtrue、例外がスローされます。これは、 であっても、これらのメソッドを EDT から呼び出すべきではないという理由にisAutoWaitForIdleなりfalseます。

于 2012-05-11T00:24:30.937 に答える
6
  • API は非常に正確に話します。ロボットが EDT から呼び出されたかどうかにかかわらず、ロボットを無視する必要があることを理解しています。

クラスを使用して入力イベントを生成することは、イベントがプラットフォームのネイティブ入力キューで生成されるという点で、AWT イベント キューまたは AWT コンポーネントにイベントを投稿することとは異なります。

  • 私は Java では比較的新しいです。私の最初のタッチは Java1.6.009 でした。その後、Java1.3 の AWT と (生まれたときの) Swing と Java1.4 の残りの変更を比較することはできません。

私の例

import javax.imageio.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;

public class CaptureScreen implements ActionListener {

    private JFrame f = new JFrame("Screen Capture");
    private JPanel pane = new JPanel();
    private JButton capture = new JButton("Capture");
    private JDialog d = new JDialog();
    private JScrollPane scrollPane = new JScrollPane();
    private JLabel l = new JLabel();
    private Point location;

    public CaptureScreen() {
        capture.setActionCommand("CaptureScreen");
        capture.setFocusPainted(false);
        capture.addActionListener(this);
        capture.setPreferredSize(new Dimension(300, 50));
        pane.add(capture);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(pane);
        f.setLocation(100, 100);
        f.pack();
        f.setVisible(true);
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                createPicContainer();
            }
        });
    }

    private void createPicContainer() {
        l.setPreferredSize(new Dimension(700, 500));
        scrollPane = new JScrollPane(l,
                ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setBackground(Color.white);
        scrollPane.getViewport().setBackground(Color.white);
        d.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
        d.add(scrollPane);
        d.pack();
        d.setVisible(false);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("CaptureScreen")) {
            Dimension d1 = Toolkit.getDefaultToolkit().getScreenSize(); // gets the screen size
            Robot r;
            BufferedImage bI;
            try {
                r = new Robot(); // creates robot not sure exactly how it works
                Thread.sleep(1000); // waits 1 second before capture
                bI = r.createScreenCapture(new Rectangle(d1)); // tells robot to capture the screen
                showPic(bI);
                saveImage(bI);
            } catch (AWTException e1) {
                e1.printStackTrace();
            } catch (InterruptedException e2) {
                e2.printStackTrace();
            }
        }
    }

    private void saveImage(BufferedImage bI) {
        try {
            ImageIO.write(bI, "JPG", new File("screenShot.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void showPic(BufferedImage bI) {
        ImageIcon pic = new ImageIcon(bI);
        l.setIcon(pic);
        l.revalidate();
        l.repaint();
        d.setVisible(false);
        location = f.getLocationOnScreen();
        int x = location.x;
        int y = location.y;
        d.setLocation(x, y + f.getHeight());
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                d.setVisible(true);
            }
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                CaptureScreen cs = new CaptureScreen();
            }
        });
    }
}
于 2012-05-06T06:52:18.993 に答える