我写了一个Java程序,它将最小化一个窗口时,移动到屏幕的较低部分.它通过将鼠标按下Robot键移动到最小化按钮并按下mousePressmouseRelease键来执行任务.我确信有一种更理想的方式来编写这个程序,但我并不是在寻找这种方式.

在测试时,我注意到了一些奇怪的事情.删除打印语句时,程序没有按预期工作,也没有最小化窗口.PRINT语句应该不会对程序的功能产生任何影响,所以我认为其中可能存在某种损坏.如果没有PRINT语句,Point变量会因为某种原因而不能实现吗?

I am wondering what is causing this failure and seeking an explanation as to what is going on behind the scenes with this issue.

以下是代码:

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系统,但您可能需要为不同的操作系统调整坐标.

推荐答案

至于你的问题的真正原因--我不能(准确地)说,因为它引起了许多副作用和问题--当以这种方式使用Robot时,并不奇怪.

然而,我会:

  • 当窗口可能被拖动时,请先松开鼠标按钮
  • 使用Robot#delay在事件之间注入一个小的延迟,以便系统有时间处理它们(否则它可能会 Select 忽略一些事件,因为它们很快就会发生).

然而,我能够使用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"));
        }
    }
}

本质上,它所做的是,在移动中,它将计算当前屏幕的可见大小(考虑到菜单和任务栏),计算出一个"命中区域",即屏幕高度减go 窗口高度的两倍,当窗口经过这个"命中区域"时,它将被最小化.

作为一个额外的功能,当窗口最小化,它的位置将被重置(到屏幕的中心)

作为一个很好的副作用,它现在支持跨平台

Java相关问答推荐

如何让TaskView总是添加特定的列来进行排序?

找到允许的最大底片

查找最大子数组的和

Spring Batch 5-不要让它在数据库中自动创建表

多个Java线程和TreeMap.put()的非预期行为

取消按钮,但没有任何操作方法引发和异常

Java 21虚拟线程执行器的性能比池化操作系统线程的执行器差?

使用REST客户端和对象映射器从字符串反序列化Json

为什么S的文档中说常量方法句柄不能在类的常量池中表示?

如何获取Instant#of EpochSecond(?)的最大值

尽管通过中断请求线程死亡,但线程仍将继续存在

使用多个RemoteDatabase对象的一个线程

在Java中将int[]矩阵添加到ArrayList中,但出现错误

在settings.gradle.kts和Build.gradle.kts中使用公共变量

一对多关系和ID生成

如何在盒子的顶部和底部创建两张不同图片(大小相同)的盒子?

S数学.exp的相同错误保证也适用于StrictMath.exp吗?

在应用程序运行时更改LookAndFeel

基于Java中mm/dd/yy格式的最近日期对数组列表进行排序

Xml Reader 将 BMP 外部的字符解析为代理项对,这会导致无效的 xml