-1

I am currently practicing OOP with Java.

I have created a GUI project via WindowBuilder with Eclipse IDE and below is the result.

private JFrame frame;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Example window = new Example();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

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

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 450, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    JProgressBar progressBar = new JProgressBar();
    frame.getContentPane().add(progressBar, BorderLayout.CENTER);
}

What I am trying to do is to connect the JProgressBar to another class that has the actual task, to show the progress.

For example, if the other class contains the following code:

int i = 0;
while(i <= 100) {
    progressBar.setValue(i);
    i++;
}

how should I change the progressBar.setValue(i); part?

CescoDesu
  • 21
  • 3
  • 1
    "I am currently practicing OOP with Java." - Doing this with Swing is as if you'd try to learn juggling with 5 flaming sticks. Try the basics first. – Thomas Oct 11 '22 at 06:00
  • "What I am trying to do is to connect the JProgressBar to another class that has the actual task, to show the progress." - You _could_ just have that other task update the progress bar or you could just send a notification to the progress bar and have it read the data from the tasks model (see the MVC pattern). One important thing though: run the task on a separate thread. – Thomas Oct 11 '22 at 06:03
  • Oracle has a helpful tutorial, [Creating a GUI With Swing](https://docs.oracle.com/javase/tutorial/uiswing/index.html). Skip the Learning Swing with the NetBeans IDE section. Pay particular attention to the [Concurrency in Swing](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html) section. – Gilbert Le Blanc Oct 11 '22 at 06:36

2 Answers2

1

Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section. Pay particular attention to the Concurrency in Swing section.

Here's the simplest working example I could create. As you can see in the picture, I caught the JProgressBar in the middle.

Example

Each time you press the button, the progress bar will count from 0 to 100, one unit every 100 milliseconds.

In order to access the progress bar, you have to make it a class field or variable. You can then access the class field with a setter. Getters and setters are a basic Java concept. You can see another example of a plain Java getter/setter class in my JProgressBarModel class.

I used a Swing Timer to add a delay to the updating of the progress bar so you can see the bar update and simulate an actual long-running task. The actual work takes place in the WorkListener class. Because the code is inside an ActionListener, the Swing update of the progress bar takes place on the Event Dispatch Thread.

Here's the complete runnable code. I made all the additional classes inner classes so I could post the code as one block.

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class JProgressBarExample implements Runnable {

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

    private JProgressBar progressBar;

    private final JProgressBarModel model;

    public JProgressBarExample() {
        this.model = new JProgressBarModel();
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Progress Bar Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createMainPanel(), BorderLayout.CENTER);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel createMainPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        progressBar = new JProgressBar();
        panel.add(progressBar);

        JButton button = new JButton("Start Process");
        button.addActionListener(event -> {
            model.setIndex(0);
            setValue();
            Timer timer = new Timer(100, new WorkListener(this, model));
            timer.start();
        });
        panel.add(button);

        return panel;
    }

    public void setValue() {
        progressBar.setValue(model.getIndex());
    }

    public class WorkListener implements ActionListener {

        private final JProgressBarExample view;

        private final JProgressBarModel model;

        public WorkListener(JProgressBarExample view, JProgressBarModel model) {
            this.view = view;
            this.model = model;
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            Timer timer = (Timer) event.getSource();
            int index = model.getIndex() + 1;
            model.setIndex(index);
            view.setValue();
            if (index >= 100) {
                timer.stop();
            }
        }

    }

    public class JProgressBarModel {

        private int index;

        public int getIndex() {
            return index;
        }

        public void setIndex(int index) {
            this.index = index;
        }

    }

}
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
0

One option is to do it similar to the frame part. You Example class has a field variable that could be directly accessible to your other code.

A better way would be to have a private field for the JProgressBar and a getProgressBar() method.

But currently you are using a method variable that is forgotten when initialize() returns.

Queeg
  • 7,748
  • 1
  • 16
  • 42