2013-12-14 43 views
0

基本上,我有2個類:1,JProgressBar被添加到JPanel的GUI,另一個是具有JProgressBar應該更新的進程的類。JProgressBar作爲參數傳遞給其他類中的方法&將不會更新?

我的問題是進度條不會定期更新,只會在處理完成後纔會更新。我嘗試過使用SwingUtilities.invokeLater(),但不知怎的,事後證明處理任務已完成,並且在處理甚至執行之前所有已完成的消息都已經打印出來,所以我正在嘗試invokeAndWait()。

我搜索了周圍的答案,但其中大多數只是舉例JProgressBar GUI和更新在同一類中完成,而在我的情況下,2是分開的。我也考慮過SwingWorker,但不知道我應該在哪裏以及如何實現它,因爲它會改變我的程序結構。

以下是我的代碼。對不起,它是混亂的,命名不是很連貫,我嘗試了很多東西來使進度條更新,並需要一些時間來重新組織(但基本上代碼工作正常)。

的GUI類(參見具體方法getYesButton()):

public class TextureRevertPanel extends JPanel { 

private TextureEditor te; 
private TextureEditorGUI parent; 
private JButton yesButton; 
private JButton noButton; 
private String imgtype; 
private String path; 
private JProgressBar pbar; 
static final int MY_MINIMUM = 0; 
static final int MY_MAXIMUM = 100; 

public TextureRevertPanel(TextureEditor te, TextureEditorGUI parent, String imgtype, String path) { 
    super(); 
    this.parent = parent; 
    setPreferredSize(new Dimension(800, 400)); 

    setLayout(new GridBagLayout()); 

    GridBagConstraints c = new GridBagConstraints(); 
    c.insets = new Insets(5, 5, 5, 5); 
    c.anchor = GridBagConstraints.WEST; 

    c.gridx = 0; 
    c.gridy = 0; 
    c.gridwidth = 2; 
    add(new JLabel("Energy saving mode is turned ON, do you want to turn it off?"), c); 

    c.gridx = 0; 
    c.gridy = 1; 
    c.gridwidth = 2; 
    JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING)); 
    bottomPanel.add(getYesButton()); 
    bottomPanel.add(getNoButton()); 
    add(bottomPanel, c); 

    c.gridx = 0; 
    c.gridy = 4; 
    c.gridwidth = 1; 
    add(new JLabel("Progress"), c); 

    c.gridx = 1; 
    c.gridy = 4; 
    c.gridwidth = 1; 
    pbar = new JProgressBar(); 
    pbar.setMinimum(MY_MINIMUM); 
    pbar.setMaximum(MY_MAXIMUM); 
    // add to JPanel 
    add(pbar, c); 

    this.te = te; 
    this.path = path; 
    this.imgtype = imgtype; 

} 

private JButton getYesButton() { 
    if (yesButton == null) { 
     yesButton = new JButton("Yes"); 
     yesButton.addMouseListener(new MouseAdapter() { 

      @Override 
      public void mouseReleased(MouseEvent e) { 
       if (MouseEvent.BUTTON1 == e.getButton()) { 
        boolean b = te.revertTextures("Y", path, imgtype, pbar); 
        if (b) { 
         /*JOptionPane.showMessageDialog(
           parent.getMainFrame(), 
           "Textures in " + path + " have been reverted back", 
           "Notification", JOptionPane.INFORMATION_MESSAGE);*/ 
         //parent.showMainPane(); 
        } 
       } 
      } 
     }); 
    } 
    return yesButton; 
} 

private JButton getNoButton() { 
    if (noButton == null) { 
     noButton = new JButton("No"); 
     noButton.addMouseListener(new MouseAdapter() { 

      @Override 
      public void mouseReleased(MouseEvent e) { 
       if (MouseEvent.BUTTON1 == e.getButton()) { 
        parent.showMainPane(); 
       } 
      } 
     }); 
    } 
    return noButton; 
} 
} 

按YES,類將調用TextureEditor類的方法revertTextures()。 JProgressBar pbar作爲參數傳遞給方法。

然後,在TextureEditor的revertTextures方法:

