简体   繁体   English

JProgressBar没有更新,找不到线索

[英]JProgressBar doesn't update , can't find a clue

nice job , now i just wanna know why if i add into while loop the instruction System.out.println below the progress is shown on both , cmd and Pgbar in the Gui ?? 很好的工作,现在我只想知道为什么如果我加入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(); } }

need some help around , i can't get the JProgressBar to update, i can't use SwingWorker, i have to solve this without it . 需要一些帮助,我不能让JProgressBar更新,我不能使用SwingWorker,我必须解决这个没有它。 the variable Path.operationProgress is a static variable from a "Path" class instance, and it's updated from another thread, so i think the PBar and Path instances are both executed in user's Threads and not in the EDT . 变量Path.operationProgress是来自“Path”类实例的静态变量,它是从另一个线程更新的,所以我认为PBar和Path实例都是在用户的线程中执行而不是在EDT中执行。 here is the Code of the progress bar : 这是进度条的代码:

  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(); }}} } 

this is the action that launches the threads : 这是启动线程的操作:

 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(){ @Override public void run(){ result = p.SimulatedAnnealing(neighborHood_Type); 线程sa = new Thread(){@ Override public void run(){result = p.SimulatedAnnealing(neighborHood_Type); String lastCostString = result.Cost() + ""; String lastCostString = result.Cost()+“”; lastCostLabel.setText(lastCostString); lastCostLabel.setText(lastCostString); }}; }}; sa.start(); sa.start(); Pbar pb = new Pbar(operationProgressBar); Pbar pb = new Pbar(operationProgressBar); pb.start(); pb.start(); } //Some other Stuff ... } } //其他一些东西......}

If you can't use SwingWorker then use SwingUtilities.invokeLater , eg: 如果您不能使用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);
        }
    });
}

Note: When doing this, everything used in run has to be final or there have to be other measures to access the variables. 注意:执行此操作时, run中使用的所有内容都必须是最终的,或者必须有其他度量来访问变量。 This code is symbolic in that regard. 在这方面,这段代码具有象征意义。

You need to do operations on Swing components outside the event dispatching thread, there is no way around this. 你需要在事件调度线程之外对Swing组件进行操作,没有办法解决这个问题。

I would use a PropertyChangeListener to allow you to make the annealing progress value a "bound" property of the class. 我将使用PropertyChangeListener来允许您使退火进度值成为类的“绑定”属性。 Than any observer can follow this property if desired. 如果需要,任何观察者都可以遵循此属性。 For example: 例如:

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);
   }   
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM