2013-12-14 1 views
0

기본적으로 JProgressBar가 JPanel에 추가 된 GUI의 경우 1, JProgressBar를 업데이트해야하는 프로세스가있는 클래스 인 경우 2 가지 클래스가 있습니다.JProgressBar가 다른 클래스의 메서드에 매개 변수로 전달되고 업데이트되지 않습니다?

내 문제는 진행률 표시 줄이 주기적으로 업데이트되지 않으며 처리가 완전히 끝난 후에 만 ​​업데이트된다는 것입니다. 나는 SwingUtilities.invokeLater()를 사용하여 시도했지만, 어떻게 든 처리 작업이 나중에 수행하고, 처리도 실행되기 전에 모두 완료 메시지가 처음 인쇄 된 밝혀, 그래서 나는()의 invokeAndWait을 시도하고있다.

나는 답을 주위에 검색 한, 그러나 대부분은 그냥 내 경우에, 2 개의 분리되는 반면, GUI 및 업데이트가, 같은 클래스에서 이루어집니다 JProgressBar가의 예를 제공합니다. 또한 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; 
} 
} 

예 클래스 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()가 호출된다. 이 JProgressBar가 업데이트해야하는 위치입니다 : 당신은 백그라운드 스레드에서 restorebackup() 호출하지 않을

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

OK, 결국 난 그냥 내 TextureEditor 클래스 내부 SwingWorker의 클래스를 사용하기로 결정했다. 이것은 내 문제를 해결했다. 그러나 doInBackGround()에 restorebackup() 작업을 복사해야합니다.

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

'restorebackup (tpath, imagetype);에 의해'SwingUtilities.invokeAndWait (doHelloWorld);를 대체하십시오. –