2015-07-06 16 views
0

这是我到目前为止,它可能是完全错误的...如何在线程内的JInternalFrame中执行可更新的JProgressBar?

该问题似乎是更新循环内的百分比,然后在SwingUtilities.invokeLater程序中调用它的外部。

此外JInternalFrame坐落在程序的其余部分,也许JDialog会更好地使用。

将在这里进行必要了代码,也愿意,如果你需要更多的信息张贴在github整个项目。(如果被允许)

这是我的代码的第一个项目,因此任何帮助,将不胜感激!

package twoDMapEditor; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.lang.reflect.InvocationTargetException; 

import javax.swing.BorderFactory; 
import javax.swing.JInternalFrame; 
import javax.swing.JProgressBar; 
import javax.swing.SwingUtilities; 

public class SaveActionListener implements ActionListener { 
    public void actionPerformed(ActionEvent me) { 
     final JProgressBar progressBar = new JProgressBar(); 
     progressBar.setValue(0); 
     progressBar.setStringPainted(true); 
     progressBar.setBorder(BorderFactory.createTitledBorder("Saving...")); 
     final JInternalFrame loadingDialog = new JInternalFrame(); 
     loadingDialog.add(progressBar); 
     loadingDialog.pack(); 
     loadingDialog.setVisible(true); 
     TwoDMapEditor.frame.add(loadingDialog); 
     TwoDMapEditor.frame.revalidate(); 
     TwoDMapEditor.frame.repaint(); 

     new Thread(new Runnable() { 
       public void run() { 
        final int percentage = 0; 
        int i = 0, j; 
        while (i < TwoDMapEditor.size[0]) { 
         j = 0; 
         while(j < TwoDMapEditor.size[1]){ 
          if (!TwoDMapEditor.mySql.updateMapPiece(i, j)) { 
           System.out.println("Something went wrong"); 
          } 
          //percentage = ((i * TwoDMapEditor.size[1]) + j+1) * 100/(TwoDMapEditor.size[0] * TwoDMapEditor.size[1]); 
          j++; 
         } 
         i++; 
        } 

        try { 
        SwingUtilities.invokeAndWait(new Runnable() { 
         public void run() { 
          progressBar.setValue(percentage); 
         } 
         }); 
       } catch (InvocationTargetException | InterruptedException e1) { 
        e1.printStackTrace(); 
       } 

        try { 
        java.lang.Thread.sleep(100); 
        } 
        catch(Exception e) { } 
       } 
     }).start(); 
    } 
} 

编辑:现在得到这个:

package twoDMapEditor; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import javax.swing.BorderFactory; 
import javax.swing.JInternalFrame; 
import javax.swing.JProgressBar; 
import javax.swing.SwingWorker; 

public class SaveActionListener implements ActionListener, PropertyChangeListener { 
JProgressBar progressBar; 
ProgressBar progressBarClass; 
JInternalFrame loadingDialog; 

SaveActionListener(){ 
    progressBar = new JProgressBar(); 
    progressBar.setValue(0); 
    progressBar.setStringPainted(true); 
    progressBar.setBorder(BorderFactory.createTitledBorder("Saving...")); 
    loadingDialog = new JInternalFrame(); 
    loadingDialog.add(progressBar); 
    loadingDialog.pack(); 
    loadingDialog.setVisible(true); 
    TwoDMapEditor.frame.add(loadingDialog); 
    TwoDMapEditor.frame.revalidate(); 
    TwoDMapEditor.frame.repaint();   
} 

class ProgressBar extends SwingWorker<Void, Void>{ 
    public int percentage = 1; 
    protected Void doInBackground(){ 
     int i = 0, j; 
      while (i < TwoDMapEditor.size[0]) { 
       j = 0; 
       while(j < TwoDMapEditor.size[1]){ 
        if (!TwoDMapEditor.mySql.updateMapPiece(i, j)) { 
         System.out.println("Something went wrong"); 
        } 
        percentage = ((i * TwoDMapEditor.size[1]) + j+1) * 100/(TwoDMapEditor.size[0] * TwoDMapEditor.size[1]); 
        progressBar.setValue(percentage); 
        System.out.println(percentage); 
        j++; 
       } 
       i++; 
      } 

     return null; 
    } 

