2015-07-06 5 views
0

Это то, что я до сих пор, это, вероятно, совершенно неправильно ...Как сделать обновляемый JProgressBar в JInternalFrame внутри потока?

Проблема, кажется, обновляя процент внутри цикла и затем вызвать его на улице в программе 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, поскольку она обеспечивает возможность оповещать пользовательский интерфейс изменения состояния прогресса довольно легко, к примеру ...

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 Swing и Worker Threads and SwingWorker для получения более подробной информации

+0

TwoDMapEditor.size [1] и 0 всегда одного размера. –

+0

Хорошо, поэтому я проверил SweingWorker, но теперь у меня возникла проблема: он порождает 2 из них в начале программы вместо 1 на actionPerformed. –

+0

Это будет порождать только два, потому что вы создаете дважды вручную, или вы дважды зарегистрировали один и тот же «ActionListener» на кнопку ... – MadProgrammer