JProgressBar не обновляется, не могу найти подсказку - PullRequest
3 голосов
/ 19 февраля 2012

Хорошая работа, теперь я просто хочу знать, почему, если я добавлю в цикл while инструкцию System.out.println ниже прогресса, показанного на обоих, cmd и Pgbar в графическом интерфейсе ??:

while(progress < 99){ 
  System.out.println("into while of PBar Thread progress = "+progress); 
  if(progress != Path.operationProgress){ 
    operationProgressBar.setValue(progress); 
    progress = Path.operationProgress; 
    operationProgressBar.repaint(); } }

нужна помощь, я не могу обновить JProgressBar, я не могу использовать SwingWorker, я должен решить это без него.Переменная Path.operationProgress является статической переменной из экземпляра класса «Path», и она обновляется из другого потока, поэтому я думаю, что экземпляры PBar и Path выполняются в пользовательских потоках, а не в EDT.вот код индикатора выполнения:

    import javax.swing.*;
    public class Pbar extends Thread {
      JProgressBar operationProgressBar;
      public Pbar(JProgressBar operationProgressBar) {
          this.operationProgressBar = operationProgressBar;
      }

      @Override
      public void run() {
          int progress = Path.operationProgress;
          while(progress < 99) {
              if(progress != Path.operationProgress) {
                  operationProgressBar.setValue(progress);
                  progress = Path.operationProgress;
                  operationProgressBar.repaint();
              }}}
     }

это действие, запускающее потоки:

private javax.swing.JProgressBar operationProgressBar;
private javax.swing.JLabel pathImage;
private javax.swing.JButton simulatedAnnelingButton;

public class TSPGUI extends javax.swing.JFrame {

    TSPMG tspInstance;
    Path p, result;
    String filename = "";
    int neighborHood_Type = 1, i = 0;
    // ......Constructor Stuff and init()

private void simulatedAnnelingButtonActionPerformed(java.awt.event.ActionEvent evt)

{
Thread sa = new Thread () {@Overridepublic void run () {result = p.SimulatedAnnealing (neighbour_Type);String lastCostString = result.Cost () + "";lastCostLabel.setText (lastCostString);}};sa.start ();Pbar pb = новый Pbar (operationProgressBar);pb.start ();} // Некоторые другие вещи ...}

Ответы [ 2 ]

5 голосов
/ 19 февраля 2012

Если вы не можете использовать SwingWorker, тогда используйте SwingUtilities.invokeLater, например ::

if (progress != Path.operationProgress) {
    final int progressCopy = progress; // Probably not final so copy is needed
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        void run() {
            operationsProgressBar.setValue(progressCopy);
        }
    });
}

Примечание. При этом все, что используется в run, должно быть окончательным или должны быть другие меры для доступа к переменным. Этот код является символическим в этом отношении.

Вам необходимо выполнять операции с компонентами Swing вне потока диспетчеризации событий, этого нет.

0 голосов
/ 19 февраля 2012

Я бы использовал PropertyChangeListener, чтобы позволить сделать значение процесса отжига «связанным» свойством класса.Тогда любой наблюдатель может следить за этим свойством при желании.Например:

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;

@SuppressWarnings("serial")
public class TspGui2 extends JPanel {
   private static final String ANNEALING_PROGRESS = "Annealing Progress";
   private JProgressBar progBar = new JProgressBar(0, 100);
   private JLabel valueLabel = new JLabel();
   private JButton beginAnnealingBtn = new JButton("Begin Annealing");
   private MyAnnealing myAnnealing = new MyAnnealing(this);

   public TspGui2() {
      beginAnnealingBtn.addActionListener(new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent e) {
            beginAnnealing();
         }
      });
      myAnnealing.addPropertyChangeListener(new PropertyChangeListener() {

         @Override
         public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getPropertyName().equals(MyAnnealing.ANNEALING)) {
               // be sure this is done on the EDT
               SwingUtilities.invokeLater(new Runnable() {
                  public void run() {
                     int annealedValue = myAnnealing.getAnnealedValue();
                     setValue(annealedValue);
                     if (annealedValue >= MyAnnealing.MAX_ANNEALED_VALUE) {
                        beginAnnealingBtn.setEnabled(true);
                     }
                  }
               });
            }
         }
      });
      progBar.setString(ANNEALING_PROGRESS);
      progBar.setStringPainted(true);

      JPanel northPanel = new JPanel(new GridLayout(1, 0));
      northPanel.add(beginAnnealingBtn);
      northPanel.add(valueLabel);

      setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
      add(northPanel);
      add(progBar);
   }

   public void setValue(int value) {
      valueLabel.setText("Value:" + value);
      progBar.setValue(value);
   }

   public void beginAnnealing() {
      beginAnnealingBtn.setEnabled(false);
      setValue(0);
      myAnnealing.reset();
      new Thread(new Runnable() {
         public void run() {
            myAnnealing.beginAnnealing();
         }
      }).start();
   }

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

      JFrame frame = new JFrame("TspGui2");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class MyAnnealing {
   public static final String ANNEALING = "Annealing";
   public  static final int MAX_ANNEALED_VALUE = 100;
   private SwingPropertyChangeSupport propChangeSupport = 
         new SwingPropertyChangeSupport(this);
   private TspGui2 gui;
   private int annealedValue;

   public MyAnnealing(TspGui2 gui) {
      this.gui = gui;
   }

   public void addPropertyChangeListener(
         PropertyChangeListener listener) {
      propChangeSupport.addPropertyChangeListener(listener);
   }

   public void removePropertyChangeListener(
         PropertyChangeListener listener) {
      propChangeSupport.removePropertyChangeListener(listener);
   }

   public void reset() {
      setAnnealedValue(0);
   }

   // simulate some long process...
   public void beginAnnealing() {
      long sleepDelay = 100;
      while (annealedValue < MAX_ANNEALED_VALUE) {
         setAnnealedValue(annealedValue + 1);
         try {
            Thread.sleep(sleepDelay);
         } catch (InterruptedException e) {
            e.printStackTrace();
         }
      }
   }

   public int getAnnealedValue() {
      return annealedValue;
   }

   private void setAnnealedValue(int value) {
      final int oldValue = this.annealedValue;
      this.annealedValue = value;
      propChangeSupport.firePropertyChange(ANNEALING, oldValue, annealedValue);
   }   
}
...