0

次のように初期化されたJava-GnomeGUIがあります。

public static void main(String[] args) {
    Gtk.init(args);
    new GTK();
    Gtk.main();
}

public GTK() {
    initUI(this);
    //Exit GUI cleanly if close pressed
    connect(this);
    showAll();
}

public void initUI(final GTK gtk) {
    //Add various panes, boxes, buttons etc...
    //All my UI updates made at runtime here work correctly

    start.connect(new Button.Clicked(){

    @Override
    public void onClicked(Button start){
    worker = new worker(fileList, gtk);
    Thread workerThread = new Thread(worker);
    workerThread.start();

    Glib.idleAdd(new Handler(){
    public boolean run(){

    progress = worker.getProgress();

    if(progress != 1){
        progressBar.setFraction(progress);
        return true;
    }
    else{
          progressBar.setFraction(progress);
          return false;
                }
             }
         });
            }
    });
}

progressBarが私のGUI(org.gnome.gtk.ProgressBar)のコンポーネントであるが、progressBarはすべての実行が終了するまで更新されない場合、それはキューの後ろに置かれ、対照的に最後に実行されるようです。私が望んでいたようにすぐに。

http://java-gnome.sourceforge.net/NEWS.html

http://java-gnome.sourceforge.net/doc/api/4.1/org/gnome/glib/Glib.html#idleAdd(org.gnome.glib.Handler)

編集。

私のワーカースレッドは、最初の2つのクラスにまたがっています。

public class auCDtect implements Runnable { 

private String processingLog;
private String output;
private String summary;
private Collection<String> fileList;
private double progress = 0.0;
private GTK gtk;

auCDtect(Collection<String> fileList, GTK gtk){this.fileList = fileList; this.gtk = gtk;}

public void run () {

    List<String> command = new ArrayList<String>();
    command.add("./auCDtect");
    command.add("-d");
    command.add("-m10");

    //Add each song passed to this class to the auCDtect command
    for(String file:fileList){

        command.add(file);
    }
    ProcessBuilder processBuilder = new ProcessBuilder(command);

        Process process = null;
        try {
            process = processBuilder.start();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //Set up error stream thread 
        StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(), "ERROR", this); 

        //Set up output stream thread
        StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream(), "OUTPUT", this); 

        // Start error and input stream threads
        new Thread(errorGobbler).start(); 
        new Thread(outputGobbler).start(); 
  }

public void update(double progress, String processingLog, String output, String summary){

    this.processingLog = processingLog;
    this.output = output;
    this.summary = summary;
    this.progress = progress/(fileList.size());
    gtk.setOutputUpdated(true);
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public double getProgress(){

    return progress;
}

public String getProcessingLog(){

    return processingLog;
}

public String getOutput(){

    return output;
}

public String getSummary(){

    return summary;
}

}

そして、1番目によって生成された2番目:

public class StreamGobbler implements Runnable { 

InputStream inputStream; 
String type;
private String processingLog = null;
private String output = null;
private String summary = null;
protected boolean finished = false;
private auCDtect auCDtect;
private int progress = 0;

StreamGobbler(InputStream inputStream, String type, auCDtect auCDtect){this.inputStream = inputStream; this.type = type; this.auCDtect = auCDtect;} 

public void run(){ 

    Scanner scanner = new Scanner(inputStream);

    while (((scanner.hasNextLine())&&(type == "OUTPUT"))){

        String line = scanner.nextLine();

        if(line.contains("Processing file:")){
            processingLog = line.substring(line.indexOf("P"), (line.indexOf("]")+1));
        }
        if(line.contains("This track looks like")){
            output = line.substring(line.indexOf("This track"), (line.indexOf("%")+1));
            progress = progress + 1;
        }
        if(line.contains("These")){
            summary = line.substring(line.indexOf("These tracks"));
        }

        if((type == "OUTPUT")&&(progress > 0)){

            auCDtect.update(progress, processingLog, output, summary);
            processingLog = null;
            output = null;
            summary = null;
        }
    }

}
}
4

1 に答える 1

1

これがJavaバージョンに当てはまるかどうかはわかりませんが、私はCバージョンに慣れていますが、とにかく...

メインスレッドを更新しようとするのはワーカースレッドではなく、その逆です。clickedシグナルを処理するコールバックから、を呼び出しidleAdd、ワーカースレッドを作成して実行する必要があります。ワーカースレッドでは、メインスレッドがアクセスできる変数と、進行状況の値を配置する場所を更新します。次に、メインループはアイドルハンドラーを時々実行し、その値を読み取ります。その後、プログレスバーが更新されますが、重要なのは、この呼び出しがメインスレッドから実行されることです。

ほとんどのツールキットのように、GTKはスレッドセーフではありません(Javaバージョンはスレッドセーフに近いかもしれませんが、100%確信はありません。また、GTKで行われたその後の変更により、将来これが壊れる可能性があるため、依存しません。それ)。したがって、ワーカースレッドがユーザーインターフェイスコンポーネントを混乱させないようにする必要があります。

これを一粒の塩で考えてみてください。私はjava-gnomeではなくCのGTKを少し知っているので、完全に間違っている可能性があります。これはidleAddとにかくドキュメントで確認されているようです。

于 2013-01-22T12:42:14.460 に答える