2017-06-29 63 views
0

我試圖實現JprogressBar來顯示數據插入進度。 基本上用戶選擇將數據源導入數據庫的數量。 使用這個參數的主程序啓動一個方法來列出這些參數,並用foreach循環調用插入線程和ProgressBar更新線程。jProgressBar數據庫數據插入線程

for (Maquina i : m.listar()) { 
    //Passing to Import Thread the object with the data and a Date parameter 
    ImportarDados imp = new ImportarDados(i, jDateInicial.getDate()); 

    //Calling progress bar update Thread with the progressbar itself and progress parameter 
    BarraDeProgresso bp = new BarraDeProgresso(progresso, progImportacao); 

    imp.run(); 
    bp.run(); 
} 

螺紋自己有點兒工作,但結果不是我想要的,會導致數據被導入後,進度被更新,但它是所有數據後,被更新至100%進口。只要導入線程完成每個(Maquina i)對象的導入,我就需要更新進度欄。

如果有必要,我可以提供線程代碼...但我不知道這個調用方法是否可以提供我想要的結果。在論壇上搜索我發現了關於EDT的一些東西,我認爲這是酒吧沒有更新的問題。你們能幫我解決這個問題嗎?

最小可驗證示例: 我的代碼很短。 netbeans生成的代碼非常龐大,爲此。

該代碼模擬我的問題。只有在for循環結束後纔會刷新窗口。但BarraDeProgresso線程運行在相同和SYSOUT一些信息...

import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JLabel; 
import javax.swing.JProgressBar; 



public class Minimo extends javax.swing.JFrame { 


    public Minimo() { 
     initComponents(); 
    } 

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {           
     int progImportacao[] = {0}; 

     progresso.setMaximum(15); 
     for (int i = 0; i <= 15; i++) { 
      ImportarDados imp = new ImportarDados(i,lblProgresso); 
      BarraDeProgresso bp = new BarraDeProgresso(progresso, progImportacao); 

      imp.run(); 
      bp.run(); 

      progImportacao[0] += 1; 
     } 
    } 

組件初始化(生成的Netbeans)

private void initComponents() { 

    progresso = new javax.swing.JProgressBar(); 
    lblProgresso = new javax.swing.JLabel(); 
    jButton1 = new javax.swing.JButton(); 

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

    lblProgresso.setText("..."); 

    jButton1.setText("IMPORT DATA"); 
    jButton1.addActionListener(new java.awt.event.ActionListener() { 
     public void actionPerformed(java.awt.event.ActionEvent evt) { 
      jButton1ActionPerformed(evt); 
     } 
    }); 

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
    getContentPane().setLayout(layout); 
    layout.setHorizontalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGroup(layout.createSequentialGroup() 
      .addGap(60, 60, 60) 
      .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addComponent(lblProgresso) 
       .addComponent(progresso, javax.swing.GroupLayout.PREFERRED_SIZE, 382, javax.swing.GroupLayout.PREFERRED_SIZE)) 
      .addContainerGap(47, Short.MAX_VALUE)) 
     .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 
      .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 
      .addComponent(jButton1) 
      .addGap(191, 191, 191)) 
    ); 
    layout.setVerticalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 
      .addGap(32, 32, 32) 
      .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE) 
      .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 29, Short.MAX_VALUE) 
      .addComponent(lblProgresso) 
      .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 
      .addComponent(progresso, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 
      .addGap(37, 37, 37)) 
    ); 

    pack(); 
}// </editor-fold> 

Runnable接口的類

class BarraDeProgresso implements Runnable { 

    public JProgressBar jProgressBar1; 
    public int progresso[]; 

    public BarraDeProgresso(JProgressBar barra, int progresso[]) { 
     this.jProgressBar1 = barra; 
     this.progresso = progresso; 
    } 

    @Override 
    public void run() { 
     try { 
      Thread.sleep(0); 
      System.out.println("TBARRA PROG " + progresso[0]); 
      jProgressBar1.setValue(progresso[0]); 
      jProgressBar1.repaint(); 
     } catch (InterruptedException e) { 
     } 

    } 
} 

class ImportarDados implements Runnable { 

    private int pi = 0; 
    JLabel x; 

    public ImportarDados(int i, JLabel tag) { 
     this.pi = i; 
     this.x = tag; 
    } 

    @Override 
    public void run() { 
     try { 
      Thread.sleep(500); 

      x.setText(Integer.toString(pi)+" /15"); 

     } catch (InterruptedException ex) { 
      Logger.getLogger(Minimo.class.getName()).log(Level.SEVERE, null, ex); 
     } 

    } 
} 

主要(Netbeans的生成)

