我有问题。当我按下链接到使用其他类别的方法
的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;
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
}
我不知道我是否需要给该课程自己的线程,然后在我通过构造函数调用该方法或什么时在GUI类中调用该线程!请帮助我!
您需要将操作关闭到秋千UI线程的其他线程。
Swing有一个特殊的课程可以帮助您 - 摇摆人
按下按钮时,将在事件调度线程(EDT)上调用Action Perverfermed方法,该方法负责处理事件并绘制GUI。由于您调用从ActionPerformed()执行thread.sleep()的方法,因此您仍在EDT上,因此阻止EDT重新绘制GUI。
您需要使用一个单独的线程来运行ScanMarket()方法。
任何摇摆/GUI读/写操作都应在事件调度线程上运行。你应该使用swingutilities.invokelater()确保在秋千线上运行GUI突变/读取。
您要在后台运行的任何操作都应在单独的线程上运行。
您可能需要使用Swingworker类来运行背景任务。(http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html)
问题:
- 您正在通过不将其放入背景线程中来调用
ScanMarket.scanMarket()
,这是一个非常长的代码,在摇摆事件线程上。 - 当应该在秋千事件线程中排队时,您正在在背景线程中调用秋千GUI。
解决方案:
- 使用Swingworker创建您的背景线程,并以
doInBackground()
方法运行长期运行的代码。 - 通过将运行可运行的可运行到
SwingUtilities.invokeLater(...)
方法。 - 阅读Swing的线程模型以及您通过阅读Swing教程中的并发性而遇到的问题。