Re: Losing controlListeners when display is rebuilt



Bill Hibbard wrote:


Not a bug, just the way it works. The DisplayImpl.clearMaps()
call clears up everything (it is desireable to have a method
that clears up everything - the bug would be to find something
that is not cleared up).



Then this works differently than the other unique controls in a
Display. I mispoke in my previous message.  ProjectionControl
does act differently from GraphicsModeControl and RendererControl.
If I add ControlListeners to these two controls, when I rebuild
the display I do not lose my listeners, as I would expect should
happen since these controls are only created once and nothing
in clearMaps removes ControlListeners (other than the DisplayMonitor)
from a control.  So, clearMaps does not really "clear up everything".
That being the case, I would think that
either ProjectionControl should not remove it's listeners, or
that GraphicsModeControl and RendererControl should for
consistency.  Since they are unique controls, I think
ProjectionControl should retain it's listeners.  The only thing
that should clear out all listeners for a control is calling
Control.nullControl() and the only thing that does this is
ScalarMap.  Since ProjectionControl is not related to any
ScalarMap (i.e. it's not gotten by ScalarMap.getControl()),
I don't see why its listeners are cleared or stop working
upon a rebuild.

It is good to have a method to clear everything up, as long
as it actually does that.  Since GraphicsModeControl and
RendererControl don't get cleared up, then I'd maintain that
there is a bug in there somewhere.

>The work-around is to re-add the
> ControlListerner after rebuilding the display.

So in addition to a ControlListener, I have to add a DisplayListener
to listen for MAPS_CLEARED and then guess which ones got added
back and which ones didn't?

I've attached a modified version of PCTest that shows the
inconsistent behavior between these unique controls.


Don

import visad.*;
import visad.java3d.*;
import visad.java2d.*;
import visad.data.mcidas.BaseMapAdapter;
import javax.swing.*;
import java.util.Vector;
import java.awt.event.*;

public class PCTest extends JFrame {

    DisplayImpl display;
    DataReference mapRef;

    public PCTest() {

        try {
           addWindowListener(new WindowAdapter() {
               public void windowClosing(WindowEvent we) {
                   System.exit(0);
               }
           });
           display = new DisplayImplJ3D("display");
           makeControlListener(display.getGraphicsModeControl());
           makeControlListener(display.getProjectionControl());
           makeControlListener(
             display.getDisplayRenderer().getRendererControl());

           display.addMap(
              new ScalarMap(RealType.Latitude, Display.YAxis));
           display.addMap(
              new ScalarMap(RealType.Longitude, Display.XAxis));
           display.addMap(
              new ScalarMap(RealType.Altitude, Display.ZAxis));
           BaseMapAdapter bma = new BaseMapAdapter("OUTLUSAM");
           mapRef = new DataReferenceImpl("map");
           mapRef.setData(bma.getData());
           display.addReference(mapRef);
           getContentPane().add(display.getComponent());
           JPanel p = new JPanel();
           JCheckBox scale = new JCheckBox("Scale On", false);
           scale.addActionListener(new ActionListener() {
               public void actionPerformed(ActionEvent be) {
                 try {
                   display.getGraphicsModeControl().setScaleEnable(
                     ((JCheckBox)be.getSource()).isSelected());
                 } catch (Exception e) {
                    e.printStackTrace();
                 }
               }
           });
           p.add(scale);
           JCheckBox color = new JCheckBox("White Background", false);
           color.addActionListener(new ActionListener() {
               public void actionPerformed(ActionEvent be) {
                 try {
                   RendererControl r = 
                       display.getDisplayRenderer().getRendererControl();
                   if (((JCheckBox)be.getSource()).isSelected()) {
                      r.setBackgroundColor(1.f, 1.f, 1.f);
                      r.setForegroundColor(0.f, 0.f, 0.f);
                   } else {
                      r.setBackgroundColor(0.f, 0.f, 0.f);
                      r.setForegroundColor(1.f, 1.f, 1.f);
                   }
                 } catch (Exception e) {
                    e.printStackTrace();
                 }
               }
           });
           p.add(color);
           getContentPane().add("North", p);
           JButton rebuild = new JButton("Rebuild Display");
           rebuild.addActionListener(new ActionListener() {
               public void actionPerformed(ActionEvent ae) {
                   rebuildDisplay();
               }
           });
           getContentPane().add("South", rebuild);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void makeControlListener(Control c) {
        try {
           c.addControlListener(new ControlListener() {
               public void controlChanged(ControlEvent e) {
                   System.out.println("PC: got event: " + e + 
                   " from instance " +
                    ((Control) e.getControl()).getClass().getName());
                    //((Control) e.getControl()).getInstanceNumber());
               }
           });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void rebuildDisplay() {
        try {
            Vector maps = display.getMapVector();
            display.removeAllReferences();
            display.clearMaps();
            for (int i = 0; i < maps.size(); i++) {
                display.addMap((ScalarMap) maps.get(i));
            }
            display.addReference(mapRef);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        PCTest pc = new PCTest();
        pc.pack();
        pc.setVisible(true);
    }
}