簡體   English   中英

使用線程更新jlabel的內容

[英]use thread to updata content of jlabel

我想在單擊一個按鈕時使用線程來更改 JLabel 的內容。 此按鈕將處理一個花費大量時間的文檔。 但是當我點擊按鈕時,處理文檔后會顯示JLabel的內容。 我希望它可以立即顯示。

這是代碼

public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        String command = e.getActionCommand();
        // Load button
        if (command.equals("Load")) {
            // set load to true
            load = true;
            // get text area name
            name = nameField.getText();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    loadState.setText("Loading document "+name+" . Please wait!");
                }           
            }).start();
            // load daffodils
            if (name.toLowerCase().equals("daffodils.txt")) {
                try {
                    loadText(tpPoem);
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
}

任何人都可以告訴我為什么這個線程不起作用。

Swing 大多是單線程的,從多個線程調用方法可能會出現問題。 您應該在稱為事件調度線程 (EDT) 的特殊線程上修改您的標簽。

ActionListener.actionPerformed在這個線程上運行,而不是

new Thread(new Runnable() {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        loadState.setText("Loading document "+name+" . Please wait!");
    }           
}).start();

你可以寫:

loadState.setText("Loading document "+name+" . Please wait!");

您的加載似乎也在 EDT 上運行:

if (name.toLowerCase().equals("daffodils.txt")) {
    try {
        loadText(tpPoem);
    } catch (IOException e1) {
        e1.printStackTrace();
    }
}

如果您在該方法中使用后台線程,則可以,否則請查看SwingWorker 那是為了在后台線程中執行冗長的任務。 如果使用長時間運行的任務阻塞 EDT,則在任務完成之前不會更新標簽。

如果您想從后台線程更新 GUI, SwingWorker有相應的方法。 此外,您可能會發現這個問題很有趣: 何時何地調用 EventQueue.invokeLater() 方法

嘗試這個:

public interface IWorkerThreadCallback {

    void onSuccess(boolean result);

    void onError(@NonNull Throwable result);
}


public class WorkerThread implements Runnable {
    private IWorkerThreadCallback callback;

    public WorkerThread(@NonNull IWorkerThreadCallback callback){
        this.callback = callback;
    }

    @Override
    public void run() {
        try {

            // do long task on a background thread

            // return when task is success
            callback.onSuccess(true);
        }
        catch (Exception ex){
            // return when task is error
            callback.onError(ex.fillInStackTrace());
        }
    }
}

// 從主線程調用工作線程

 new Thread(new WorkerThread(new IWorkerThreadCallback() {
     @Override
     public void onSuccess(boolean result) {
         // success result
     }

     @Override
     public void onError(@NonNull Throwable result) {
         // error result
     }
 })).start();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM