Java GUI停止工作,即使它';s在自己的线程和线程中。sleep()不是';我没打电话

Java GUI停止工作,即使它';s在自己的线程和线程中。sleep()不是';我没打电话,java,multithreading,swing,user-interface,thread-sleep,Java,Multithreading,Swing,User Interface,Thread Sleep,我有个问题。当我按下链接到另一个类使用的方法的JButton时,我的GUI停止工作 Thread.sleep(); 考虑到我有自己的GUI线程,我不知道为什么会发生这种情况。请看一下我的代码,告诉我为什么会这样 这是我的GUI类: package com.robot; import java.awt.AWTException; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import jav

我有个问题。当我按下链接到另一个类使用的方法的JButton时,我的GUI停止工作

Thread.sleep();
考虑到我有自己的GUI线程,我不知道为什么会发生这种情况。请看一下我的代码,告诉我为什么会这样

这是我的GUI类:

package com.robot;

import java.awt.AWTException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;

public class GUI extends JFrame implements Runnable {

//defines the panels
JPanel mainPanel;
JPanel labelPanel;
JPanel buttonPanel1;
JPanel buttonPanel2;
JPanel consolePanel;

//defines the label
JLabel title;

//defines the buttons
JButton runDemo;
JButton runLive;
JButton scan;
JButton findPatterns;
JButton cleanFolder;
JButton configureSettings;

//defines the console
JTextArea console;

//defines the line break
String newline = System.getProperty("line.separator");

//start of the constructor method for GUI
public GUI() {

}

public void run() {
    //makes the program unable to be resized
            this.setResizable(false);

            //allows the user to close the program with the x button
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            //sets the title of the program
            this.setTitle("ROBOT Alpha Alfred Version 3.0");

            //creates panels to hold the elements of the GUI
            mainPanel = new JPanel();
            labelPanel = new JPanel();
            buttonPanel1 = new JPanel();
            buttonPanel2 = new JPanel();
            consolePanel = new JPanel();

            //creates label
            title = new JLabel("Robotically Operated Binary Options Trader");

            //creates buttons
            runDemo = new JButton("Run Demo");
            runLive = new JButton("Run Live");
            scan = new JButton("Scan Market");
            findPatterns = new JButton("Find Patterns");
            cleanFolder = new JButton("Clean Up Folder");
            configureSettings = new JButton("Configure Settings");

            //defines button listener objects
            ButtonListener buttonListener = new ButtonListener();

            //adds buttons to button listeners
            runDemo.addActionListener(buttonListener);    
            runLive.addActionListener(buttonListener);
            scan.addActionListener(buttonListener);
            findPatterns.addActionListener(buttonListener);
            cleanFolder.addActionListener(buttonListener);
            configureSettings.addActionListener(buttonListener);

            //creates the console
            console = new JTextArea(6, 40);

            //sets the default text of the console
            console.setText("----------------------- ROBOT Console -----------------------" + newline);

            //makes the console unable to be edited
            console.setEditable(false);

            //sets the line wrapping of the console
            console.setLineWrap(true);
            console.setWrapStyleWord(true);

            //creates scroll bars
            JScrollPane scrollBar = new JScrollPane(console);
            scrollBar.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            scrollBar.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);

            //adds label to the label panel
            labelPanel.add(title);

            //adds buttons to the button panel
            buttonPanel1.add(runDemo);
            buttonPanel1.add(runLive);
            buttonPanel2.add(scan);
            buttonPanel2.add(findPatterns);
            buttonPanel2.add(cleanFolder);
            buttonPanel2.add(configureSettings);

            //adds the console to the console panel
            consolePanel.add(scrollBar);

            //adds panels to the main panel
            mainPanel.add(labelPanel);
            mainPanel.add(buttonPanel1);
            mainPanel.add(buttonPanel2);
            mainPanel.add(consolePanel);

            //adds the main panel to the frame
            this.add(mainPanel);

            //packs the GUI
            this.pack();

            //sizes the GUI
            this.setSize(600, 400);

            //centers the GUI
            this.setLocationRelativeTo(null);

            //sets the GUI to be visible
            this.setVisible(true);
}

public void add(String string) {
    console.append(string + newline);
}

