我在包含进度条的MainPanel
中有一个静态布尔变量 inProgress 。通信器类将此变量的值更改为true false。
propertyListener如下
@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....");
}
}
});
传播者类是观察者。那是听其他一些课。现在,只要有进度,沟通者类就会更新MainPanel的变量,但propertyChangeListener
不起作用。我不知道为什么会这样。另请参阅此处链接的Question
这是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();
}
}
Communicator类
import javax.swing.JOptionPane;
public class Communicator {
public void methodCalled(){
JOptionPane.showInputDialog("Hi");
MainFrame.inProgress = true;
}
}
答案 0 :(得分:2)
问题是,我不认为你理解PropertyChangeListener
实际上做了什么。 PropertyChangeListener
监视其注册的Object
属性的更改。
此通知不会偶然发生或自动发生,您需要提供,通常通过PropertyChangeSupport
来帮助您管理PropertyChangeListener
和触发事件......
通过向PropertyChangeListener
添加JProgressBar
,您正在监控对其的更改,而不是您的框架。同样,通过从JProgressBar
中修改PropertyChangeListener
的状态,您可能会陷入无限循环,因为对象会尝试通知您已经进行的更改,一遍又一遍再次....
首先,你真的应该避免以这种方式使用static
,最好有一个实例变量和一个setter来改变它的状态。你需要将框架的引用传递给那些对改变状态感兴趣的人,这引发了另一个问题,你真的不想不必要地暴露你的程序元素,所以最好包含这个功能在某种界面中,例如......
public interface Progressable {
public void addPropertyChangeListener(PropertyChangeListener listener);
public void removePropertyChangeListener(PropertyChangeListener listener);
public void setInProgress(boolean inProgress);
public boolean isInProgress();
}
然后实现此接口。然后Communicator
将引用此接口的实例并根据需要调用setInProgress
,例如......
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);
}
});
}
}
答案 1 :(得分:0)
这是工作解决方案。感谢 MadProgrammer 的输入。必须添加PropertyChangeSupport
以便在inProgress
属性发生更改时继续检查。
package progressbarPoc;
import java.awt.DisplayMode;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
public class MainFrame extends JFrame{
public PropertyChangeSupport propertChangeSupport;
public boolean inProgress;
private JProgressBar bar;
public Communicator diplayFacade;
private PropertyChangeListener listener;
public MainFrame() {
this.setSize(500, 500);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
diplayFacade = new Communicator();
diplayFacade.frame = this;
bar = new JProgressBar();
setLayout(new GridBagLayout());
add(bar);
addProgressListener();
propertChangeSupport = new PropertyChangeSupport(this);
addListener();
bar.addPropertyChangeListener(listener);
this.addPropertyChangeListener(listener);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
this.propertChangeSupport.addPropertyChangeListener(listener);
}
public void fireProperty(boolean oldValue , boolean newValue){
this.propertChangeSupport.firePropertyChange("inProgress", oldValue, newValue);
}
public void addProgressListener(){
System.out.println("Here");
}
public static void main(String[] args) {
MainFrame frame = new MainFrame();
frame.diplayFacade.methodCalled();
}
public void addListener(){
listener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
addPropertyChangeListener(this);
if(true == inProgress){
System.out.println("Property change check none" + true);
bar.setIndeterminate(true);
}
else if(false ==inProgress){
System.out.println("Property change check none" + false);
bar.setIndeterminate(false);
}
}
};
}
}
Communicator类
package progressbarPoc;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javax.swing.JOptionPane;
public class Communicator {
public MainFrame frame;
public void methodCalled(){
JOptionPane.showInputDialog("Hi");
frame.inProgress = true;
frame.fireProperty(frame.inProgress, !frame.inProgress);
}
}