删除打印语句会影响功能...正在发生损坏?

问题描述 投票:0回答:1

我编写了一个java程序,当移动到屏幕的下部时,它将最小化窗口。它通过使用

Robot
将鼠标移动到最小化按钮并使用
mousePress
mouseRelease
按下来执行任务。我确信有一种更理想的方法来编写这个程序,但我并不是在寻找那种方法。

我在测试时发现了一些奇怪的事情。删除打印语句时,程序未按预期工作,并且未最小化窗口。打印语句应该对程序的功能没有影响,所以我认为可能存在某种损坏。由于某种原因,如果没有 print 语句,

Point
变量是否无法实现?

我想知道是什么导致了此失败,并寻求解释此问题的幕后情况。

这是代码:

import java.awt.AWTException;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.InputEvent;

import javax.swing.JFrame;

public class AutoMinimize {

    public static void main(String[] args) {
        JFrame frame = new JFrame("My mini frame");
        frame.setSize(200,200);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        
        frame.setVisible(true);
        
        outerloop:
        while(true) {
            Point location = frame.getLocation();
            System.out.println(location); //Comment out this print statement and it doesnt work??
            if (location.getY()>700) {
                try {
                    Thread.sleep(1000);
                    location = frame.getLocation();
                    Robot r = new Robot();
                    r.mouseMove(((int) location.getX()+34), ((int) location.getY()+14));
                    r.mousePress(InputEvent.BUTTON1_MASK);
                    r.mouseRelease(InputEvent.BUTTON1_MASK);
                    break outerloop;
                } catch (AWTException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}

注意:鼠标移动适用于 MacOS 系统,但您可能需要针对不同操作系统调整坐标。

java mousemove corruption robot memory-corruption
1个回答
0
投票

至于你的问题的实际原因 - 我不能(准确地)说,因为它导致了许多副作用和问题 - 以这种方式使用

Robot
并不奇怪。

但是,我会:

  • 先释放鼠标按钮,因为窗口可能被拖动
  • 利用
    Robot#delay
    在事件之间注入一个小的延迟,以便系统有时间处理它们(否则它可能会选择忽略一些事件,因为它们很快就会到来)

但是,我能够使用

ComponentListener
来复制该功能...

import java.awt.EventQueue;
import java.awt.GraphicsConfiguration;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowStateListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                frame.addComponentListener(new ComponentAdapter() {
                    @Override
                    public void componentMoved(ComponentEvent e) {
                        GraphicsConfiguration gc = e.getComponent().getGraphicsConfiguration();
                        Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
                        Rectangle bounds = gc.getBounds();
                        int height = bounds.height - (insets.top + insets.bottom);
                        int range = height - (e.getComponent().getHeight() * 2);

                        if (e.getComponent().getY() > range) {
                            frame.setExtendedState(JFrame.ICONIFIED);
                        }
                    }
                });

                frame.addWindowStateListener(new WindowStateListener() {
                    @Override
                    public void windowStateChanged(WindowEvent e) {
                        if (e.getNewState() == JFrame.ICONIFIED) {
                            frame.setLocationRelativeTo(null);
                        }
                    }

                });
            }
        });
    }

    public class TestPane extends JPanel {
        public TestPane() {
            setBorder(new EmptyBorder(32, 32, 32, 32));
            setLayout(new GridBagLayout());
            add(new JLabel("Nothing to see here"));
        }
    }
}

本质上,它的作用是,一步一步,它将计算当前屏幕的可视大小(考虑到菜单和任务栏),计算一个“点击区域”,即屏幕的高度减去窗口高度的两倍,当窗口经过此“命中区域”时,它将被最小化。

作为一项附加功能,当窗口最小化时,它的位置将被重置(到屏幕中心)

作为一个很好的副作用,现在可以跨平台了

© www.soinside.com 2019 - 2024. All rights reserved.