ControlP5 I am misunderstanding something

edited July 2016 in Library Questions

Hello, I am a rusty programmer.. I was wondering if someone would be kind enough to point out my misunderstanding. I am setting up two windows.. one running a temperature graph and one containing the controls. There are three temp stations. Everything was running along smoothly until I tried using the setOn() or setOff() button functions. I think I am misunderstanding something basic about how the ControlP5 library works.

There is a lot of irrelevant code... I think this should be enough to help me...if you so choose.

        `
        SecondWin sw;

        void settings() {
           size(1100, 850, JAVA2D);  
        }

        void setup() {
           sw = new SecondWin(this, 700, 400);  //second Window (Control Panel)
        }
        void draw() {  
        }

        public class SecondWin extends PApplet {  // code for window

          int w, h;
          PApplet parent;
          ControlP5 cp5;


            public SecondWin(PApplet _parent, int _w, int _h) {
               super();
               parent = _parent;

               w = _w;
               h = _h;
               PApplet.runSketch(new String[]{this.getClass().getName()}, this);
            }

            public void settings() {
               size(w, h); 
            }

            public void setup() {

            cp5 = new ControlP5(this);

              cp5.addButton("VS2")
                            .setImages(icons[0], icons[0], icons[10])
                            .updateSize()
                            .setPosition(10, 10)
                            .setSwitch(true)
                            .setId(50)
                            .plugTo(parent, "VS2");
        }

          public void draw() {
          background(255);
          fill(0);
         }
         public void controlEvent(ControlEvent theEvent) {
              if (theEvent.isController()) {
                  println(((Button)cp5.getController("VS2")).isOn());
       //         ((Button)cp5.getController("VS2")).setOn();       ########## PROBLEM  ######
            }

        }
}
`

As mentioned, I left out a lot of code. I have been fighting this for a few hours...so a lot of this code I have stolen from online sources and Frankenstein'd here.

As is, it runs with no errors and hitting the VS2 button prints out the proper false and true values. When I un-comment the ((Button)cp5.getController("VS2")).setOn(); and then hit the button, I get a stream of multiple 'trues' printed to console and

    java.lang.NoClassDefFoundError: Could not initialize class java.util.logging.LogRecord
at java.util.logging.Logger.log(Logger.java:787)
at java.util.logging.Logger.severe(Logger.java:1463)
at controlP5.ControlBroadcaster.printMethodError(Unknown Source)
at controlP5.ControlBroadcaster.invokeMethod(Unknown Source)
at controlP5.ControlBroadcaster.broadcast(Unknown Source)
at controlP5.Controller.broadcast(Unknown Source)
at controlP5.Button.setValue(Unknown Source)
at controlP5.Button.activate(Unknown Source)
at controlP5.Button.mouseReleased(Unknown Source)
at controlP5.Controller.setMousePressed(Unknown Source)
at controlP5.ControllerGroup.setMousePressed(Unknown Source)
at controlP5.ControlWindow.mouseReleasedEvent(Unknown Source)
at controlP5.ControlWindow.mouseEvent(Unknown Source)
at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at processing.core.PApplet$RegisteredMethods.handle(PApplet.java:1398)
at processing.core.PApplet.handleMethods(PApplet.java:1593)
at processing.core.PApplet.handleMouseEvent(PApplet.java:2680)
at processing.core.PApplet.dequeueEvents(PApplet.java:2603)
at processing.core.PApplet.handleDraw(PApplet.java:2414)
at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1527)
at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:316)

If it is something really basic I am missing, even throwing me a reference page address would be appreciated.

Thanks!

Answers

  • Answer ✓

    Barely I know anything 'bout ControlP5 library. Just did some experiments regardless. :-\"
    Seems like when setSwitch() is set to true, both setOn() & setOff() re-triggers controlEvent().
    It means if we use any of them inside controlEvent(), it's gonna invoke the latter forever! @-)
    My workaround is to place setOn() or setOff() in draw(), away from controlEvent().

    // forum.Processing.org/two/discussion/17376/
    // controlp5-i-am-misunderstanding-something
    
    // GoToLoop (2016-Jun-30)
    
    import controlP5.ControlP5;
    import controlP5.ControlEvent;
    import controlP5.Button;
    
    void settings() {
      size(600, 400);
      smooth(4);
    }
    
    void setup() {
      frameRate(1);
      runSketch(platformNames, new SecondWin());
    }
    
    void draw() {
      background((color) random(#000000));
    }
    
    static class SecondWin extends PApplet {
      static final String BTN_NAME = "Test";
    
      Button btn;
      boolean gotBtnEvent;
    
      void settings() {
        size(400, 300);
        smooth(4);
      }
    
      void setup() {
        btn = new ControlP5(this).addButton(BTN_NAME)
          .setSize(width>>1, height>>1)
          .setPosition(width>>2, height>>2)
          .updateSize()
          .setSwitch(true)
          .plugTo("???")
          ;
      }
    
      void draw() {
        background(0100);
    
        if (gotBtnEvent) {
          btn.setOn();
          //btn.setOff();
    
          println("Main:", btn.isOn());
          gotBtnEvent = false;
        }
      }
    
      void controlEvent(ControlEvent evt) {
        gotBtnEvent = BTN_NAME.equals(evt.getName());
        print("Event:", btn.isOn(), TAB);
        //btn.setOff(); // Re-triggers controlEvent() forever!!!
      }
    }
    
  • I will try that tomorrow at work and will post the results. Thank you in advance, either way, for the input.

  • All fixed up!! Thanks very much GoToLoop!

  • A quick addendum in order to add my fix.... in case anyone else needs it. And thanks again to GoToLoop for pointing out my error.

    My goal was to have my set of buttons behave, and appear, as only one 'on' at a time. This probably could have been more easily done with ControlP5's buttonBar class... but I found the custom setImages() for appearance more easy to understand with the Button class.

    Anyhow... I was getting an infinite loop by both catching, and receiving, the same Event in a function. Namely, catching a Button release and then creating another Button release with the setOn(), setOff() functions.

    I initially wanted a released Button which was already in the 'On' state to remain 'On'... but as it doesn't matter much for my application, I postponed this behavior fix.

    My fix was to create a state monitoring array of Booleans, in order to prevent the infinite loop.

             public void controlEvent(ControlEvent theEvent) {
             Button btn = (Button)theEvent.getController();
             int index = btn.getId();
                 if (btn.isOn() && !btnState[index]) {
                          btnState[index] = true;
                          mutualEx(index);
                          whichGraph = index;
                }
             }
    
                void mutualEx(int index) {
                    Button btn;
                    for (int i = 0; i < 3; i++) {
                        btn = (Button)cp5.getController("VS"+str(i+1));
                        if ((btn.getId()-50)!= index) {
                          btnState[index] = false;
                          btn.setOff();
                        }
                    }
    
              }
    

    Which I am sure can be cleaned up some. The important line is

       if (btn.isOn() && !btnState[index]) {
    

    Don't send out an Event if the button is already on.

    That's how I fixed it. Cheers.

Sign In or Register to comment.