//implement listeners
private class ButtonListener implements ActionListener {

    public void actionPerformed(ActionEvent e) {

        if(e.getSource() == runDemo) {



        } else if(e.getSource() == runLive) {



        } else if(e.getSource() == scan) {

            try {
                ScanMarket.scanMarket();
            } catch (IOException e1) {
                e1.printStackTrace();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            } catch (AWTException e1) {
                e1.printStackTrace();
            }

        } else if(e.getSource() == findPatterns) {

            try {
                FindPattern.findPattern("Images");
            } catch (AWTException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }

        } else if(e.getSource() == cleanFolder) {

            AddNeededFiles.addNeededFiles();

        } else if(e.getSource() == configureSettings) {



        }

    }

}

}
以下是调用GUI类的位置:

//main method start
public static void main(String[] args) throws InterruptedException, IOException, AWTException {

    //opens up the GUI
    (new Thread(new GUI())).start();

    //possible methods
    //ScanMarket.scanMarket(); //scans market for data
    //FindPattern("Images"); //finds pattern among images in image folder labeled Images

}//end of main method
下面是一个类的方法,它使用Thread.sleep()链接到该方法

package.com.robot;
导入java.awt.AWTException;
导入java.awt.Robot;
导入java.io.IOException;
公共级扫描市场扩展了主要{
//定义对象
rename文件rename文件=新的rename文件();
IsGraphFull IsGraphFull=新的IsGraphFull();
NumberOfImagesInFolder NumberOfImagesInFolder=新的NumberOfImagesInFolder();
TakePicColumn TakePicColumn=新的TakePicColumn();
HasGraphCrashed HasGraphCrashed=新的HasGraphCrashed();
RefreshPage RefreshPage=新建RefreshPage();
/*scanMarket基本上用于“扫描”市场,并记录捕获的图像
连续数小时保存所有列。此方法将按顺序保存图像,
具有碰撞保护功能,可连续运行数小时*/
public static void scanMarket()引发IOException、InterruptedException、AWTExException{
//告诉要扫描的图像数
float wantedImages=700;
//统计文件夹中的图像数
NumberOfImagesInFolder.NumberOfImagesInFolder(“图像”);
//创建分配给所有图像的编号
浮点名称计数器=NumberOfImagesInFolder.NumberOfImagesInFolder;
//保存列,直到我们有1000个不同列的图像

而(NumberOfImagesInFolder.NumberOfImagesInFolder您需要将操作从swing UI线程推送到另一个线程上


Swing有一个特殊的类来帮助实现这一点-任何Swing/GUI读/写操作都应该在事件分派线程上运行 确保GUI突变/读取在Swing线程上运行

要在后台运行的任何操作都应该在单独的线程上运行


您可能希望使用该类运行后台任务。(

当按下按钮时,将在事件调度线程(EDT)上调用actionPerformed方法,该线程负责处理事件和绘制GUI。因为您从actionPerformed()调用了执行Thread.sleep()的方法,您仍在EDT上,因此阻止EDT重新绘制GUI

您需要使用运行scanMarket()方法的单独线程。

问题:

  • 您正在Swing事件线程上调用
    ScanMarket.ScanMarket()
    ,这是一段非常长时间运行的代码,方法是不将其放在后台线程中
  • 当Swing GUI应该在Swing事件线程上排队时,您正在后台线程中调用它
  • 解决方案:

    • 使用SwingWorker创建后台线程,并使长期运行的代码在其
      doInBackground()
      方法中运行
    • 通过将Runnable传递给
      SwingUtilities.invokeLater(…)
      方法,确保在事件调度线程EDT上对Swing代码进行排队
    • 阅读本教程,了解Swing的线程模型和遇到的问题
    Thread.sleep()
    使当前线程睡眠。即执行该语句的线程。
    package com.robot;
    
    import java.awt.AWTException;
    import java.awt.Robot;
    import java.io.IOException;
    
    public class ScanMarket extends Main{
    
    //define objects
    RenameFile renameFile = new RenameFile();
    IsGraphFull isGraphFull = new IsGraphFull();
    NumberOfImagesInFolder numberOfImagesInFolder = new NumberOfImagesInFolder();
    TakePicColumn takePicColumn = new TakePicColumn();
    HasGraphCrashed hasGraphCrashed = new HasGraphCrashed();
    RefreshPage refreshPage = new RefreshPage();
    
    /*scanMarket is used to basically "scan" the market and will record captured images 
    of all of the columns for many hours. This method will save the images in order, 
    has crash protection and will run continuously for hours*/
    public static void scanMarket() throws IOException, InterruptedException, AWTException {
    
        //tells number of images to scan
        float wantedImages = 700;
    
        //counts the number of images in the folder
        NumberOfImagesInFolder.numberOfImagesInFolder("Images");
    
        //creates the Number that is assigned to all images
        float nameCounter = NumberOfImagesInFolder.numberOfImagesInFolder;
    
        //saves the columns until we have 1000 images of different columns
        while (NumberOfImagesInFolder.numberOfImagesInFolder <= wantedImages) {
    
            //first check if the graph has crashed
            HasGraphCrashed.hasGraphCrashed();
    
            //if the graph has crashed then refresh the page
            if(HasGraphCrashed.hasGraphCrashed == true){
    
                //refresh the page
                RefreshPage.refreshPage();
    
                //alert the system it updated the page and the page is no longer down
                HasGraphCrashed.hasGraphCrashed=false;
    
            }
    
            //update the amount of images in the folder again
            NumberOfImagesInFolder.numberOfImagesInFolder("Images");
    
            //check if the graph is full 
            IsGraphFull.isGraphFull();
    
            //if the graph is full
            if (match == true) {
    
                //takes a picture of every single column
                TakePicColumn.takePicColumn();
    
                //sets up the 2 image locations for the first column
    
                    //temporary first column image
                    String file1 = imageLocation + "1" + end;
    
                    //permanent first column image
                    String file2 = imageLocation + "real" + nameCounter + end;
    
                    //increases the value of the number assigned to each image so that the next image has a different value than the first image
                    nameCounter++;
    
                    //rename the temporary file to the permanent file name
                    RenameFile.renameFile(file1, file2);
    
                    //sets up the 2 image locations for the second column
    
                        //temporary second column image
                        file1 = imageLocation + "2" + end;
    
                        //permanent second column image
                        file2 = imageLocation + "real" + nameCounter + end;
    
                    //increases the value of the number assigned to each image so that the next image has a different value than the second image
                    nameCounter++;
    
                    //rename the temporary file to the permanent file name
                    RenameFile.renameFile(file1, file2);
    
                    //sets up the 2 image locations for the third column
    
                        //temporary third column image
                        file1 = imageLocation + "3" + end;
    
                        //permanent third column image
                        file2 = imageLocation + "real" + nameCounter + end;
    
                    //increases the value of the number assigned to each image so that the next image has a different value than the third image
                    nameCounter++;
    
                    //rename the temporary file to the permanent file name
                    RenameFile.renameFile(file1, file2);
    
                    //sets up the 2 image locations for the fourth column
    
                        //temporary fourth column image
                        file1 = imageLocation + "4" + end;
    
                        //permanent fourth column image
                        file2 = imageLocation + "real" + nameCounter + end;
    
                    //increases the value of the number assigned to each image so that the next image has a different value than the fourth image
                    nameCounter++;
    
                    //rename the temporary file to the permanent file name
                    RenameFile.renameFile(file1, file2);
    
                    //sets up the 2 image locations for the fifth column
    
                        //temporary fifth column image
                        file1 = imageLocation + "5" + end;
    
                        //permanent fifth column image
                        file2 = imageLocation + "real" + nameCounter + end;
    
                        //increases the value of the number assigned to each image so that the next image has a different value than the fifth image
                        nameCounter++;
    
                    //rename the temporary file to the permanent file name
                    RenameFile.renameFile(file1, file2);
    
                    //waits for graph to shift
                    Thread.sleep(90000);
    
                }
    
                //create a temporary robot
                Robot test = new Robot();
    
                //move the mouse to the top left side of the screen to alert the person 
                //you can move the mouse for 90 seconds
                test.mouseMove(0,0);
    
                //give some time to let the user check what they need to check
                Thread.sleep(90000);
    
            }//end of if the graph is full statement
    
        }//end of capturing images
    
    }