JProgressBar kann nicht von der SwingWorker-Klasse aktualisiert werden

Ich habe meinen Haupt-GUI-Thread, der eine JprogressBar enthält und ProprtyChangeListener implementiert.

Wenn eine Taste gedrückt wird, tritt eine andere Klasse in Aktion, die SwingWorker erweitert, und führt eine Reihe potenziell langer Berechnungen durch. Ich benötige den Fortschrittsbalken in Klasse A, um den Fortschritt anhand einer Variablen in Klasse B darzustellen.

Mein Code ist unten (könnte bei all meinen fehlgeschlagenen Versuchen etwas chaotisch sein ...)

Würde mich über jede Hilfe freuen.

GUI-KLASSE:

SignalSimulator signalSimulator = new SignalSimulator(
                path, numOfdataPoints, numOfLocalSpikes,
                    numOfExpSpikes, noiseAmp, slope, offset,
                                    rdbtnSineWave.isSelected());       
signalSimulator.addPropertyChangeListener( new PropertyChangeListener() {
    public void propertyChange(PropertyChangeEvent evt) {
        String property = evt.getPropertyName();
        if ("progress".equals(property)) {
            int progress = (Integer) evt.getNewValue();
            System.out.println("value in PropertChangeListener is: " + progress);
            progressBar.setValue(progress);
        }
    }
});
signalSimulator.execute(); 

Klasse berechnen:

protected Integer doInBackground() throws Exception {
    if (isSine){
        data = generateSineWave(numOfDataPoints, noiseAmp, offset);
        data = addAnomalies(data, numOfPointOutliers, numOfExpSpikes);
    } else {
        data = generateLinearSignal(numOfDataPoints, noiseAmp, slope, offset);
        data = addAnomalies(data, numOfPointOutliers, numOfExpSpikes);
    }
    writeLogFile(path, ".txt", data);
    firePropertyChange("progress", 1, 1);
    setProgress((int)progress);
    publish(progress);
    System.out.println("value in doInBackground is: " + progress);
    return 1;
}

BEARBEITE

Original Problem bleibt. Aus irgendeinem Grund wird der Fortschrittsbalken immer noch nicht aktualisiert. Ich weiß mit Sicherheit, dass die Variable "progress" in progressBar.setValue (progress) aktualisiert wird. Der Fortschrittsbalken in der GUI bleibt jedoch unverändert (auf 0 festgelegt). Hier ist mein neuer Code:

GUI-Klasse:

    SignalSimulator signalSimulator = new SignalSimulator(path, numOfdataPoints, numOfLocalSpikes, numOfExpSpikes, noiseAmp, slope, offset, rdbtnSineWave.isSelected());       
    signalSimulator.addPropertyChangeListener( new PropertyChangeListener() {
      public void propertyChange(PropertyChangeEvent evt) {
        String property = evt.getPropertyName();

        if ("progress".equals(property)) {
            int progress = (Integer) evt.getNewValue();
             System.out.println("value in PropertChangeListener is: " + progress);
             progressBar.setValue(progress);

        }
      }
    });
    signalSimulator.execute();

SwingWorker Klasse:

@Override
        protected Integer doInBackground() throws Exception {

            if (isSine){
                data = generateSineWave(numOfDataPoints, noiseAmp, offset);
                data = addAnomalies(data, numOfPointOutliers, numOfExpSpikes);
            }
            else{
                data = generateLinearSignal(numOfDataPoints, noiseAmp, slope, offset);
                data = addAnomalies(data, numOfPointOutliers, numOfExpSpikes);
            }

            writeLogFile(path, ".txt", data);

            return 1;}


public double[] generateSineWave(int numOfDataPoints, double noiseAmp, double offset){

            Random rnd = new Random();
            double[] dataArray = new double[numOfDataPoints];           


            for (int i=0;i<numOfDataPoints;i++){

                dataArray[i] =  Math.sin(Math.toRadians(i))+rnd.nextDouble()*noiseAmp+offset;
                progress = ((double)i)/(double)numOfDataPoints*100;

                //firePropertyChange("progress", 1, 1);
                setProgress((int)progress);
                //publish(progress);
                System.out.println("value in doInBackground is: " + progress);
            }

            return dataArray;           

BEARBEITE Das Ganze ohne den zusätzlichen (irrelevanten) Code umgeschrieben. Ich vermisse hier etwas Grundlegendes, da die Fortschrittsanzeige immer noch nicht aktualisiert wird.

public class ProgressBarTest implements PropertyChangeListener {


    private JFrame frame;
    private JButton btnRun;
    static JProgressBar progressBar = new JProgressBar(0,100);

public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable()  {
            public void run() {
                try {
                    //UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); 
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); 
                    ProgressBarTest window = new ProgressBarTest();
                    window.frame.setVisible(true);
                    //SignalSimulator signalSimulator = new SignalSimulator();

                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        });
    }

/**
 * Create the application.
 */
public ProgressBarTest() {
    initialize();
}

private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 450, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(null);
    frame.setResizable(false);  

    JProgressBar progressBar = new JProgressBar();
    progressBar.setAlignmentX(Component.RIGHT_ALIGNMENT);
    progressBar.setBounds(0, 252, 444, 20);
    progressBar.setStringPainted(true);
    frame.getContentPane().add(progressBar);


    JButton btnRun = new JButton("Start Long Run");
    btnRun.setBounds(167, 214, 159, 31);
    frame.getContentPane().add(btnRun);
    btnRun.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            longRun();
        }

    } );

}


private void longRun(){

    LongRunner longRunner = new LongRunner(100000);
    longRunner.addPropertyChangeListener(new PropertyChangeListener() {

        @Override
        public void propertyChange(PropertyChangeEvent evt) {

            if ("progress".equals(evt.getPropertyName())){
                int progress = (int) evt.getNewValue();
                System.out.println("Value in propertyChangeListener: "+progress);
                progressBar.setValue(progress);
            }
        }
    });
    longRunner.execute();
}
@Override
public void propertyChange(PropertyChangeEvent arg0) {
    // TODO Auto-generated method stub

}

}

Und der SwingWorker:

import javax.swing.SwingWorker;


public class LongRunner extends SwingWorker<Integer, Double>{

    int numOfPoints;
    double progress;

    public LongRunner(int numOfPoints) {

        this.numOfPoints = numOfPoints;
        this.progress = 0;
    }

    private void runLong(int bigNum){

        for (int i=0; i< bigNum; i++){

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            progress =  (((double)i*100)/(double)bigNum);
            setProgress((int)progress);
            System.out.println("Value in setProgress: "+progress);

        }

    }
    @Override
    protected Integer doInBackground() throws Exception {

        runLong(numOfPoints);
        return null;
    }

}

Was mache ich hier falsch?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage