Moving a translucent window around the screen

edited January 2017 in Questions about Code

I have made the window translucent, but that removes the ability to grab the outside of the window to move it (maybe there is a way to allow that?). I get the location of surface and relocate it with the mouse coordinates, but I need the location of the mouse in relationship to the monitor screen. Any ideas on this?

import processing.awt.PSurfaceAWT;
import javax.swing.JFrame;

JFrame frame;

void setup() {
  size(250, 140);
  frame = getJFrame();
  frame.removeNotify();
  frame.setUndecorated(true);
  frame.setOpacity(0.5f);
  frame.addNotify();
}

void draw() {
} 

void keyPressed() {
  if (keyCode == 112) { //F1
    frame.setOpacity(1.0f);
  }
  if (keyCode == 113) { //F2
    frame.setOpacity(0.5f);
  }
}

void mousePressed() {
  if (mouseButton == LEFT) {
    fill(0);
    ellipse(mouseX, mouseY, 5, 5);
  } else if (mouseButton == RIGHT) {
    surface.setLocation(mouseX, mouseY);
  }
}

void mouseDragged() {
  if (mouseButton == LEFT) {
    ellipse(mouseX, mouseY, 5, 5);
  } else if (mouseButton == RIGHT) {
    surface.setLocation(mouseX, mouseY);
  }
}

JFrame getJFrame() {
  PSurfaceAWT surf = (PSurfaceAWT) getSurface();
  PSurfaceAWT.SmoothCanvas canvas = (PSurfaceAWT.SmoothCanvas) surf.getNative();
  return (JFrame) canvas.getFrame();
}

Answers

  • Do remember that it may not work with other renderers.
    Is setUndecorated necessary to make it work?
    Try using setUndecorated(false) after setting opacity.

  • I get the error "Buffers have not been created" when I try to setUndecorated(false).

  • edited January 2017

    This works:

    import processing.awt.PSurfaceAWT;
    import javax.swing.JFrame;
    import javax.swing.*;
    
    JFrame frame;
    
    void setup() {
      size(250, 140);
      frame = getJFrame();
      frame.removeNotify();
      frame.setUndecorated(true);
      frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
      frame.setLocationRelativeTo(null);
      frame.setOpacity(0.5f);
      frame.addNotify();
    }
    
    void draw() {
    } 
    
    void keyPressed() {
      if (keyCode == 112) { //F1
        com.sun.awt.AWTUtilities.setWindowOpacity(frame, 0.5f);
      }
      if (keyCode == 113) { //F2
        com.sun.awt.AWTUtilities.setWindowOpacity(frame, 1.0f);
      }
    }
    
    JFrame getJFrame() {
      PSurfaceAWT surf = (PSurfaceAWT) getSurface();
      PSurfaceAWT.SmoothCanvas canvas = (PSurfaceAWT.SmoothCanvas) surf.getNative();
      return (JFrame) canvas.getFrame();
    }
    
  • Answer ✓

    Really nice "hack" job there, @Bird! <:-P

    Just a small tip: In Processing, we don't need to suffix literals w/ f to force float.
    PDE's pre-processor already does that for us automatically for ".pde" tabs. :-bd

    Now if we need for double, we've gotta suffix them w/ d for ".pde" tabs. L-)
    And of course, it's the opposite for ".java" tabs. :P

  • edited January 2017

    Thanks! Yes, thank you for the clarification. When I'm bouncing around and "borrowing" other people's code I usually just leave the 'f's until I refactor. This is an effect I've been wanting to achieve for a while and, though not perfect, finally allows me to move on.

  • So this approach works because the user can click on the window top bar and move the window around?

    Kf

  • edited January 2017

    A lil' refactoring of mine: :P

    /**
     * Opacity + WindowDecoration (v2.0)
     * Bird (2017-Jan-27)
     * mod GoToLoop
     *
     * forum.Processing.org/two/discussion/20499/
     * moving-a-translucent-window-around-the-screen#Item_8
     */
    
    import processing.awt.PSurfaceAWT.SmoothCanvas;
    import com.sun.awt.AWTUtilities;
    
    import javax.swing.JFrame;
    import javax.swing.JRootPane;
    
    static final float STEP = .05;
    JFrame jframe;
    
    void setup() {
      size(300, 200);
      noLoop();
    
      jframe = getJFrame(getSurface());
    
      jframe.removeNotify();
      jframe.setUndecorated(true);
      jframe.addNotify();
    
      jframe.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
      jframe.setOpacity(.5);
    }
    
    void draw() {
      jframe.setTitle(nf(jframe.getOpacity(), 0, 2));
      background((color) random(#000000));
    } 
    
    void mousePressed() {
      final int btn = mouseButton;
      float opac = 1;
    
      if (btn == CENTER)  AWTUtilities.setWindowOpacity(jframe, 1);
      else {
        final float step = btn == LEFT? -STEP : STEP;
        opac = constrain(jframe.getOpacity() + step, .1, .95);
        jframe.setOpacity(opac);
      }
    
      redraw = true;
      println(opac);
    }
    
    static final JFrame getJFrame(final PSurface surf) {
      return (JFrame) ((SmoothCanvas) surf.getNative()).getFrame();
    }
    
  • Cool hacking from @Bird and @GoToLoop here. ^:)^ \m/

  • Hello, I feel like it's good for this feature to be implemented as an internal feature of Processing so that anybody can easily decorate their app windows without having to know much deeper implementation details like this. I would like to implement this feature in PSurfaceAWT.java. Any comments/suggestions would be appreciated. Thanks :)

Sign In or Register to comment.