    public void done(){ 
     loadingDialog.dispose(); 
    } 
} 

public void actionPerformed(ActionEvent me) { 
    progressBarClass = new ProgressBar(); 
    progressBarClass.addPropertyChangeListener(this); 
    progressBarClass.execute(); 
} 

public void propertyChange(PropertyChangeEvent pce) { 
    System.out.println(TwoDMapEditor.saveActionListener.progressBarClass.percentage); 
    progressBar.setValue(TwoDMapEditor.saveActionListener.progressBarClass.percentage); 
} 

}

+0

我会用'SwingWorker'作为初学者... – MadProgrammer

+0

谢谢你一定会看看!全新的,所以需要学习很多! :) –

回答

0

没有一个完全可运行的例子,它是一种很难知道在哪里的问题可能是。

您应该坚决更新循环内的进度。如果你能保证每一个TwoDMapEditor.size[1]都是相同的价值,那就更容易了。

您基本上需要知道两件事情,即可能的迭代总数和已完成的迭代次数,但我没有在您的代码段中看到可能提供该信息的任何信息。

反正我也建议使用SwingWorker,因为它提供了非常简便地通知进度状态变化的UI的能力,例如...

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.GridBagLayout; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.util.Random; 
import javax.swing.JDesktopPane; 
import javax.swing.JFrame; 
import javax.swing.JInternalFrame; 
import javax.swing.JPanel; 
import javax.swing.JProgressBar; 
import javax.swing.SwingWorker; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TestProgress { 

    public static void main(String[] args) { 
     new TestProgress(); 
    } 

    public TestProgress() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JDesktopPane dp = new JDesktopPane() { 

        @Override 
        public Dimension getPreferredSize() { 
         return new Dimension(400, 400); 
        } 

       }; 
       JInternalFrame inf = new JInternalFrame("Progressing", true, false, false, false); 
       inf.add(new TestPane()); 
       inf.pack(); 
       dp.add(inf); 
       inf.setVisible(true); 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(dp); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private JProgressBar pb; 

     public TestPane() { 
      setLayout(new GridBagLayout()); 
      pb = new JProgressBar(); 
      add(pb); 

      LongRunningProcessWorker worker = new LongRunningProcessWorker(); 
      worker.addPropertyChangeListener(new PropertyChangeListener() { 
       @Override 
       public void propertyChange(PropertyChangeEvent evt) { 
        String name = evt.getPropertyName(); 
        SwingWorker worker = (SwingWorker) evt.getSource(); 
        switch (name) { 
         case "progress": 
          System.out.println(worker.getProgress()); 
          pb.setValue(worker.getProgress()); 
          break; 
         case "state": 
          switch (worker.getState()) { 
           case DONE: 
            // Close the window or something 
            break; 
          } 
          break; 
        } 
       } 
      }); 
      worker.execute(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

    } 

    public class LongRunningProcessWorker extends SwingWorker { 

     @Override 
     protected Object doInBackground() throws Exception { 

      Random rnd = new Random(); 
      int outterMax = rnd.nextInt(150) + 50; 
      int innerMax = rnd.nextInt(150) + 50; 

      System.out.println(outterMax + "/" + innerMax); 

      for (int outter = 0; outter < outterMax; outter++) { 
       for (int inner = 0; inner < innerMax; inner++) { 
        float progress = (float)((outter * innerMax) + inner)/(float)(innerMax + outterMax); 
        Thread.sleep(10); // Simulate some processing 
       } 
      } 
      return null; 
     } 

    } 

} 

看看Concurrency in SwingWorker Threads and SwingWorker欲了解更多详情

+0

TwoDMapEditor.size [1]和0的大小始终相同。 –

+0

好吧,所以我检查了SweingWorker,但现在我得到了问题,它在程序的开头产生了2个,而不是1个在actionPerformed上。 –

+0

它只会产生两个,因为你手动创建两次或者你已经注册了相同的'ActionListener'两次按钮...... – MadProgrammer