javaswingnetbeanspolymorphismmatisse

Cannot invoke "this.firePropertyChange()" on JPanel reference


Why can I not invoke firePropertyChange() on this reference?

    [javac] /home/thufir/NetBeansProjects/Legacy/src/legacy/gui/table/SelectTableFollowup.java:41: error: cannot find symbol
    [javac]                     this.firePropertyChange("client", null, i);
    [javac]                         ^
    [javac]   symbol: method firePropertyChange(String,<null>,int)
    [javac] Note: Some input files use unchecked or unsafe operations.
    [javac] Note: Recompile with -Xlint:unchecked for details.
    [javac] 1 error
    [javac] 1 warning

BUILD FAILED
/home/thufir/NetBeansProjects/Legacy/nbproject/build-impl.xml:923: The following error occurred while executing this line:
/home/thufir/NetBeansProjects/Legacy/nbproject/build-impl.xml:263: Compile failed; see the compiler error output for details.

Total time: 4 seconds
thufir@dur:~/NetBeansProjects/Legacy$ 

This is my code:

package legacy.gui.table;

import java.awt.BorderLayout;
import java.util.logging.Logger;
import javax.swing.JPanel;
import legacy.database.Queries;

public class SelectTableFollowup extends JPanel {

    private static final Logger log = Logger.getLogger(SelectTableFollowup.class.getName());
    private ClientsTable table;
    private Followup followup;
    private Select Select;
    private final Queries queries = new Queries();

    public SelectTableFollowup() {
        initComponents();
    }

    private void initComponents() {
        table = new ClientsTable();
        followup = new Followup();
        Select = new Select();
        setLayout(new BorderLayout());
        add(Select, BorderLayout.NORTH);
        add(table, BorderLayout.CENTER);
        add(followup, BorderLayout.SOUTH);
        followupButton();
        query();
        cannotFirePropertyChangeOnThisObj();
    }

    private void cannotFirePropertyChangeOnThisObj() {
        table.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            @Override
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                if ("client".equals(evt.getPropertyName())) {
                    String s = evt.getNewValue().toString();
                    int i = Integer.parseInt(s);
                    log.info("i is " + i);
                    this.firePropertyChange("client", null, i);
                }
            }

        });
    }

    private void followupButton() {
        followup.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            @Override
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                if ("followup".equals(evt.getPropertyName())) {
                    try {
                        int id = table.getId();
                        queries.send(id);
                        table.updateModel();
                    } catch (ArrayIndexOutOfBoundsException obe) {
                        log.info(obe.toString());  //no big deal
                    }
                }
            }
        });
    }

    private void query() {
        Select.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            @Override
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                if ("select".equals(evt.getPropertyName())) {
                    log.info(evt.getNewValue().toString());
                    table.select(evt.getNewValue().toString());
                }
            }
        });
    }
}

From Netbeans, I know that it's quite possible to invoke this.firePropertyChange(), for JPanel's which NetBeans creates.

How is the above class any different from a Netbeans generated class? Both extend the same base class.

If I've misused any terminology, please do let me know.


Solution

  • In this context:

    table.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
        @Override
        public void propertyChange(java.beans.PropertyChangeEvent evt) {
            ...
            this.firePropertyChange("client", null, i);
        }
    }
    

    The keyword this refers to the anonymous inner class generated when you create a new PropertyChangeListener instance. This fact is explained here: Using the this Keyword

    Take a look to this topic: Keyword for the outer class from an anonymous inner class? You should replace this line for this one to refer to your panel class:

    table.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
        @Override
        public void propertyChange(java.beans.PropertyChangeEvent evt) {
            ...
            SelectTableFollowup.this.firePropertyChange("client", null, i);
        }
    }
    

    Or you can remove this and compiler will resolve the same for you:

    table.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
        @Override
        public void propertyChange(java.beans.PropertyChangeEvent evt) {
            ...
            firePropertyChange("client", null, i);
        }
    }
    

    Given the anonymous inner class doesn't have any firePropertyChange() method, compiler will look up for the outer class (or eventually the hierarchy tree) and chek if it has such method, which is indeed the case.