pixels of a new window

edited August 2015 in Library Questions

Hi again! I'm still probing the g4p control and now I have problems with showing an extra window. The problem is that I really don't understand how it works and how can I obtain data from that other window, for example use pixels when I click a button in the main sketch.

Answers

  • Answer ✓

    If you have a GWindow calledgw then you can access the pixels using

    gw.papplet.loadPixels ();
    int [] pix = gw.papplet.pixels;
    gw.papplet.updatePixels ();
    

    use pixels when I click a button in the main sketch

    This can be difficult because the main sketch and gw are speate threads so there is a very high risk of concurrent access exceptions if you attempt to modify gw's pixels from the main sketch. It needs careful program design to avoid this. I suggest that you create a simple sketch with a single GWindow and experiment with that.

  • is it similar if I want to use millis()??

  • Answer ✓

    millis () returns the time the applet started. I suspect that

    gw.papplet.millis ();

    will return the time since gw was created. You would need to confirm this yourself by experiment.

  • edited August 2015

    Thank you so much I will probe it :D. I made some tests with pixels and it work really good

  • you were right, millis() start in the moment the new window is opened :)

  • I'm trying to copy what is happening in one window into another every x-time. But I don't know if what I am doing is correct. This is my code:

    import g4p_controls.*;
    
    GWindow window;
    GButton btnStart;
    
    int x = 10;
    int y = 10;
    int [] px = {
      1, 2
    };
    boolean n = false;
    void setup() {
      size(200, 200);
      btnStart = new GButton(this, 4, 34, 120, 60, "Create 3 Windows");
    }
    
    
    void draw() {
      background(240);
      if (n)
      {
        loadPixels();
        for (int i= 0; i < px.length; i++)
        {
          if (pixels[i] != px[i])
          {
            pixels[i] = px[i];
          }
        }
        updatePixels();
      }
      if ( millis()%40== 0)
      {
        if (window != null)
        {
          window.papplet.loadPixels ();
          px = window.papplet.pixels;
          window.papplet.updatePixels ();
        }
      }
    }
    
    void createWindows() {
      window = new GWindow(this, "Window ", 70, 160, 200, 200, false, JAVA2D);
      window.setBackground(230);
      window.addDrawHandler(this, "windowDraw");
    }
    
    void handleButtonEvents(GButton button, GEvent event) {
      if (window == null && event == GEvent.CLICKED) {
        createWindows();
        btnStart.setEnabled(false);
        n = true;
      }
    }
    
    void windowDraw(GWinApplet appc, GWinData data) {
      appc.fill(0, 25, 85);
      appc.ellipse(x, 30, 30, 30);
      if (x < appc.width)
      {
        x++;
      } else
      {
        x = appc.width;
      }
    }  
    

    It sometimes works when I make the modulo with values that are less than 40 (millis()%40) but the values are greater it doesn't work, can you help me please?

  • the draw method is called ~60 per second so the time interval between frames is about 17ms. The chances that millis() % 40 == 0 is extremely small and is gets worse when you increase the 40. Also this is not a good solution because the main display will flicker because only sometimes the window is copied/

    The following code is one way to do what you want although you still have a little flicker.

    import g4p_controls.*;
    
    GWindow window = null;
    GButton btnStart;
    
    int x = 10;
    int y = 10;
    int [] px = {
      1, 2
    };
    boolean n = false;
    
    void setup() {
      size(200, 200);
      btnStart = new GButton(this, 4, 100, 120, 60, "Create 3 Windows");
    }
    
    void draw() {
      background(240);
      if (n && window != null) {
        println("xxx");
        loadPixels();
        window.papplet.loadPixels ();
        int nbr = min(window.papplet.pixels.length, pixels.length);
        // Copy to main window
        arrayCopy( window.papplet.pixels, 0, pixels, 0, nbr);
        updatePixels ();
      }
    }
    
    void createWindows() {
      window = new GWindow(this, "Window ", 70, 160, 200, 200, false, JAVA2D);
      window.setBackground(230);
      window.addDrawHandler(this, "windowDraw");
    }
    
    void handleButtonEvents(GButton button, GEvent event) {
      if (window == null && event == GEvent.CLICKED) {
        createWindows();
        btnStart.setEnabled(false);
        n = true;
      }
    }
    
    void windowDraw(GWinApplet appc, GWinData data) {
      appc.fill(0, 25, 85);
      appc.ellipse(x, 30, 30, 30);
      if (x < appc.width) {
        x++;
      } else {
        x = appc.width;
      }
    }  
    

    Notice I don't call window.papplet.updatePixels (); you only need to do that if the pixels change

  • ok, that is a great program, but i want to copy the window every 2 seconds (more or less), that`s why I was using millis(). How can I do that??

  • In 2 seconds the draw() method would be called 120 times. It means the image will be displayed in 1 frame and not displayed in 119 frames. I suspect that is not what you want but i could be wrong ;)

  • Answer ✓

    I suspect that you want to see the contents of the 2nd window in the main window all the time but update it every 2 seconds. The following program demonstrates how you might do this.

    import g4p_controls.*;
    
    GWindow window = null;
    GButton btnStart;
    PImage img = null;
    int ct, lt, et;
    int delay = 2000; // 2000ms or 2 seconds
    
    int x = 10;
    
    void setup() {
      size(600, 200);
      btnStart = new GButton(this, 4, 100, 120, 60, "Create 3 Windows");
    }
    
    void draw() {
      background(240);
      if (window != null && img != null) {
        image(img, 0, 0);
      }
    }
    
    void createWindows() {
      window = new GWindow(this, "Window ", 70, 160, 600, 200, false, JAVA2D);
      window.setBackground(230);
      window.addDrawHandler(this, "windowDraw");
      ct = window.papplet.millis();
      lt = ct - delay;
    }
    
    void handleButtonEvents(GButton button, GEvent event) {
      if (window == null && event == GEvent.CLICKED) {
        createWindows();
        btnStart.setEnabled(false);
      }
    }
    
    void windowDraw(GWinApplet appc, GWinData data) {
      appc.fill(0, 25, 85);
      appc.ellipse(x, 30, 30, 30);
      if (x < appc.width - 15) {
        x++;
      } else {
        x = 15;
      }
      // Get the current display every 2 seconds
      ct = appc.millis();
      if (ct - lt >= delay) {
        lt = ct;
        PImage temp = appc.get();
        img = temp;
      }
    }
    
  • thank you so much!!! That is what I tried to do :)

Sign In or Register to comment.