1

在下面的代码行中,当按下 Button1 时,Jframe 变得无响应,直到 encode() 方法的执行完成。但我需要更新 Jframe 中显示进度的进度条。

private void Button1ActionPerformed(java.awt.event.ActionEvent evt) {                                   
    try {
        if (flagState == 0) {
            WavFile.decode(readWavFile, msg.getText(), key.getText().hashCode());
        } else if (flagState == 1) {
            WavFile.encode(readWavFile, msg.getText(), key.getText().hashCode());            
        }
    } catch (WavFileException | IOException e) {
        notes.setText(e.getMessage());
    }
}         

我想过这样做

private void Button1ActionPerformed(java.awt.event.ActionEvent evt) {                                   
    try {
        if (flagState == 0) {
            Thread t = new Thread(new Runnable() {
                               public void run() {
                                  WavFile.decode(readWavFile, msg.getText(), key.getText().hashCode()); 
                               }
                            };)
            t.start();
        } else if (flagState == 1) {
            Thread t = new Thread(new Runnable() {
                               public void run() {
                                  WavFile.encode(readWavFile, msg.getText(), key.getText().hashCode()); 
                               }
                            };)
            t.start();
        }
    } catch (WavFileException | IOException e) {
        notes.setText(e.getMessage());
    }
} 

并从 encode() 方法更新进度条。

但我知道它会在模块之间产生强烈的耦合,我不希望这样。

我也不认为每次都调用一个新线程是一个好主意(想到 ExecutorService 但不知道如何使用它)。

我应该怎么做才能把它变成一个像样的代码?

4

3 回答 3

1

在以下代码行中,当按下 Button1 时,Jframe 变得无响应,直到 encode() 方法的执行完成。但我需要更新 Jframe 中显示进度的进度条。

在 Swing 中遇到 Concurency问题,阻止 EDT,导致 GUI 无响应,直到代码结束

于 2012-09-10T18:20:18.143 回答
1

线程绝对是你必须在这里介绍的东西。任何需要花费大量时间才能完成的事情都不应该在 awt 事件线程中运行。

每次单击按钮时产生一个新线程本质上不是问题。但是,您应该考虑,甚至在第一个完成之前,可能会产生许多执行相同操作的线程。如果需要,您可以使用 Executor,但可能没有必要。

至于跟踪进度,我会添加另一个线程,该线程会定期查询另一个线程并根据需要更新进度条。这是我将如何构建它:

private void Button1ActionPerformed(java.awt.event.ActionEvent evt) {
    disableButton1();
    final Thread t;
    if (flagState == 0) {
        t = new Thread(new Runnable() {
            public void run() {
                try {
                    WavFile.decode(readWavFile, msg.getText(), key.getText().hashCode());
                } catch (WavFileException | IOException e) {
                    notes.setText(e.getMessage());
                }
            }
        });
    } else if (flagState == 1) {
        t = new Thread(new Runnable() {
            public void run() {
                try {
                    WavFile.encode(readWavFile, msg.getText(), key.getText().hashCode()); 
                } catch (WavFileException | IOException e) {
                    notes.setText(e.getMessage());
                }
            }
        });
    }

    Thread monitor = new Thread(new Runnable() {
        public void run() {
            try {
                while (notComplete(t)) {
                    setProgressBar(getProgress(t));
                    Thread.sleep(SLEEP_TIME);
                }
                t.join();
            } finally {
                enableButton1();
            }
        }
    });

    t.start();
    monitor.start();
}
于 2012-09-10T18:25:09.110 回答
0

多线程是您所需要的,没有其他好的方法我能想到不要担心调用新线程,这就是它们的用途,jvm 有一个线程池可供使用,这种东西运行起来非常好线程,试试看!

创建一个扩展 Runnable 的类,实现 run 方法或使其调用您当前的方法,这应该足以做到这一点。

你也可以让它休眠一小会儿,并在每次休眠时间结束时检查状态,如果进程完成,你可以继续,如果没有,再睡一小会,这样你就不必问了很多遍。

我希望它有所帮助。

于 2012-09-10T18:16:47.707 回答