public static void main(String args[]) { 
    /* Set the Nimbus look and feel */ 
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> 
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. 
    * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
    */ 
    try { 
     for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
      if ("Nimbus".equals(info.getName())) { 
       javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
       break; 
      } 
     } 
    } catch (ClassNotFoundException ex) { 
     java.util.logging.Logger.getLogger(Minimo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (InstantiationException ex) { 
     java.util.logging.Logger.getLogger(Minimo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (IllegalAccessException ex) { 
     java.util.logging.Logger.getLogger(Minimo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (javax.swing.UnsupportedLookAndFeelException ex) { 
     java.util.logging.Logger.getLogger(Minimo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } 
    //</editor-fold> 

    /* Create and display the form */ 
    java.awt.EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      new Minimo().setVisible(true); 
     } 
    }); 
} 
+0

問題尋求幫助調試(「?爲什麼不是這個代碼工作」)真的應該包括所期望的行爲,並在*在問題本身*中重現它所需的最短代碼*。請創建併發布您的[mcve],以便我們可以使用一個小型可編譯和可運行的程序,以便我們可以自己測試您的代碼,並希望對其進行修改以使其可以正常工作。請注意,我們不希望看到您的整個程序**,也不應該發佈指向代碼庫的鏈接。相反,保持它小,保持簡單,並使其運作。運氣。 –

+0

顯然它現在按預期工作。我將通過所提供的課程瞭解更多信息。我一直在考慮3個月,而且我總是努力變得更好。 Thx很多yout幫助@Hovercraft充滿了鰻魚。我要看看你編寫的代碼並嘗試優化我的代碼。 – Yoostah

+0

Thx @Bug也有幫助 – Yoostah

回答

1

您當前的代碼不會創建後臺線程。是的,你有Runnables,但你打電話給run(),這意味着你在上調用它們的Swing事件線程。當你這樣做時,你會阻止事件線程,有效地凍結你的程序。相反,您需要:

  • 通過將您的Runnable傳遞給線程對象的構造函數並在該線程上調用start()來創建一個真正的後臺線程。
  • 沒有從這些後臺線程內
  • 變異Swing組件或者使用的SwingWorker爲每Lesson: Concurrency in Swing,這將有助於解決上述問題

對於使用SwingWorker類的例子,請參閱:

import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.util.concurrent.ExecutionException; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class Minimo2 extends JPanel { 
    private static final int EB_GAP = 15; 
    private static final int PROG_BAR_WDTH = 400; 
    public static final int MAX_DATA = 15; 
    private JProgressBar progresso; 
    private JLabel lblProgresso; 
    private JButton jButton1; 
    private Action importDataAction = new ImportDataAction("Import Data"); 

    public Minimo2() { 
     initComponents(); 
    } 

    private void initComponents() { 
     progresso = new JProgressBar(0, MAX_DATA); 
     lblProgresso = new JLabel(" "); 
     jButton1 = new JButton(importDataAction); 
     int progBarHeight = progresso.getPreferredSize().height; 
     progresso.setPreferredSize(new Dimension(PROG_BAR_WDTH, progBarHeight)); 
     progresso.setStringPainted(true); 

     JPanel btnPanel = new JPanel(); 
     btnPanel.add(jButton1); 
     JPanel labelPanel = new JPanel(); 
     labelPanel.add(lblProgresso); 
     JPanel progressPanel = new JPanel(); 
     progressPanel.add(progresso); 

     setBorder(BorderFactory.createEmptyBorder(EB_GAP, EB_GAP, EB_GAP, EB_GAP)); 
     setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); 
     add(btnPanel); 
     add(Box.createVerticalStrut(EB_GAP)); 
     add(labelPanel); 
     add(Box.createVerticalStrut(EB_GAP)); 
     add(progressPanel); 
    } 

    private class ImportDataAction extends AbstractAction { 
     public ImportDataAction(String name) { 
      super(name); // give the button text 
      int mnemonic = (int) name.charAt(0); 
      putValue(MNEMONIC_KEY, mnemonic); // give it a hot key 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      setEnabled(false); // disable our button 
      ImportDataWorker worker = new ImportDataWorker(MAX_DATA); 
      worker.addPropertyChangeListener(new WorkerListener()); 
      worker.execute(); 
     } 
    } 

    private class WorkerListener implements PropertyChangeListener { 
     @Override 
     public void propertyChange(PropertyChangeEvent evt) { 
      if ("progress".equals(evt.getPropertyName())) { 
       int progValue = (int) evt.getNewValue(); 
       progresso.setValue(progValue); 
       String text = String.format("%02d/15", progValue); 
       lblProgresso.setText(text); 
      } else if ("state".equals(evt.getPropertyName())) { 
       if (evt.getNewValue() == SwingWorker.StateValue.DONE) { 
        @SuppressWarnings("rawtypes") 
        SwingWorker worker = (SwingWorker)evt.getSource(); 
        try { 
         worker.get(); 
        } catch (InterruptedException | ExecutionException e) { 
         e.printStackTrace(); 
        } 
        progresso.setValue(MAX_DATA); 
        String text = String.format("%02d/15", MAX_DATA); 
        lblProgresso.setText(text); 
        importDataAction.setEnabled(true); 
       } 
      } 
     } 
    } 

    private class ImportDataWorker extends SwingWorker<Void, Void> { 

     private static final long SLEEP_TIME = 500; 
     private int max; 

     public ImportDataWorker(int max) { 
      this.max = max; 
     } 

     @Override 
     protected Void doInBackground() throws Exception { 
      for (int i = 0; i < max; i++) {     
       setProgress(i); 
       Thread.sleep(SLEEP_TIME); 
      } 
      return null; 
     } 

    } 

    private static void createAndShowGui() { 
     Minimo2 mainPanel = new Minimo2(); 

     JFrame frame = new JFrame("Minimo2"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
}