在这种情况下,ProgressBar properychangeListener不会更新

时间:2014-10-08 05:44:32

标签: java swing progress-bar observer-pattern propertychangelistener

我在包含进度条的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;
    }
}

2 个答案:

答案 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);
    }

}