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?
CodePudding user response:
Oracle has a helpful tutorial,
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;
}
}
}
CodePudding user response:
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.