I have a static boolean variable inProgress in a MainPanel
containing a progressbar. A communicator class changes the value of this variable to true false.
The propertyListener is as follows
@Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("Property change check none");
if(true ==MainPanel.inProgress){
progressInformationPanel.getProgressBar().setIndeterminate(true);
progressInformationPanel.getCurrentProcesLabel().setText("Processing...");
}
else if(false ==MainPanel.inProgress){
System.out.println("Property change check none" + false);
progressInformationPanel.getProgressBar().setIndeterminate(false);
progressInformationPanel.getCurrentProcesLabel().setText("Finished....");
}
}
});
The communicator class is an observer. That is listening to some other class. Now as soon as there is a progress communicator class updates the variable of the MainPanel but the propertyChangeListener
does not act. I am not getting idea about why this is happening. Also please see my linked Question here
Here is the SSCCE
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
public class MainFrame extends JFrame{
public static boolean inProgress = true;
private JProgressBar bar;
public Communicator diplayFacade;
public MainFrame() {
this.setSize(500, 500);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
diplayFacade = new Communicator();
bar = new JProgressBar();
setLayout(new GridBagLayout());
add(bar);
addProgressListener();
}
public void addProgressListener(){
bar.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if(true == MainFrame.inProgress){
System.out.println("Property change check none" + true);
bar.setIndeterminate(true);
}
else if(false ==MainFrame.inProgress){
System.out.println("Property change check none" + false);
bar.setIndeterminate(false);
}
}
});
}
public static void main(String[] args) {
MainFrame frame = new MainFrame();
frame.diplayFacade.methodCalled();
}
}
And the Communicator class
import javax.swing.JOptionPane;
public class Communicator {
public void methodCalled(){
JOptionPane.showInputDialog("Hi");
MainFrame.inProgress = true;
}
}
The problem is, I don't think you understand what the PropertyChangeListener
actually does. A PropertyChangeListener
monitors for changes to the properties of the Object
it is registered to.
This notification doesn't happen by chance or automatically, you need to provide it, normally via PropertyChangeSupport
which helps you manage the PropertyChangeListener
s and triggering events...
By adding a PropertyChangeListener
to the JProgressBar
, you are monitoring for changes to it, not your frame. Equally, by modifying the state of the JProgressBar
from within the PropertyChangeListener
, you risk ending up in an infinite loop, as the object tries to notify you of the changes that you have already made, over and over again....
First of all, you really should avoid using static
in this manner, it would be better to have an instance variable and a setter to change it's state. You would need to pass a reference of the frame to those people interested in changing the state, which raises another issue, you really don't want to expose your elements of your program unnecessarily, so it would be better to encompass this functionality in some kind of interface, for example...
public interface Progressable {
public void addPropertyChangeListener(PropertyChangeListener listener);
public void removePropertyChangeListener(PropertyChangeListener listener);
public void setInProgress(boolean inProgress);
public boolean isInProgress();
}
Then you implement this interface. The Communicator
would then take a reference to an instance of the this interface and call setInProgress
as required, for example...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MainFrame extends JFrame implements Progressable {
private JProgressBar bar;
public Communicator diplayFacade;
private boolean inProgress;
public MainFrame() {
diplayFacade = new Communicator(this);
bar = new JProgressBar();
setLayout(new GridBagLayout());
add(bar);
addPropertyChangeListener("inProgress", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (isInProgress()) {
bar.setIndeterminate(true);
} else {
bar.setIndeterminate(false);
}
}
});
}
@Override
public void setInProgress(boolean value) {
if (inProgress != value) {
inProgress = value;
firePropertyChange("inProgress", !inProgress, inProgress);
}
}
@Override
public boolean isInProgress() {
return inProgress;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new MainFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}