Java 除非使用System.out.println(),否则程序不会执行
我的程序应该检查屏幕上的某个图像,如果它找到了,应该移动鼠标。问题是,除非我记录消息,否则它永远不会工作。我不知道为什么 如果我加入System.out.println(“废话”);在主类中的每个while循环中,它都起作用。但如果我不包括他们,那就不包括了。有人能解释一下吗。。。?我不明白为什么会这样。当我使用调试器时也会发生这种情况。它在调试时工作,但在运行时不工作 它工作时的示例:Java 除非使用System.out.println(),否则程序不会执行,java,awtrobot,system.out,Java,Awtrobot,System.out,我的程序应该检查屏幕上的某个图像,如果它找到了,应该移动鼠标。问题是,除非我记录消息,否则它永远不会工作。我不知道为什么 如果我加入System.out.println(“废话”);在主类中的每个while循环中,它都起作用。但如果我不包括他们,那就不包括了。有人能解释一下吗。。。?我不明白为什么会这样。当我使用调试器时也会发生这种情况。它在调试时工作,但在运行时不工作 它工作时的示例: public class Main { public static void main(Strin
public class Main {
public static void main(String[] args) {
GUI gui = new GUI();
GameHandler gameHandler = new GameHandler();
while (!gui.shouldStop()) {
while (gui.isRunning()) {
gameHandler.run();
}
}
}
}
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class GUI extends JFrame implements KeyListener, WindowListener {
private JLabel label;
private boolean run = false;
private boolean stop = false;
public GUI() {
label = new JLabel("Not running.");
JPanel panel = new JPanel();
panel.setSize(300, 200);
panel.add(label);
setSize(300, 200);
add(panel);
addKeyListener(this);
addWindowListener(this);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
}
public boolean isRunning() {
return run;
}
public boolean shouldStop() {
return stop;
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
String text = label.getText().equalsIgnoreCase("Not running.") ? "Running!" : "Not running.";
label.setText(text);
run = !run;
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
stop = true;
}
@Override
public void windowClosed(WindowEvent e) {
stop = true;
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
}
import java.awt.*;
public class GameHandler {
private Elektra elektra;
private Button popupExitButton;
public GameHandler() {
elektra = new Elektra();
popupExitButton = new Button(Button.EXIT_POPUP_IMAGE_PATH);
}
public void run() {
if (elektra.isAlive()) {
try {
new Robot().mouseMove(20, 90);
} catch (AWTException e) {
e.printStackTrace();
}
} else if (popupExitButton.isVisible()) {
try {
new Robot().mouseMove(90, 90);
} catch (AWTException e) {
e.printStackTrace();
}
}
}
}
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class Button {
BufferedImage image;
public Button(String fileName) {
try {
image = ImageIO.read(ClassLoader.getSystemResourceAsStream(fileName));
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean isVisible() {
try {
return new ImageSearcher(new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()))).containsSubImage(image);
} catch (AWTException e) {
e.printStackTrace();
}
return false;
}
public static final String EXIT_POPUP_IMAGE_PATH = "images/exitPopupButton.png";
}
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class Elektra {
String imagePath = "images/elektra.png";
BufferedImage image;
public Elektra() {
try {
image = ImageIO.read(ClassLoader.getSystemResourceAsStream(imagePath));
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean isAlive() {
try {
return new ImageSearcher(new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()))).containsSubImage(image);
} catch (AWTException e) {
e.printStackTrace();
}
return false;
}
}
我在互联网上找不到任何东西来支持这一点,但我认为你的打印语句会减慢程序的运行速度,足以让一切按正确的顺序运行。Swing请求从单个线程发出,因此事件很容易被绑定,正如Hover所说的,特别是当您有许多输入事件(如KeyEvents等)时。要解决这个问题,您可以尝试Thread.sleep,但最好重写程序,使其不使用while循环或不使用swing 这台MSCCE的性能是否比您预期的更好?(我必须承认,我并不完全清楚它应该做什么。它看起来像一个胶水盒一样有用。)
import java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
导入javax.imageio.imageio;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
班长{
公共静态void main(字符串[]args){
GameHandler GameHandler=新GameHandler();
GUI=新GUI(gameHandler);
gameHandler.run();
}
}
类GUI扩展JFrame实现KeyListener{
私人标签;
私有布尔运行=false;
私有布尔停止=false;
游戏者游戏者;
公共GUI(GameHandler GameHandler){
this.gameHandler=gameHandler;
标签=新的JLabel(“未运行”);
JPanel面板=新的JPanel();
面板设置尺寸(300200);
面板。添加(标签);
设置大小(300200);
添加(面板);
addKeyListener(此);
setDefaultCloseOperation(在关闭时处理);
可设置大小(假);
setLocationRelativeTo(空);
setVisible(真);
}
公共布尔值正在运行(){
回程;
}
公共布尔值shouldStop(){
返回站;
}
@凌驾
public void keyTyped(KeyEvent e){
}
@凌驾
按下公共无效键(按键事件e){
如果(例如getKeyCode()==KeyEvent.VK_ENTER){
String text=label.getText().equalsIgnoreCase(“未运行”)?“正在运行!”:“未运行”;
label.setText(文本);
跑=!跑;
如果(运行){
gameHandler.run();
}否则{
gameHandler.stop();
}
}
}
@凌驾
公共无效密钥已释放(密钥事件e){
}
}
类游戏处理程序{
私人Elektra Elektra;
私人按钮弹出退出按钮;
定时器;
公共游戏处理程序(){
elektra=新elektra();
popupExitButton=新建按钮(“按钮.退出\弹出\图像\路径”);
定时器=新定时器(400,侦听器);
}
公开募捐{
timer.start();
}
公共停车场(){
timer.stop();
}
ActionListener=新建ActionListener(){
已执行的公共无效行动(行动事件ae){
System.out.println(“elektra.isAlive():”+elektra.isAlive());
if(elektra.isAlive()){
试一试{
新机器人().鼠标移动(20,90);
}捕获(awtexe){
e、 printStackTrace();
}
}else if(popupExitButton.isVisible()){
试一试{
新机器人().鼠标移动(90,90);
}捕获(awtexe){
e、 printStackTrace();
}
}
}
};
}
类按钮{
缓冲图像;
公共按钮(字符串文件名){
试一试{
//image=ImageIO.read(ClassLoader.getsystemresourceastream(文件名));
image=new Robot().createScreenscapture(新矩形(0,0200200));
}捕获(例外e){
e、 printStackTrace();
}
}
公共布尔值可见(){
试一试{
返回新的ImageSearcher(新Robot().CreateScreateScreenCapture(新矩形)(Toolkit.getDefaultToolkit().getScreenSize())).ContainessubImage(图像);
}捕获(awtexe){
e、 printStackTrace();
}
返回false;
}
}
Elektra类{
缓冲图像;
公共电子{
试一试{
image=new Robot().createScreenscapture(新矩形(0,0200,50));
}捕获(例外e){
e、 printStackTrace();
}
}
公共生活{
试一试{
返回新的ImageSearcher(
新建Robot().createScreenCapture(
新矩形(Toolkit.getDefaultToolkit().getScreenSize()))
.containsSubImage(图像);
}捕获(awtexe){
e、 printStackTrace();
}
返回false;
}
}
类图像搜索器{
缓冲图像主图像;
公共图像搜索器(BuffereImage图像){
mainImage=图像;
}
公共布尔值containsSubImage(BuffereImage子映像){
int mainWidth=mainImage.getWidth();
int mainHeight=mainImage.getHeight();
int width=subImage.getWidth();
int height=subImage.getHeight();
对于(int-xOffset=0;xOffsetpublic class Main {
public static void main(String[] args) {
GUI gui = new GUI();
GameHandler gameHandler = new GameHandler();
while (!gui.shouldStop()) {
System.out.println("..");
while (gui.isRunning()) {
System.out.println("..");
gameHandler.run();
}
}
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
class Main {
public static void main(String[] args) {
GameHandler gameHandler = new GameHandler();
GUI gui = new GUI(gameHandler);
gameHandler.run();
}
}
class GUI extends JFrame implements KeyListener {
private JLabel label;
private boolean run = false;
private boolean stop = false;
GameHandler gameHandler;
public GUI(GameHandler gameHandler) {
this.gameHandler = gameHandler;
label = new JLabel("Not running.");
JPanel panel = new JPanel();
panel.setSize(300, 200);
panel.add(label);
setSize(300, 200);
add(panel);
addKeyListener(this);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
}
public boolean isRunning() {
return run;
}
public boolean shouldStop() {
return stop;
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
String text = label.getText().equalsIgnoreCase("Not running.") ? "Running!" : "Not running.";
label.setText(text);
run = !run;
if (run) {
gameHandler.run();
} else {
gameHandler.stop();
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
}
class GameHandler {
private Elektra elektra;
private Button popupExitButton;
Timer timer;
public GameHandler() {
elektra = new Elektra();
popupExitButton = new Button("Button.EXIT_POPUP_IMAGE_PATH");
timer = new Timer(400, listener);
}
public void run() {
timer.start();
}
public void stop() {
timer.stop();
}
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
System.out.println("elektra.isAlive(): " + elektra.isAlive());
if (elektra.isAlive()) {
try {
new Robot().mouseMove(20, 90);
} catch (AWTException e) {
e.printStackTrace();
}
} else if (popupExitButton.isVisible()) {
try {
new Robot().mouseMove(90, 90);
} catch (AWTException e) {
e.printStackTrace();
}
}
}
};
}
class Button {
BufferedImage image;
public Button(String fileName) {
try {
//image = ImageIO.read(ClassLoader.getSystemResourceAsStream(fileName));
image = new Robot().createScreenCapture(new Rectangle(0,0,200,200));
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean isVisible() {
try {
return new ImageSearcher(new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()))).containsSubImage(image);
} catch (AWTException e) {
e.printStackTrace();
}
return false;
}
}
class Elektra {
BufferedImage image;
public Elektra() {
try {
image = new Robot().createScreenCapture(new Rectangle(0,0,200,50));
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean isAlive() {
try {
return new ImageSearcher(
new Robot().createScreenCapture(
new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())))
.containsSubImage(image);
} catch (AWTException e) {
e.printStackTrace();
}
return false;
}
}
class ImageSearcher {
BufferedImage mainImage;
public ImageSearcher(BufferedImage image) {
mainImage = image;
}
public boolean containsSubImage(BufferedImage subImage) {
int mainWidth = mainImage.getWidth();
int mainHeight = mainImage.getHeight();
int width = subImage.getWidth();
int height = subImage.getHeight();
for (int xOffset = 0; xOffset < mainWidth && xOffset + width < mainWidth; xOffset++) {
for (int yOffset = 0; yOffset < mainHeight && yOffset + height < mainHeight; yOffset++) {
if (picturesEquivalent(subImage, xOffset, yOffset)) {
return true;
}
}
}
return false;
}
private boolean picturesEquivalent(BufferedImage subImage, int xOffset, int yOffset) {
int mainWidth = mainImage.getWidth();
int mainHeight = mainImage.getHeight();
int width = subImage.getWidth();
int height = subImage.getHeight();
for (int x = 0; x < width && xOffset + x < mainWidth; x++) {
for (int y = 0; y < height && yOffset + y < mainHeight; y++) {
int mainRGB = mainImage.getRGB(xOffset + x, yOffset + y);
int subRGB = subImage.getRGB(x, y);
if (mainRGB != subRGB) {
return false;
}
}
}
return true;
}
}