我编写了一个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 系统,但您可能需要针对不同操作系统调整坐标。
至于你的问题的实际原因 - 我不能(准确地)说,因为它导致了许多副作用和问题 - 以这种方式使用
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"));
}
}
}
本质上,它的作用是,一步一步,它将计算当前屏幕的可视大小(考虑到菜单和任务栏),计算一个“点击区域”,即屏幕的高度减去窗口高度的两倍,当窗口经过此“命中区域”时,它将被最小化。
作为一项附加功能,当窗口最小化时,它的位置将被重置(到屏幕中心)
作为一个很好的副作用,现在可以跨平台了