2013-06-11 50 views
1

我已經把打開文本文件,並允許用戶編輯他們的應用程序後設置一個標誌(如:文本編輯器)的SwingWorker完成其工作

一些文本文件,可以任意大,所以它會採取一些有時間打開它們。我已經添加了一個進度條來通知用戶實際上正在發生的事情,並且正在使用一個swing工作人員來執行實際的文件加載,併爲其提供對文本區域的引用以轉儲所有文本。

我在主應用程序中也有一個標誌,名爲isFileLoaded,如果有文件打開,則爲true,否則爲false。理想情況下,擺動工作人員應在完成文件加載並進行所需的任何處理後設置該值。

我已經把swing worker寫成了一個單獨的類,所以它不是嵌套在我的主Frame類中,它包含了所有的GUI邏輯,主要是因爲我不喜歡純粹出於美學原因定義類內部的類。因此,我現在將整個幀的引用傳遞給擺動工作人員,並讓它設置標誌的值。

這是做事的好方法嗎?有更好的方法嗎?

回答

3

請考慮添加一個PropertyChangeListener,其中持有對您的Frame(一個匿名的內部類將適用於此事)的引用,並聽取"state"屬性。當SwingWorker完成時,事件的值將等於StateValue.DONE

這裏是一個完全工作的例子:

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.util.List; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JProgressBar; 
import javax.swing.SwingUtilities; 
import javax.swing.SwingWorker; 
import javax.swing.SwingWorker.StateValue; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TestSwingWorker { 

    private JProgressBar progressBar; 

    protected void initUI() { 
     final JFrame frame = new JFrame(); 
     frame.setTitle(TestSwingWorker.class.getSimpleName()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JButton button = new JButton("Clik me to start work"); 
     button.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       doWork(); 
      } 
     }); 
     progressBar = new JProgressBar(0, 100); 
     frame.add(progressBar, BorderLayout.NORTH); 
     frame.add(button, BorderLayout.SOUTH); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    private boolean someFlag; 

    protected void doWork() { 
     SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() { 
      @Override 
      protected Void doInBackground() throws Exception { 
       for (int i = 0; i < 100; i++) { 
        // Simulates work 
        Thread.sleep(10); 
        publish(i); 
       } 
       return null; 
      } 

      @Override 
      protected void process(List<Integer> chunks) { 
       progressBar.setValue(chunks.get(chunks.size() - 1)); 
      } 

      @Override 
      protected void done() { 
       progressBar.setValue(100); 
       progressBar.setStringPainted(true); 
       progressBar.setString("Done"); 
      } 
     }; 
     worker.getPropertyChangeSupport().addPropertyChangeListener("state", new PropertyChangeListener() { 

      @Override 
      public void propertyChange(PropertyChangeEvent evt) { 
       if (StateValue.DONE.equals(evt.getNewValue())) { 
        someFlag = true; 
       } 
      } 
     }); 
     worker.execute(); 
    } 

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, 
      UnsupportedLookAndFeelException { 
     UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new TestSwingWorker().initUI(); 
      } 
     }); 
    } 
} 
+0

我對聽衆不熟悉,雖然在閱讀了一些搖擺教程之後,它看起來像是如果我真的想獲得一些響應式應用程序,我需要開始與他們合作。你能否提供一些片段,說明我將在哪裏添加聽衆,以及揮杆工作人員將如何使用它? – MxyL

+0

@Keikoku看到我的更新後的一個完整的工作示例。 –

1

你應該調整你的代碼一點,以避免使用全幀這的確是不是真的乾淨(但如果它的工作原理誰在乎)。

如果你想更冷靜從設計的角度來看,你應該使用一個模型:

class FileModel 
{ 
    boolean isLoading; 
    // getter and setter that notifies 
} 

,只有這種模式傳遞給你的工人,而一旦完成設置標誌。

+0

讓多個組件共享一個對象聽起來像個好主意,因爲我可以統一地訪問來自各種對象的數據並提供額外的抽象層。 – MxyL

+0

這是MVC模式及其所有衍生產品的本質:單獨的擔憂:一方面觀點,另一方面是邏輯和數據。 :) – Pragmateek