![](/img/trans.png)
[英]Is it okay to use Thread.sleep as a timer in a console application?
[英]Is it okay to use thread.sleep() when coding a bot?
我正在嘗試編寫原始垃圾郵件發送者。 在編寫機器人代碼時可以使用 thread.sleep() 嗎?
我是一個新手程序員。 如果我的代碼中有任何地方可以修復它,如果您告訴我,我將不勝感激。 我可能不正確地使用了 JComponents。 如果它引起您的注意,您可以指定。 謝謝你。
注意:“看起來您的帖子主要是代碼;請添加更多詳細信息。” 我正在寫這篇筆記,因為我找不到更多要添加的細節。 對不起
public class Spammer extends JFrame implements Runnable{
private boolean running = false;
private JButton jButton1;
private JLabel jLabel1, jLabel2;
private JScrollPane jScrollPane1;
private JSpinner jSpinner1;
private JTextArea jTextArea1;
public Spammer() {
setLayout(null);
jLabel1 = new JLabel("Text: ");
jTextArea1 = new JTextArea(10,28);
jLabel2 = new JLabel("Interval: ");
jSpinner1 = new JSpinner();
jScrollPane1 = new JScrollPane();
jButton1 = new JButton("Spam");
jButton1.setSize(350, 60);
jButton1.setLocation(100, 220);
jLabel1.setSize(50, 150);
jLabel1.setLocation(15, 10);
jLabel1.setFont(new Font("Verdana" , Font.BOLD , 14));
jTextArea1.setSize(350, 150);
jTextArea1.setLocation(100, 10);
jLabel2.setSize(80, 25);
jLabel2.setLocation(15, 180);
jLabel2.setFont(new Font("Verdana" , Font.BOLD , 12));
jSpinner1.setSize(350, 25);
jSpinner1.setLocation(100, 180);
getContentPane().add(jLabel1);
getContentPane().add(jTextArea1);
getContentPane().add(jLabel2);
getContentPane().add(jSpinner1);
getContentPane().add(jScrollPane1);
getContentPane().add(jButton1);
setTitle("Spammer by Me");
setLocationRelativeTo(null);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(500, 340));
pack();
jButton1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
jButton1ActionPerformed();
}
} );
}
private void jButton1ActionPerformed() {
if(!running) {
jTextArea1.setEnabled(false);
jSpinner1.setEnabled(false);
jButton1.setText("Spamming in 3 seconds...");
jButton1.setEnabled(false);
running = true;
new Thread(this).start();
}else {
jTextArea1.setEnabled(true);
jSpinner1.setEnabled(true);
jButton1.setText("Spam");
running = false;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Spammer().setVisible(true);
}
});
}
public void run() {
Robot robot = null;
try {
robot = new Robot();
} catch (AWTException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
int[] keys = new int[jTextArea1.getText().length()];
if((int) jSpinner1.getValue() < 0) {
jSpinner1.setValue((int) 0);
}
int interval = (int) jSpinner1.getValue();
for(int i = 0 ; i < keys.length; i++) {
keys[i] = KeyEvent.getExtendedKeyCodeForChar(jTextArea1.getText().charAt(i));
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
jButton1.setEnabled(true);
jButton1.setText("Stop");
while(running) {
for(int i = 0 ; i < keys.length; i++) {
robot.keyPress(keys[i]);
robot.keyRelease(keys[i]);
}
try {
Thread.sleep(interval);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
這里工作的關鍵原則主要是“EDT”——事件調度線程。 這是一個執行 GUI 內容的線程 - 例如,如果您將一個完全不同的應用程序 window 的標題欄拖動到屏幕上,這會將應用程序的 window 移動到您的上方,那么 EDT 會努力重繪所有內容。 EDT 是看到您在按鈕上按下鼠標的線程,並將在“按下”視圖中呈現按鈕。
EDT 是您可以從中執行 GUI 內容的唯一線程,無論是檢索信息,例如getText()
,還是更改內容,例如更新 label 的文本等。
EDT 也是您在代碼運行時所在的線程,您注冊為事件處理程序,例如響應按鈕單擊或諸如此類的代碼。
因此,您不能在 EDT 上休眠(因為這樣您的應用程序看起來沒有響應;響應按鈕單擊或重繪需要重繪的線程未在主動運行),但您只能從 EDT 獲取 GUI 數據/設置 GUI 內容.
規則:
你的代碼壞了,不是因為你在睡覺(這很好——那個run()
方法不在 EDT 中),而是因為你從這個非 EDT 線程做 GUI 的東西。
你需要在這里做一個仔細的舞蹈:你想睡覺(在 EDT 上不允許),但與 GUI 元素交互,例如間隔框,以知道要睡多久,這只能在 EDT 上完成。
為此,您可以通過 SwingWorkers 或簡單地通過以下方式“發送”代碼以在 EDT 中運行:
SwingUtilities.invokeAndWait(() -> {
// code that will run in the EDT goes here
});
您不能在此代碼中設置任何變量,但您可以使用AtomicReference
和朋友創建可以更改的對象。 所以,而不是:
int[] keys = new int[jTextArea1.getText().length()];
if (jSpinner1.getValue() < 0) {
jSpinner1.setValue(0);
}
int interval = (int) jSpinner1.getValue();
這是做GUI的東西,做:
AtomicInteger interval = new AtomicInteger();
SwingUtilities.invokeAndWait(() -> {
int[] keys = new int[jTextArea1.getText().length()];
if (jSpinner1.getValue() < 0) {
jSpinner1.setValue(0);
}
interval.set((int) jSpinner1.getValue());
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.