2013-02-02 45 views
0

我有2個班的.java怎麼看2可運行之間的交流與發展

主要:

public class Controller extends javax.swing.JFrame 
{ 
    public static void updateProgressBar(int i) { 
     jProgressBar1.setValue(i); 
     jProgressBar1.repaint(); 
    } 

    public static void main(String args[]) { 

     /* Create and display the form */ 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       Controller app = new Controller(); 
       app.setVisible(true); 
       app.setResizable(false); 
      } 
     }); 
    } 

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) { 
     ChildModel model = new ChildModel(); 
     Thread t1 = new Thread(model); 
     t1.start(); 
    } 

    private javax.swing.JProgressBar jProgressBar1; //Initialized with Netbeans builder 
} 

我ChildModel(ChildModel.java)計算某些代碼(即大約需要10-20秒),我想在父類(Controller.java)上顯示進度。

這裏是我的ChildModel:

public class ChildModel implements Runnable 
{ 
    public ChildModel(){ /* Something */ } 

    public void complexMath() 
    { 
     //Lots of logic here 
     Controller.updateProgression(purcent); 
    } 

    @Override 
    public void run() { 
     complexMath(); 
    } 
} 

的問題顯然是我的靜態無效updateProgressBar無法修改非靜態變量。我怎樣才能做到這一點?

+0

我想你是指變量「purcent」。爲什麼不把它變成靜態的呢? –

+0

Purcent工作正常。問題來自Controller類> updateProgress函數。該函數是靜態的,禁止引用非靜態變量jProgressBar1。我不想將jProgressBar1設置爲靜態。 – Kalzem

回答

2

jProgressBar1變量是一個實例變量,因此您無法從靜態方法訪問它。該方法不應該是靜態的:你想更新控制器中的進度,而不是所有的控制器實例。

將對控制器的引用傳遞給ChildModel,並使用ChildModel中的此引用來更新進度欄。另外請記住,所有Swing交互必須在EDT中完成,而不是在後臺線程中完成。所以代碼應該看起來像這樣:

public class Controller extends javax.swing.JFrame 
{ 
    public void updateProgressBar(int i) { 
     jProgressBar1.setValue(i); 
     // no need for repaint. The progress bar knows it must be repainted 
     // when its value changes 
    } 

    public static void main(String args[]) { 

     /* Create and display the form */ 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       Controller app = new Controller(); 
       app.setVisible(true); 
       app.setResizable(false); 
      } 
     }); 
    } 

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) { 
     ChildModel model = new ChildModel(this); 
     Thread t1 = new Thread(model); 
     t1.start(); 
    } 

    private javax.swing.JProgressBar jProgressBar1; //Initialized with Netbeans builder 
} 

public class ChildModel implements Runnable 
{ 

    private Controller controller; 

    public ChildModel(Controller controller){ 
     this.controller = controller; 
    } 

    public void complexMath() 
    { 
     //Lots of logic here 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       controller.updateProgression(percent); 
      } 
     }); 
    } 

    @Override 
    public void run() { 
     complexMath(); 
    } 
} 
+0

如果complexMath()中的部件「SwingUtilities.invokeLater ...」在for(100 000個循環)中,它是否正確工作?或者它會遭受速度/內存問題? (我想它會創建100 000個新的Runnable) – Kalzem

+0

是的。只有在新百分比值與前一個百分比值不同的情況下才會調用該值,並將其降至100以下。或者使用SwingWorker,它將爲您批量更新。 –

+0

謝謝!奇蹟般有效 ! – Kalzem

2

Swing有自己的concurrency mechanisms來處理更新組件。在這裏,您可以使用 a Swing Timer並更新JProgressBarChildModel不是ChildModel實現Runnable,您可以使用Timer作爲類成員變量並傳入您的實例jProgressBar1,使您能夠在需要時調用setValue

+0

感謝您讓我發現定時器! (但是我會堅持使用Nizet的方法) – Kalzem