public boolean revertTextures(String input, String texturepath, String imgtype,  JProgressBar pbar) { 
    System.out.println("Energy saving mode is on, do you want to turn it off?(Y/N)"); 
    if (input.equalsIgnoreCase("Y")) { 
     System.out.println("Turning off energy saving mode..."); 
     //copy all the png in the backup folder to texture folder 
final String tpath = texturepath; 
final String imagetype = imgtype; 
this.pbar = pbar; 
final Runnable doHelloWorld = new Runnable() { 

      public void run() { 
       System.out.println("Hello World on " + Thread.currentThread()); 
       restorebackup(tpath, imagetype); 
      } 
     }; 

     Thread appThread = new Thread() { 

      @Override 
      public void run() { 
       try { 
        SwingUtilities.invokeAndWait(doHelloWorld); 
        String text = "OFF"; 
        try { 
         File file = new File(tpath + "backup\\indicator.txt"); 
         BufferedWriter output = new BufferedWriter(new FileWriter(file)); 
         output.write(text); 
         output.close(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
        System.out.println("Energy saving mode has been turned off."); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
       System.out.println("Finished on " + Thread.currentThread()); 
      } 
     }; 
     appThread.start(); 

然後該線程內,真正的處理方法restorebackup()被調用。這是關於SpringLayout應該被更新:

public void restorebackup(String tpath, String imgtype) { 
    File backuppath = new File(tpath + "backup\\"); 
    final File[] files = backuppath.listFiles(); 
    final String imagetype = "." + imgtype; 
    final String texpath = tpath; 
    final String imagtype = imgtype; 

    for (int i = 0; i < files.length; i++) { 
     final int ii = i; 
     System.out.println(files[i].getName()); 
     File texturepath; 
     BufferedImage image; 
     try { 
      System.out.println(files[ii]); 
      if (files[ii].getName().contains(imagetype)) { 
       texturepath = new File(texpath + files[ii].getName()); 
       image = ImageIO.read(files[ii]); 
       ImageIO.write(image, imagtype, texturepath); 
       double proportion = (ii/(double) (files.length - 1)); //count out the indicator file 
       System.out.println((int) (proportion * 100) + "%"); 
       pbar.setValue((int) (proportion * 100)); 
      } 
     } catch (IOException e) { 
      System.out.println("Could not open texture files in backup folder"); 
     } 
    } 
    System.out.println("Done"); 
} 
+0

1)爲了更快得到更好的幫助,請發佈[SSCCE](http://sscce.org/)。 2)請不要忘記添加'?'提問!有些人在頁面中搜索'?'如果'問題'中不存在,則直接進入下一個(實際)問題。 –

回答

0

好的,最後我決定在我的TextureEditor類中使用一個SwingWorker類。這解決了我的問題。不過,我需要將restorebackup()操作複製到doInBackGround()。

private static class MySwingWorker extends SwingWorker<String, Double> { 

    private final JProgressBar fProgressBar; 
    private final String tpath; 
    private final String imagetype; 
    private final TextureEditorGUI parent; 

    private MySwingWorker(JProgressBar aProgressBar, String tpath, String imagetype, TextureEditorGUI parent) { 
     fProgressBar = aProgressBar; 
     this.tpath = tpath; 
     this.imagetype = imagetype; 
     this.parent = parent; 
    } 

    @Override 
    protected String doInBackground() throws Exception { 
     File backuppath = new File(tpath + "backup\\"); 
     File texturepath; 
     final File[] files = backuppath.listFiles(); 
     BufferedImage image; 
     final String texpath = tpath; 
     for (int i = 0; i < files.length; i++) { 
      final int ii = i; 
      try { 
       System.out.println(files[i].getName()); 
       System.out.println(files[ii]); 
       if (files[ii].getName().contains("." + imagetype)) { 
        texturepath = new File(texpath + files[ii].getName()); 
        image = ImageIO.read(files[ii]); 
        ImageIO.write(image, imagetype, texturepath); 
        double proportion = (ii/(double) (files.length - 1)); //count out the indicator file 
        publish(proportion); 
        System.out.println((int) (proportion * 100) + "%"); 
       } 
      } catch (IOException e) { 
       System.out.println("Could not open texture files in backup folder"); 
      } 
     } 
     return "Finished"; 
    } 

    @Override 
    protected void process(List<Double> aDoubles) { 
     //update the percentage of the progress bar that is done 
     int amount = fProgressBar.getMaximum() - fProgressBar.getMinimum(); 
     fProgressBar.setValue((int) (fProgressBar.getMinimum() + (amount * aDoubles.get(aDoubles.size() - 1)))); 
    } 

    @Override 
    protected void done() { 
     try { 
      JOptionPane.showMessageDialog(
        parent.getMainFrame(), 
        "Textures in " + tpath + " have been reverted back", 
        "Notification", JOptionPane.INFORMATION_MESSAGE); 
      parent.showMainPane(); 
     } catch (Exception ignore) { 
     } 
    } 
} 

但是,我有我的TextureEditor類中的另一種方法,需要進度欄更新以及。這是否意味着我需要爲其他方法創建另一個SwingWorker類,或者SwingWorker內部的條件會做什麼(即將參數傳遞給SwingWorker,並且它將通過條件爲不同的方法執行不同的操作)?

0

你不是要求從後臺線程​​。你從事件調度線程調用它,因爲它的調用被包裝在SwingUtilities.invokeAndWait()的調用中。因此,此方法中的所有工作都是在UI線程中完成的,凍結它並阻止它更新UI,直到方法完成。

您必須在後臺線程中完成所有這項工作,除了進度條的更新外,必須將其更新到SwingUtilities.invokeLater()調用中。

或者更好,你應該閱讀SwingWorker的文檔並使用它。

+0

我如何在後臺線程中完成這項工作?我試着把裏面的進度條更新放在restorebackup()或revertTextures()裏面的SwingUtilities.invokeLater()裏面,它仍然沒有更新。 –

+0

替換'SwingUtilities.invokeAndWait(doHelloWorld);'''restorebackup(tpath,imagetype);' –

相關問題