簡體   English   中英

Java Swing:長事件期間重繪組件

[英]Java Swing: repaint component during long event

我正在使用Java Swing渲染應用程序的GUI。 我在JButton上設置了一個ActionListener來觸發一系列測試。 理想情況下,我想使用實時測試信息和結果更新狀態區域(當前為JTextArea )。 換句話說,程序會在運行和完成測試時逐行設置文本區域,例如:

Running Tests... 
    Test 1:  Check Something...
         Success
    Test 2:  Check Something else...
         Success
    ..    //More testing output

All tests have completed successfully.  Yay.

問題是當我的actionPerformed事件方法仍在運行時,我無法更新狀態文本。 當所有測試都快速完成時,這一切都很好。 但是,我的一些測試花費的時間是不確定的(請考慮“數據庫連接超時”)。 發生這種情況時,用戶將被狀態區域中已有的任何文本所困擾,並且我的應用程序將凍結,直到測試完成或失敗。

我每次嘗試更新狀態時都嘗試在JTextArea上調用repaint ,但似乎只是將其添加到事件隊列中(直到我的actionPerformed事件完成后才會被觸發... doh)。 我還嘗試調用revalidateupdateUI ,甚至嘗試在運行測試的ActionListener類上調用wait() ,但到目前為止沒有任何效果。 這是我當前代碼的結構:

..

JTextArea statusOutput_textArea;

..

public void actionPerformed(ActionEvent e) {
    setStatusText("Running Tests...");

    //Run Tests
    int currentTest = 1;

    //Check something
    appendStatusText("        Test " + currentTest++ + ":  Checking Something...");
    ..    //Check Something Here
    appendStatusText("            Success");

    //Check something else
    appendStatusText("        Test " + currentTest++ + ":  Checking Something else...");
    ..    //Check Something Else Here
    appendStatusText("            Success");

    //Other tests
    ..    //Run other tests here

    appendStatusText("\nAll tests have completed successfully.  Yay.");
}//End of actionPerformed method

public void setStatusText (String statusText) {
    statusOutput_textArea.setText(statusText);
    statusOutput_textArea.repaint();
}//End of setStatusText method

public void appendStatusText (String statusTextToAppend) {
    statusOutput_textArea.setText(statusOutput_textArea.getText() + "\n" + statusTextToAppend);
    statusOutput_textArea.repaint();
}//End of appendStatusText method 

任何幫助將非常感激 :)

UPDATE

對於那些對解決方案的總體結構感興趣的人,這里是:

public class RunTestsButtonActionListener implements ActionListener {
    JTextArea statusOutput_textArea;
    JButton testDatabaseSettings_JButton;

    public RunTestsButtonActionListener(JTextArea statusOutput_textArea){
        this.statusOutput_textArea = statusOutput_textArea;
    }

    public void actionPerformed(ActionEvent e) {
        testDatabaseSettings_JButton = (JButton) e.getSource();

        Thread tests = new Thread(){
            public void run() {
                //Disable button and add tooltip
                testDatabaseSettings_JButton.setEnabled(false);
                testDatabaseSettings_JButton.setToolTipText("Running Tests...");

                //Run Tests
                try {
                    statusOutput_textArea.setText("Running Tests...");
                    int currentTest = 1;

                    //Check something
                    statusOutput_textArea.append("\n        Test " + currentTest++ + ":  Checking Something...");
                    ..    //Check Something Here
                    statusOutput_textArea.append("\n            Success");

                    //Check something else
                    statusOutput_textArea.append("\n        Test " + currentTest++ + ":  Checking Something else...");
                    ..    //Check Something Else Here
                    statusOutput_textArea.append("\n            Success");

                    //Other tests
                    ..    //Run other tests here

                    statusOutput_textArea.append("\n\nAll tests have completed successfully.  Yay.");
                } finally {
                    //Enable button and remove tooltip
                    testDatabaseSettings_JButton.setEnabled(false);
                    testDatabaseSettings_JButton.setToolTipText("");
                }
            }
        };

        tests.start();
    }
}

您正在對“ Swing線程”進行檢查,最好在另一個線程中執行這些任務(如果發生/更改,通知GUI)。

在自己的線程中運行每個測試,以免彼此阻塞。 而且,JTextArea已經具有線程安全的append方法,無需使用setText來模擬append

問題是您不能在一個動作中長時間運行任務。 如您所知,這種情況不會更新。

您應該嘗試看看SwingWorker或其他一些后台線程。 您將在后台線程中運行測試,並且每次要更新UI時都將調用:

SwingUtils.invokeLater(new Runnable() {
     public void run() {
        appendStatusText(....);
    }
});

暫無
暫無

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

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